Query will not update SQL Server - sql-server

In the below code, my second query will not insert into the SQL database, but the first one will update. I can copy the query (from the msgbox i added for testing) and paste it in SQL Server Management Studio, and it will execute fine. I also do not get any error messages back from SQL, though i'm not sure if that code is correct (it was copied + pasted from another source). Also, can i simplify the code to pass both queries at the same time?
Dim Conn As New System.Data.SqlClient.SqlConnection 'sql server datastream connection
Dim Cmd As New System.Data.SqlClient.SqlCommand 'sql command vars
Dim SqlQuery As String 'string var used to hold various SQL queries
Dim data As System.Data.SqlClient.SqlDataReader 'datareader object variable
Dim MVDataset As New DataSet
Dim MVDatatable As DataTable
Dim MVDatarow As DataRow
Private Sub MVUpdateButton_Click(sender As Object, e As EventArgs) Handles MVUpdateButton.Click
vbyn = MsgBox("Are you sure you want to update Tally Sheet Master Variables?" & vbCrLf & vbCrLf & "Changes to these variables will change the functionality of the Tally Sheet!", vbYesNo, )
Try
Select Case vbyn
Case vbNo
GoTo MVTableUpdateBypass
Case vbYes
'get new data from textboxes
Vers = TextBox1.Text
If TextBox2.Text = True Then
Testing = 1
Else
Testing = 0
End If
FlatFeeCharge = TextBox3.Text
PrepricingCharge = TextBox4.Text
SendMailAcct = TextBox5.Text
SendMailPW = TextBox6.Text
TestingEmail = TextBox7.Text
PrePricingEmail = TextBox8.Text
ImperataEmail = TextBox9.Text
'update existing active row to mark inactive
SqlQuery = "Update MasterVars set Active = 0 where PKEY = " & PKEY & ";"
MsgBox(SqlQuery)
If Conn.State = ConnectionState.Closed Then
Conn.ConnectionString = "Data Source=SQL01;Initial Catalog=TallySheet;Integrated Security=SSPI;"
End If
Conn.Open()
Dim MVDataAdapter As New SqlDataAdapter(SqlQuery, Conn)
Dim MVUpdateCommand As SqlCommand
MVUpdateCommand = New SqlCommand(SqlQuery)
MVDataAdapter.UpdateCommand = MVUpdateCommand
'insert new active row
SqlQuery = "Insert into MasterVars (Vers, Testing, FlatFeeCharge, PrePricingCharge, SendMailAcct, SendMailPW, TestingEmail, PrePricingEmail, ImperataEmail, DTS, UserName, Active) Values (" & "'" & Vers & "', " & Testing & ", '" & FlatFeeCharge & "'" & ", '" & PrepricingCharge & "'" & ", '" & SendMailAcct & "'" & ", '" & SendMailPW & "'" & ", '" & TestingEmail & "'" & ", '" & PrePricingEmail & "'" & ", '" & ImperataEmail & "'" & ", '" & Date.Now & "'," & "'QGDOMAIN\" & Environment.UserName & "'," & 1 & ");"
MsgBox(SqlQuery)
Dim MVInsertCommand As SqlCommand
MVInsertCommand = New SqlCommand(SqlQuery)
MVDataAdapter.InsertCommand = MVInsertCommand
MVDataAdapter.Fill(MVDataset, "MasterVars")
End Select
Catch ex As SqlException
Dim i As Integer
Dim errormessages As String
errormessages = ""
For i = 0 To ex.Errors.Count - 1
errormessages = errormessages & " " & ("Index #" & i.ToString() & ControlChars.NewLine _
& "Message: " & ex.Errors(i).Message & ControlChars.NewLine _
& "LineNumber: " & ex.Errors(i).LineNumber & ControlChars.NewLine _
& "Source: " & ex.Errors(i).Source & ControlChars.NewLine _
& "Procedure: " & ex.Errors(i).Procedure & ControlChars.NewLine)
Next i
Console.WriteLine(errorMessages.ToString())
End Try
'reload form with updated variables
Conn.Close()
Conn.Dispose()
MVTableUpdateBypass:
End Sub

The Fill method of the SqlDataAdapter executes the SelectCommand not the UpdateCommand or the InsertCommand. In any case these two commands (and the DeleteCommand) are executed when you call the Update method of the adapter.
Moreover the Update method runs the commands looking for rows changed/added/deleted in the DataTable/DataSet retrieved by the SelectCommand and works only for those rows.
But you don't need an SqlDataAdapter to execute your two queries. You should simply construct an SqlCommand with both texts separated by a semicolon and call ExecuteNonQuery
SqlQuery = "Update MasterVars set Active = 0 where PKEY = #key;" & _
"Insert into MasterVars (Vers, Testing, .....) VALUES (#p1, #o2, ....)"
Using Conn = New SqlConnection("Data Source=SQL01;......")
Using cmd = New SqlCommand(SqlQuery, Conn)
Conn.Open()
cmd.Parameters.Add("#key", SqlDbType.Int).Value = PKEY
cmd.Parameters.Add("#p1", SqlDbType.NVarChar).Value = vers
cmd.Parameters.Add("#p2", SqlDbType.Int).Value = testing
... and so on with other parameters ....
cmd.ExecuteNonQuery()
End Using
End Using
In this incomplete example (too many parameters to write down) I have concatenated the two sql texts in a single string and prepared it with parameter placeholders. Then I build the parameter collection with the exact datatypes required by your table and finally call ExecuteNonQuery to run everything on the database side.
Notice that is not needed to keep global objects like the connection or the command. It is always better to create a local variable, use and destroy it when done. In particular disposable objects like the connection and the command should always created in a Using block

Related

Excel VBA updating SQL Table - permissions issues

I am connecting to a SQL table via an Excel VBA script using using SQL Server vs Windows Authentication as we're creating a generic update application to be used by several different users. If I log into SQL Server Management Studio with the generic ID/pswd and SQL Server Authentication, I can successfully insert and delete rows. When I use the VBA script, I receive an error indicating that the INSERT or DELETE permission was denied. The VBA script works successfully against the same table in a different schema, but fails going against this schema. I am assuming it's something in the SQL environment, as it seems like it's forced to Windows Authentication regardless of how I make the connection. Any help would be greatly appreciated.
Updates:
Thanks for the responses. I hope this additional information helps. We are on SQL Server 15.04102.2, and I am using SQL Server Authentication with a generic application ID and PSWD that has update permissions (my individual windows account only has select permissions)
As I indicated in my initial post, if I execute this code against one test environment, the DELETE and INSERT work perfectly. When I execute it against a different environment, the connection is made, but I get the permissions error on the DELETE and INSERT. If I use the exact same credentials and use SQL Server Authentication to go directly to that environment, I can successfully execute the DELETE and INSERT statements.
Here is the error I receive on the DELETE statement. A similar error is received on the INSERT statement if I bypass the delete for a new add.
Error -2147217911 (The DELETE permission was denied on the object
‘BCG_CGS_DETAILS’, database ‘xxxxxxcustom’, schema ‘dbo’.) in
procedure Export CGS to SQL. sSQL = delete dbo.BCG_CGS_DETAILS where
[CGSNUM]= ‘CGS-xxxxx’ AND [PDPD_ID]= ‘xxxxx’ AND EFF_DT=’7/1/2021’
Here is the code I am executing.
Sub Export_CGS_to_SQL()
Dim cnn
Dim rst
Dim sSQL As String
Dim iRow As Integer
Dim sLINE, sCategory, sBCBSNC_Medical_Policy, sBCBSNC_Standard_Provisions As String
Dim sIn_Network_VALUE, sIn_Network_Type_of_payment, sIn_Network_Detail As String
Dim sOut_of_Network_VALUE, sOut_of_Network_Type_of_payment, sOut_of_Network_Detail As String
Dim sCustomized, sCGSNUM, sPDPD_ID, sEFF_DT As String
Dim lLastrow As Long
Dim sServer, sTable, sDatabase, sConnection As String
On Error GoTo errHandler
With Sheets("CGS Data")
sCGSNUM = .Cells(2, 12)
sPDPD_ID = .Cells(2, 13)
sEFF_DT = .Cells(2, 14)
If sCGSNUM = "" Or sPDPD_ID = "0" Or sEFF_DT = "" Then
MsgBox "One or more required fields is blank. Please make sure that the Product ID and Effective date are set correctly on the MISC tab, and that the CGS Number exists for row A06c on the Client Profile tab"
Exit Sub
End If
lLastrow = Cells(Rows.Count, 1).End(xlUp).Row
sServer = Worksheets("MACRO_DATA").Range("B6").Value
sTable = Worksheets("MACRO_DATA").Range("B7").Value
sDatabase = Worksheets("MACRO_DATA").Range("B8").Value
sConnection = Worksheets("MACRO_DATA").Range("F5").Value
'Create a new Connection object
Set cnn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
If cnn.State <> 1 Then
sSQL = "Provider=SQLOLEDB;Data Source=" & sServer & "; Initial Catalog=" & sDatabase & ";" & sConnection & "; Trusted_Connection=yes"
cnn.Open (sSQL)
End If
Set rst.ActiveConnection = cnn
sSQL = "delete " & sTable & " where [CGSNUM]= '" & sCGSNUM & "' AND [PDPD_ID]= '" & sPDPD_ID & "' AND EFF_DT= '" & sEFF_DT & "'"
cnn.Execute sSQL
For iRow = 2 To lLastrow
sLINE = .Cells(iRow, 1)
If sLINE <> "" Then
sCategory = .Cells(iRow, 2)
sBCBSNC_Medical_Policy = .Cells(iRow, 3)
sBCBSNC_Standard_Provisions = .Cells(iRow, 4)
sIn_Network_VALUE = .Cells(iRow, 5)
sIn_Network_Type_of_payment = .Cells(iRow, 6)
sIn_Network_Detail = .Cells(iRow, 7)
sOut_of_Network_VALUE = .Cells(iRow, 8)
sOut_of_Network_Type_of_payment = .Cells(iRow, 9)
sOut_of_Network_Detail = .Cells(iRow, 10)
sCustomized = .Cells(iRow, 11)
sCGSNUM = .Cells(iRow, 12)
sPDPD_ID = .Cells(iRow, 13)
sEFF_DT = .Cells(iRow, 14)
'insert row into sDatabase
sSQL = "insert into " & sTable & "([LINE],[Category],[BCBSNC Medical Policy],[BCBSNC Standard Provisions],[In-Network_VALUE]," _
& "[In-Network_Type of payment],[In-Network Detail],[Out-of-Network_VALUE],[Out-of-Network_Type of payment],[Out-of-Network_Detail]," _
& "[Customized],[CGSNUM],[PDPD_ID],[EFF_DT])" _
& "values ('" & sLINE & "', '" & sCategory & "', '" & sBCBSNC_Medical_Policy & "', '" & sBCBSNC_Standard_Provisions & "', '" _
& sIn_Network_VALUE & "', '" & sIn_Network_Type_of_payment & "', '" & sIn_Network_Detail & "', '" & sOut_of_Network_VALUE & "', '" _
& sOut_of_Network_Type_of_payment & "', '" & sOut_of_Network_Detail & "', '" & sCustomized & "', '" & sCGSNUM & "', '" _
& sPDPD_ID & "', '" & sEFF_DT & "')"
cnn.Execute sSQL
End If
Next iRow
MsgBox "CGS Data successfully exported to " & sTable, vbInformation
cnn.Close
Set cnn = Nothing
End With
Exit Sub
errHandler:
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure Export CGS to SQL. sSQL = " & sSQL
cnn.Close
Set cnn = Nothing
End Sub

Join Excel-Table with SQL Server

My excel-sheet is connected with the data of the sql-server. My clients shall be able to write some columns back to the sql server. The excel-filenames are variable, but the sheeetname and the columns are always static. I tried it with a button and vba but it ends up in error:
Syntaxerror (missing operator) in queryexpression 'UPDATE hbs SET lieferinfo_prio_neu = xlsx.liefer_prio_neu FROM [Provider=SQLOLEDB;Data Source=myserver;Database=mydb;UID=myuser;PWD=mypass;].[tbl_haka_base_size] hbs JOIN [Tabelle3$] xlsx ON xlsx.Artikelnummer'
The internal excel-sheetname is 'Tabelle3', the custom-name is 'Hakabase':
I tried both names without any result.
My code:
Dim excelConn As String
Dim sqlServerConn As String
Dim sqlCommand As String
Dim conn As ADODB.Connection
excelConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" _
& ThisWorkbook.FullName _
& ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;IMEX=1"";"
sqlServerConn = "[Provider=SQLOLEDB;" _
& "Data Source=myserver;" _
& "Database=mydb;" _
& "UID=ymuser;PWD=mypass;]"
sqlCommand = "UPDATE hbs " _
& " SET lieferinfo_prio_neu = xlsx.liefer_prio_neu " _
& " FROM " & sqlServerConn & ".[tbl_haka_base_size] hbs " _
& " JOIN [Tabelle3$] xlsx " _
& " ON xlsx.Artikelnummer=hbs.artikelnummer"
Set conn = New ADODB.Connection
conn.Open excelConn
conn.Execute sqlCommand
I've also tried to connect to the sqlserver + join the excel-data via openrowset but the server disallowed that:
& " JOIN OPENROWSET('MSDASQL', " _
& " 'Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=" _
& ThisWorkbook.FullName & "', 'SELECT * FROM [Tabelle3$]') xlsx" _
Installable ISAM not found
I think I have to create a linked server for each file and enable 'InProcess' for those files. This is not possible because the files are variable.
I've found an alternative solution which is a little bit slow so I still hope someone else is able to answer my question.
The alternative solution is to iterate through each row.. The file got about 150.000 rows and just for 10.000 rows I am waiting about 10 minutes..
Here is the part of iterating
For Each range In sheet.rows: Do
'Continue on headline
If range.Row = 1 Or range.EntireRow.Hidden = True Then
Exit Do
End If
If Len(sheet.Cells(range.Row, lieferInfoColumnIndex)) > 0 Then
articleNumber = sheet.Cells(range.Row, artNoColumnIndex)
UpdateDatabase (articleNumber)
savings = savings + 1
End If
Loop While False: Next range
Here is the slow update function for each row:
Private Sub UpdateDatabase(articleNumber As String)
Dim sqlServerConn As String
Dim sqlCommand As String
Dim conn As ADODB.Connection
sqlServerConn = "Provider=SQLOLEDB;" _
& "Data Source=myserver;" _
& "Database=mydb;" _
& "UID=myuser;PWD=mypass;"
sqlCommand = "UPDATE hbs " _
& "SET lieferinfo_prio_neu=NULL " _
& "FROM [TBL_HAKA_BASE] hbs " _
& "WHERE Artikelnummer=" + articleNumber
Set conn = New ADODB.Connection
conn.Open sqlServerConn
conn.Execute sqlCommand
End Sub

IF adding record is cancelled then return adding another record

Im having a problem of adding records when I click the messagebox and i answered is no then cancel it and add another record but im having a message of connection has not been initialized heres my code thank you.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
Dim reader As SqlDataReader
conn.Open()
Dim bday As String
bday = adyear.Text & "-" & admonth.Text & "-" & adday.Text
If adfirstname.Text.Length < 2 Then
MessageBox.Show("Firstname is too short")
End If
Dim exist As String
exist = "select * from record where firstname='" & adfirstname.Text & "'" & " and lastname='" & adlastname.Text & "';"
cmd = New SqlCommand(exist, conn)
reader = cmd.ExecuteReader
If reader.HasRows = True Then
If MsgBox("THE MEMBER YOU ARE TRYING TO ADD HAS AN SAME FIRSTNAME AND LASTNAME IN THE RECORD DO YOU WISH TO CONTINUE ?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
ElseIf adage.Text < 18 Then
If MsgBox("The member is less than 18 years old is this an intern?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
Dim add As String
add = "insert into record(firstname,middlename,lastname,birthday,age,jobposition)" & _
"values(" & _
"'" & adfirstname.Text & "'," & _
"'" & admiddlename.Text & "'," & _
"'" & adlastname.Text & "'," & _
"'" & bday & "'," & _
"'" & adage.Text & "'," & _
"'" & adjobposition.Text & "');"
cmd = New SqlCommand(add, conn)
cmd.ExecuteNonQuery()
MessageBox.Show("Added Complete")
Else
MsgBox("Action is Terminated")
' code for return to adding and stop the messagebox of the connection has not been initialized
End If
End If
End If
conn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
conn.Dispose()
End Try
End Sub
End Class
Well, since it appears the conn is a form level object you would need to call
conn = New SqlConnection(<connection string>)
before you can use it to open the connection. Given that you call
conn.Dispose()
to destroy the conn instance in the Finally block it appears that you do not keep an open connection around for long.

i want to creat a table on sql server with vb.net where the values are in a datagridview but the update doesn't work

i'm trying to creat a table on my sql server from a datagridview
here's my code
Form2.ShowDialog()
Dim grid = DirectCast(Me.TabControl1.SelectedTab.Controls(0), DataGridView)
Static Dim header As New ArrayList
Dim sql As String
Dim values As String = ""
connection = New SqlConnection("Data Source=ABDELOUAHED;Initial Catalog=table_creances;integrated security=true")
For Each column As DataGridViewColumn In grid.Columns
column.HeaderText = column.HeaderText.Replace(" ", "_")
column.HeaderText = column.HeaderText.Replace("é", "e")
column.HeaderText = column.HeaderText.Replace("'", "")
header.Add(column.HeaderText)
Next
sql = "CREATE TABLE " & Form2.TextBox1.Text & "(" & header(0) & " int PRIMARY KEY NOT NULL," & header(1) & " int," & header(2) & " int," & header(3) & " real," & header(4) & " real," & header(5) & " date," & header(6) & " date," & header(7) & " real," & header(8) & " int)"
Try
Dim Mycommand As SqlCommand = New SqlCommand(sql, connection)
Mycommand.Connection.Open()
Mycommand.ExecuteNonQuery()
Mycommand.Connection.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
Try
cmdBuilder = New SqlCommandBuilder(adapter)
changes = ds.GetChanges()
If changes IsNot Nothing Then
adapter.Update(changes)
End If
MsgBox("Changes Done")
Catch ex As Exception
MsgBox(ex.ToString)
End Try
the table is created but it contains no value, the update part doesn't work
any help would be very appreciated

Missing semicolon (;) at the end of SQL statement when insert data to ms access table

this is my code
dim straccess as string
Do While Not rso.EOF
30 straccess = "INSERT INTO [test] ([nik],[nama]) VALUES ('" & rso.Fields(0)
& "' ,'" & rso.Fields(1) & "' ) where [nama]= '" _
& rso.Fields(0) & "';"
cna.Execute straccess
Loop
got error on line 30 when insert data.
im type this code in vb6 n want to insert data from oracle database/table to msaccess database/table. i already hv connection to oracle table n ms access. And now I try to insert data into MS Access table based data in oracle table
my table name in ms access is TEST and my table name in empmasterepms.
this is my all code .
Dim vstr As String
Dim filename As String
Dim straccess As String
Option Explicit
Const ORACLEQUERY As String = "select empcode,empname from empmasterepms order by EMPNAME"
Dim cno As New ADODB.Connection
Dim cna As New ADODB.Connection
Dim rso As New ADODB.Recordset
Dim rsa As New ADODB.Recordset
Private Sub btnload_Click()
On Error GoTo Error_Handler
'-----------------Connection to Oracle
cno.Open "Provider=msdaora;Data Source=192.168.0.15:1521/EPMS;User Id=EPMS_TRXI;Password=epmse292014;"
rso.CursorType = adOpenStatic
rso.CursorLocation = adUseClient
rso.LockType = adLockOptimistic
rso.Open ORACLEQUERY, cno, , , adCmdText
Set dg1.DataSource = rso
------- connect to msaccess
cna.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & vstr
rso.MoveFirst
Do While Not rso.EOF
30 straccess = "Update test SET [nik] = '" & rso.Fields(0).Value & "' ,[nama] = '" & rso.Fields(1).Value & "' WHERE [nama] = '" & rso.Fields(1).Value & "';"
cna.Execute straccess
rso.MoveNext
Loop
MsgBox "Done"
cno.Close
Set cno = Nothing
Set cna = Nothing
Exit Sub
Error_Handler:
MsgBox Erl & ":" & Err.Number & ":" & Err.Description
Debug.Print (straccess)
end sub
Remove the Where statement:
30 straccess = "INSERT INTO [test] ([nik],[nama]) VALUES ('" & rso.Fields(0).Value & "','" & rso.Fields(1).Value & "');"

Resources