I am trying to use a single SQL command to do two selects I want to select related data and insert it in another table from another database, but it isn't working, I am new to this, can someone help me? Thanks in advance.
Try
If CreateAccessDatabase("C:\Users\Utilizador.Utilizador-PC\Documents\Visual Studio 2013\Projects\WindowsApplication1\WindowsApplication1\Doc_Vendas_Cab.mdb") = True Then
MsgBox("Database Created")
Else
MsgBox("Database Creation Failed")
End If
Dim Sql As String = "Select strCodSeccao,strAbrevTpDoc,strCodExercicio,intNumero " & _
"From Mov_Venda_Cab where dtmdata between #d1 and #d2; Union" & _
"Select Mov_Venda_Lin.Strcodartigo" & _
"from Mov_Venda_Lin,Mov_Venda_Cab where Mov_Venda_Cab.intnumero=Mov_Venda_Lin.intnumero;"
Dim data1, data2 As DateTime
data1 = DateTime.Parse(txtData1.Text)
data2 = DateTime.Parse(txtData2.Text)
data2 = data2.AddMinutes(0)
data2 = data2.AddHours(0)
data2 = data2.AddSeconds(0)
data1 = data1.AddMinutes(0)
data1 = data1.AddHours(0)
data1 = data1.AddSeconds(0)
Dim x As Integer = 0
Dim temp1, temp2, temp3, temp4, temp5 As String
Using con = New SqlConnection("Data Source=" & txtserv.Text & ";" & "Initial Catalog=" & txtBD.Text & ";" & "User ID=" & txtuser.Text & ";" & "Password=" & txtPass.Text & "")
Using cmd = New SqlCommand(Sql, con)
con.Open()
cmd.Parameters.AddWithValue("#d1", data1)
cmd.Parameters.AddWithValue("#d2", data2)
Using reader = cmd.ExecuteReader()
While reader.Read()
Dim strCodSeccao = reader("strCodSeccao").ToString()
temp1 = reader.Item(x)
temp2 = reader.Item(x + 1)
temp3 = reader.Item(x + 2)
temp4 = reader.Item(x + 3)
temp5 = reader.Item(x + 4)
Dim Con2 As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Utilizador.Utilizador-PC\Documents\Visual Studio 2013\Projects\WindowsApplication1\WindowsApplication1\Doc_Vendas_Cab.mdb;Persist Security Info=True")
Con2.Open()
Dim Ole2 As String = "Insert into Mov_Venda_Cab values('" & temp1 & "','" & temp2 & "','" & temp3 & "','" & temp4 & "','" & temp5 & "');"
Dim OledbCom2 As New OleDb.OleDbCommand(Ole2, Con2)
Try
OledbCom2.ExecuteNonQuery()
Catch Ex As Exception
MsgBox(Ex)
End Try
Con2.Close()
End While
End Using
End Using
End Using
Catch Ex As Exception
MsgBox(Ex)
End Try
Your INSERT statement encloses all the values in single quotes. This will only work if the corresponding columns are all text columns (varchar, nvarchar etc.). Use command parameters instead:
Dim Ole2 As String = "Insert into Mov_Venda_Cab values(#p1, #p2, #p3, #p4, #p5);"
Dim OledbCom2 As New OleDb.OleDbCommand(Ole2, Con2)
OledbCom2.Parameters.AddWithValue("#p1", temp1)
OledbCom2.Parameters.AddWithValue("#p2", temp2)
OledbCom2.Parameters.AddWithValue("#p3", temp3)
OledbCom2.Parameters.AddWithValue("#p4", temp4)
OledbCom2.Parameters.AddWithValue("#p5", temp5)
This will work for any column type.
Also your SELECT statement lists only four columns, but you are accessing five columns in the reader.
SELECT strCodSeccao, strAbrevTpDoc, strCodExercicio, intNumero FROM ...
Other things in your code are strange as well. Your are defining two connections that are never used later.
You are adding zero hours, minutes and seconds to a date (this will not change the date). If you want the date part of the date without the time part, use the Date property instead, which returns the date component of the DateTime structure:
data1 = DateTime.Parse(txtData1.Text).Date
You are using a variable x for constant values.
You are opening and closing Con2 in the While-loop. Open it before the loop and close it after the loop. (You can do it with a Using-statement as for the other connection.)
Related
I am working on a custom VBA script that dynamically collects user-entered form data and inserts it into a MySQL database. My problem is, to convert form field data into an SQL script, I have to use string functions; thus, all my data, including dates, gets inserted as text. I need to convert all the dates the form collects from m/d/yyyy format to yyyy-mm-dd format for my MySQL database to infer schema and load date data into DB without an error. I need to do so dynamically, meaning, the script has to work regardless of how many date fields are collected. I have:
Private Sub Submit_Button()
Dim doc as Document
Dim control As ContentControl
Dim FormDateField As Date
Dim ReportNumber As String
Dim myValues As String
Dim myFields As String
Dim conn As ADODB.Connection
Dim strSQL As String
Set doc = Application.ActiveDocument
Set conn = New ADODB.Connection
conn.open "DSN=ABCD"
For Each control In doc.ContentControls
Skip = False
If Left(control.Range.Text, 5) = "Click" Or Left(control.Range.Text, 6) = "Choose" Then
Skip = True
Else:
myFields = myFields & control.Tag
myValues = myValues & "'" & control.Range.Text & "'"
End If
If Not Skip Then
myFields = myFields & ", "
myValues = myValues & ", "
End If
Next
myFields = Left(myFields, Len(myFields) - 2)
myValues = Left(myValues, Len(myValues) - 2)
strSQL = "INSERT INTO TABLE_1 ("
strSQL = strSQL & myFields
strSQL = strSQL & ") VALUES (" & myValues
strSQL = strSQL & ")"
conn.Execute strSQL
MsgBox "Form data saved to database!"
conn.Close
End Sub
However, my program is crashing because it is trying to insert a string into the date field (the actual final form will have many date fields.) I thought if I change the date format to MySQL format, it may be able to infer schema? I tried adding
If IsDate(control.Range.Text) Then
control.Range.Text = Format(control.Range.Text, "yyyy-mm-dd")
Else FoundOne = False
End If
and I know in Excel you can do:
Application.FindFormat.NumberFormat = "m/d/yyyy"
Application.ReplaceFormat = "yyyy-mm-dd"
Any suggestions? Thank you.
Assuming all dates are in date-picker content controls, you could use:
Private Sub Submit_Button()
Dim CCtrl As ContentControl, bSv As Boolean, DtFmt As String
Dim myFields As String, myValues As String, strSQL As String
With ActiveDocument
bSv = .Saved
For Each CCtrl In .ContentControls
With CCtrl
If .ShowingPlaceholderText = False Then
Select Case .Type
Case wdContentControlDate
DtFmt = .DateDisplayFormat
.DateDisplayFormat = "YYYY-MM-DD"
myFields = myFields & .Tag & ", "
myValues = myValues & "'" & .Range.Text & "', "
.DateDisplayFormat = DtFmt
Case wdContentControlRichText, wdContentControlText, wdContentControlDropdownList, wdContentControlComboBox
myFields = myFields & .Tag & ", "
myValues = myValues & "'" & .Range.Text & "', "
Case Else
End Select
End If
End With
Next
.Saved = bSv
End With
If myFields <> "" Then
myFields = Left(myFields, Len(myFields) - 2)
myValues = Left(myValues, Len(myValues) - 2)
strSQL = "INSERT INTO TABLE_1 (" & myFields & ") VALUES (" & myValues & ")"
Dim Conn As New ADODB.Connection
With Conn
.Open "DSN=ABCD": .Execute strSQL: .Close
End With
Set Conn = Nothing
MsgBox "Form data saved to database", vbInformation
Else
MsgBox "No form data found", vbExclamation
End If
End Sub
As you noticed, Word does not have Application.FindFormat or Application.ReplaceFormat, but if you know the format is m/d/y you should be able to do this:
myValues = myValues & "'" & ymd(control.Range.Text) & "'"
Function ymd(s as String) As String
Dim v As Variant
v = VBA.split(s, "/")
ymd = Right("0000" & v(2),4) & "-" & Right("00" & v(0),2) & "-" & Right("00" & v(1),2)
End Function
Everything else (e.g. the way you add commas to the list of dates) looks fine but I have not tested.
So here is my code below.
qry = "SELECT * FROM `tblsubjects` WHERE `GRADELEVEL` = " & lblgrade.Text & " AND `SUBJECTNAME` <> (SELECT `SUBJECTNAME` FROM `tblschedule` WHERE `SECTIONNAME` = '" & lblsect.Text & "')"
it came from may vb application. I think the error came from the query. t I'm making a scheduling system. On that query, i was trying to load the subjects that has not been scheduled on that gradelevel and section on to combo box. but that error comes out when i try to add more schedule on this section.
enter image description here
Here is my whole code on this function:
Private Sub subjectload()
con = New MySqlConnection
con.ConnectionString = "server=localhost;user id=root;password='';database=kccbeslis"
If DataGridView.Rows.Count > 0 Then
Try
con.Open()
qry = "SELECT * FROM `tblsubjects` WHERE `GRADELEVEL` = " & lblgrade.Text & " AND `SUBJECTNAME` <> (SELECT `SUBJECTNAME` FROM `tblschedule` WHERE `SECTIONNAME` = '" & lblsect.Text & "')"
cmd = New MySqlCommand(qry, con)
rdr = cmd.ExecuteReader
While rdr.Read
Dim subname = rdr.GetString("SUBJECTNAME")
cbsubject.Items.Add(subname)
End While
con.Close()
Catch ex As Exception
MessageBox.Show(ErrorToString)
End Try
Else
Try
con.Open()
qry = "SELECT * FROM `tblsubjects` WHERE `GRADELEVEL` = " & lblgrade.Text & ""
cmd = New MySqlCommand(qry, con)
rdr = cmd.ExecuteReader
While rdr.Read
Dim subname = rdr.GetString("SUBJECTNAME")
cbsubject.Items.Add(subname)
End While
con.Close()
Catch ex As Exception
MessageBox.Show(ErrorToString)
End Try
End If
End Sub
help me pls!
Subquery SELECTSUBJECTNAMEFROMtblscheduleWHERESECTIONNAME= '" & lblsect.Text & "' results more than 1 records. You are using <> instead of not in, use Not In clause and try.
It appears your sub select (SELECT subjectname FROM tblscheduler where..) has multiple schedules with the same 'sectionname' you are providing, therefore is returning more than 1 row.
Are you sure your sectionname column is unique per tblschedule entry? Try a count and group by to see if you have multiple records;
SELECT COUNT(*) FROM tblschedule GROUP BY sectionname;
You could try replacing <> with NOT IN if you require multiple rows.
Yes, that's cause your subquery returning more than 1 record and <> operator expects scalar value and list of values. You should rather use NOT IN operator like
AND `SUBJECTNAME` NOT IN (SELECT `SUBJECTNAME` FROM `tblschedule` WHERE `SECTIONNAME` = '" & lblsect.Text & "')
BTW, do you know your posted code is very much vulnerable to SQL Injection. You should consider using parameterized queries to avoid the same.
Use NOT IN instead of <>
qry = "SELECT * FROM tblsubjects WHERE GRADELEVEL = " & lblgrade.Text & " AND SUBJECTNAME NOT IN (SELECT SUBJECTNAME FROM tblschedule WHERE SECTIONNAME = '" & lblsect.Text & "')"
I'm creating an update Sub class in VB and use the insert instead of Update in Query because i want to update a multiple data in one run.
this is my references in multiple update data: SQL - Update multiple records in one query
but when I run it there is an error message.
"Missing semicolon (;) at end of SQL statement."
but in the end of my Query there is a Semicolon.
Here is my Query:
Insert into IngredientStock(IngredientID,CategoryId,UnitID,IngredientName,Price)
values(46,2,1,'Beans', 100) ON DUPLICATE KEY
UPDATE
ingredientID= Values(IngredientID),
CategoryID = Values(CategoryID),
UnitID = Values(UnitID),
IngredientName = Values(IngredientName),
Price = values(Price);
Here is my update Sub class
Sub UpdateInfo(ByVal table As String, ByVal PrimaryKey As String, ByVal C1 As String, ByVal C2 As String, ByVal C3 As String, ByVal C4 As String, ByVal Datas As String)
con.Close()
con.Open()
Query = "Insert into " & table & "(" & PrimaryKey & "," & C1 & "," & C2 & "," & C3 & "," & C4 & ") values (" & Datas & ") ON DUPLICATE KEY UPDATE " & PrimaryKey & "= Values(" & PrimaryKey & "), " & C1 & " = values(" & C1 & ")," & C2 & " = values(" & C2 & "), " & C3 & " = values(" & C3 & ")," & C4 & " = values(" & C4 & ");"
cmd = New OleDbCommand(Query, con)
DR = cmd.ExecuteScalar
con.Close()
End Sub
First, never ever concat strings to create a SQL query. If something like the ingredient contains special characters (e.g. Palmer's Condensed Milk) it will fail.
SQL Parameters also preserve the data type - according to the one snippet, only one item is string, but the code is forcing them all to text. Additionally (and most importantly) SQL Parameters avoid SQL injection.
You need something like this for a MySQL Upsert:
Dim sql = <sql>
INSERT INTO SampleZ
(Id, Name, Country, Animal, Color, Price, ItemDate, Active)
VALUES
(#id, #n, #c, #a, #clr, #p, #dt, #act)
ON DUPLICATE KEY UPDATE
Name=#n, Country=#c,
Animal=#a, Color=#clr, Price=#p,
ItemDate=#dt, Active=#act
WHERE id = #id
</sql>.Value
Using dbcon As New MySqlConnection(connStr)
Using cmd As New MySqlCommand(sql, dbcon)
cmd.Parameters.Add("#id", MySqlDbType.Int32).Value = thisID
If thisID = -1 Then
cmd.Parameters("#id").Value = DBNull.Value
End If
cmd.Parameters.Add("#n", MySqlDbType.String).Value = TextBox1.Text
cmd.Parameters.Add("#c", MySqlDbType.String).Value = ComboBox1.Text
cmd.Parameters.Add("#a", MySqlDbType.String).Value = TextBox2.Text
cmd.Parameters.Add("#clr", MySqlDbType.String).Value = TextBox3.Text
cmd.Parameters.Add("#p", MySqlDbType.Decimal).Value = NumericUpDown1.Value
cmd.Parameters.Add("#dt", MySqlDbType.DateTime).Value = DateTimePicker1.Value
cmd.Parameters.Add("#act", MySqlDbType.Bit).Value = chkActive.Checked
dbcon.Open()
Dim rows = cmd.ExecuteNonQuery()
End Using
End Using
Important Notes:
The above uses an XML literal so the query can be formatted to make sense
Each value is a Parameter with the datatype specified (MySqlDbType.DateTime
The Using blocks assure that the DbCOnnection and DbCommand object are properly closed and disposed at the end so the app doesnt leak resources
The UPDATE portion gets the data by assigning the same parameters.
MySql ON DUPLICATE KEY UPDATE Syntax
ingredientID= Values () <-- here
values clause is not required.
Liink --> On Duplicate Key Update same as insert
I'm trying to create a dynamic MySQL INSERT INTO...WHERE NOT EXIST statement by parsing the table name, array of columns, array of values and conditional column and value to a subroutine in a separate module but i keep hitting the Column count doesn't match value count at row 1 error. Below is the code:
Sub InsertRecord(ByVal tbl As String, ByVal cols() As String, ByVal params() As String, _
ByVal colCondition As String, ByVal paramCondition As String) 'As String
'Create new string of columns
Dim myCols As String = ""
For Each col As String In cols
myCols &= col & ", "
Next
Dim newCols As String = myCols.Remove(myCols.Count - 2, 2)
MsgBox(newCols)
Dim scols As String = newCols.Insert(0, "`").Replace(", ", "`, `") & "`"
MsgBox(scols)
'Create new string of parameters
Dim myParams As String = ""
For Each param In params
myParams &= param & ", "
Next
Dim newParams As String = myParams.Remove(myParams.Count - 2, 2)
MsgBox(newParams)
Dim sparams As String = newParams.Insert(0, "'").Replace(", ", "', '") & "'"
MsgBox(sparams)
'End
Dim p As String = paramCondition.Insert(0, "'") & "'"
'Try
'Dim insRemarks As String = "done"
con = New MySqlConnection("Server=localhost; Database=etms; Uid=root; Pwd=;")
comA = New MySqlCommand
'INSERT NEW RECORD.
'THIS GIVES THE ERROR
comA.CommandText = "INSERT INTO " & tbl & " (" & scols & ") SELECT * FROM (SELECT #params) AS tmp "
comA.CommandText &= "WHERE NOT EXISTS (SELECT " & colCondition & " FROM " & tbl & " WHERE " & colCondition & " = #param) limit 1"
comA.Parameters.AddWithValue("#param", p)
comA.Parameters.AddWithValue("#params", sparams)
'THIS STATIC CODE WORKS FINE.
'comA.CommandText = "INSERT INTO state (`st_state`, `ctry_Id`) SELECT * FROM (SELECT 'a', '1') AS tmp "
'comA.CommandText &= "WHERE NOT EXISTS (SELECT st_state FROM state WHERE st_state = 'a') limit 1"
comA.Connection = con
con.Open()
comA.ExecuteNonQuery()
con.Close()
'Release used up components
comA.Parameters.Clear()
comA.Dispose()
comA = Nothing
con = Nothing
MsgBox("done.")
'Return insRemarks
'Catch ex As Exception
'MsgBox(ex.Message.ToString & vbCrLf & vbCrLf & comA.CommandText.ToString)
'Return "Error"
'End Try
End Sub
As seen, i tried a lot of permutations (introducing inverted quotation marks) to no avail.
I'll be glad if someone could help out.
I have this datagridview whose rows are manually added on a click of a button.
What I wanted to do was to somehow loop through each row and insert it in a mysql database
here is my current code:
Public Sub addResBulk()
Dim cmdAddRes As New MySqlCommand
Dim addResQry As String
'field remarks left empty until process complete
With cmdAddRes
.Parameters.AddWithValue("#ctrlno", ctrlNo)
.Parameters.AddWithValue("#resdate", dtp_resDate.Value)
.Parameters.AddWithValue("#timestart", cbo_start.SelectedValue)
.Parameters.AddWithValue("#timeend", cbo_end.SelectedValue)
.Parameters.AddWithValue("#claimdate", claimdate)
.Parameters.AddWithValue("#borrowerid", tb_borrowerID.Text)
.Parameters.AddWithValue("#resloc", tb_location.Text)
End With
For row As Integer = 0 To dgv_bulk.Rows.Count - 1
Try
addResQry = "INSERT INTO tbl_test(ControlNo, bCode, Qty, resDate, timeSTART, timeEND, claimDate, borrowerID, resLocation) VALUES " _
+ "(#ctrlno, #bcode, #qty, #resdate, #timestart, #timeend, #claimdate, #borrowerID, #resloc)"
If conn.State = ConnectionState.Open Then
conn.Close()
conn.Open()
Else
conn.Open()
End If
'dgv_bulk.Item(1, o).Value
With cmdAddRes
.Parameters.AddWithValue("#bcode", dgv_bulk.Item(1, row).Value)
.Parameters.AddWithValue("#qty", dgv_bulk.Item(2, row).Value)
qryRes = .ExecuteNonQuery
End With
conn.Close()
Catch ex As Exception
MsgBox(ex.Message.ToString)
End Try
Next row
End Sub
However, an error gets in the way of successfully inserting each row into the database.
it tells me that parameter #ctrlno is already defined. and another error telling me that i need a valid and open connection...
Any ideas?
Thanks in advance!
This will Also work
For x As Integer = 0 To yourdatagridviewname.Rows.Count - 1
Dim str1 = "INSERT INTO [expensesTB]([amount],[description],[expensesDate])values(#amount,#description,#expensesDate)"
Dim com As New OleDb.OleDbCommand(str1, con)
com.Parameters.AddWithValue("#amount", yourdatagridviewname.Rows(x).Cells(2).Value)
com.Parameters.AddWithValue("#description", yourdatagridviewname.Rows(x).Cells(1).Value)
com.Parameters.AddWithValue("#expensesDate", thisyear.ToString("yyyy/MM/dd"))
com.ExecuteNonQuery()
com.Dispose()
Next
Try this if you want to insert the data that you manually input in the Datagridview into Mysql database.
Hope this will help you.
Public Sub addResBulk()
''create connection
Dim conn As MySqlConnection = New MySqlConnection(connectionString)
conn.Open()
Dim comm As MySqlCommand = New MySqlCommand()
comm.Connection = conn
''insert data to sql database row by row
Dim ctrlno, bcode, resdate, timestart, timeend, claimdate, borrowerID, resloc As Object
Dim qty As Double
Dim tbl_test As New DataTable
For i = 0 To DataGridView1.Rows.Add - 1 Step 1
ctrlno = DataGridView1.Rows(i).Cells(0).Value()
bcode = DataGridView1.Rows(i).Cells(1).Value()
qty = DataGridView1.Rows(i).Cells(2).Value()
resdate = DataGridView1.Rows(i).Cells(3).Value()
timestart = DataGridView1.Rows(i).Cells(4).Value()
timeend= DataGridView1.Rows(i).Cells(5).Value()
claimdate = DataGridView1.Rows(i).Cells(6).Value()
borrowerID = DataGridView1.Rows(i).Cells(7).Value()
resloc = DataGridView1.Rows(i).Cells(8).Value()
comm.CommandText = "insert into tbl_test(ControlNo,bCode,Qty,resDate,timeSTART,timeEND,claimDate,borrowerID,resLocation ) values('" & ctrlno & "','" & bcode & "','" & qty & "','" & resdate & "','" & timestart & "','" & timeend & "','" & claimdate & "','" & borrowerID & "','" & resloc & "')"
comm.ExecuteNonQuery()
Next
conn.Close()
Me.Close()
End If
End Sub