I have a SQL Server database with a table called tblFeatures with 2 columns Feature (Nvarchar(50)) and Setting (bit). I am trying to set the value of this Setting for each Feature via a check box in VB NET. I have tried using True/False 0/1 but have not had luck doing so using SQL parameters. I can do this fine using a normal SQL Update command:
"UPDATE tblSettings SET [Setting]='" & True & "' WHERE Feature='FSCreateTicket'"
However, I want to do it the proper/safe way with SQL parameters. I have scoured Stack and Google results have not found the proper way to get this done. I either get an error, or no error but the value does not get updated.
Here is what I have am currently trying:
Public Function ChangeSetting(ByVal strFeature As String, ByVal bSetting As Boolean)
Dim sqlcmd As New SqlCommand
Try
MYSQL.Open()
sqlcmd.Connection = MYSQL
sqlcmd.CommandText = "UPDATE tblSettings SET Setting='#setting' WHERE Feature='#feature'"
sqlcmd.Parameters.Add("#setting", SqlDbType.Bit).Value = bSetting
sqlcmd.Parameters.Add("#feature", SqlDbType.NVarChar, 50).Value = strFeature
sqlcmd.ExecuteNonQuery()
I am getting the error
Conversion failed when converting the varchar value '#setting' to data type bit
I don't understand why it says varchar when the variable sent is boolean and I have declared the SqlDbType as bit.
I have also tried using the AddwithValue parameter without luck.
Public Function ChangeSetting(ByVal strFeature As String, ByVal bSetting As Boolean)
Dim sqlcmd As New SqlCommand
Try
MYSQL.Open()
sqlcmd.Connection = MYSQL
sqlcmd.CommandText = "UPDATE tblSettings SET Setting='#setting' WHERE Feature='#feature'"
sqlcmd.Parameters.AddWithValue("#setting", bSetting)
sqlcmd.Parameters.Add("#feature", SqlDbType.NVarChar, 50).Value = strFeature
sqlcmd.ExecuteNonQuery()
This produces no error, but values are not updated. Please help!
Remove the single quotes a around the parameters in your query text, i.e. change
...
sqlcmd.CommandText = "UPDATE tblSettings SET Setting='#setting' WHERE Feature='#feature'"
...
to:
...
sqlcmd.CommandText = "UPDATE tblSettings SET Setting=#setting WHERE Feature=#feature"
...
When using parameterized queries, quotes will placed if needed you don't have to do it manually and you shouldn't.
Related
I have a simple button which end the Work day in my Management System. Sadly when pressed all fine but the Column in my Table is still empty.
Here is the code:
Dim sql As String = "UPDATE [TA-Arbeitszeit] SET Ende = #ende WHERE Personal_nr = #Personal_nr"
Using conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:\recycle2000.mdb;"),
cmd As New OleDbCommand(sql, conn)
conn.Open()
cmd.Parameters.Add("#Personal_nr", OleDbType.VarChar).Value = tbxUserInput.Text.Trim()
cmd.Parameters.Add("#ende", OleDbType.VarChar).Value = DateTime.Now.ToString("G")
Dim icount As Integer = cmd.ExecuteNonQuery
End Using
Access doesn't fully support named parameters. Although you can and should use parameter names for your own clarity, Access ignores them. It simply inserts your parameter values into the SQL code in the order they are added. That means that they need to be added in the same order as they appear in the SQL code. Your SQL code has #ende before #Personal_nr but when you add parameters you do it the other way around. Switch the order in which you add the parameters and you should hopefully be fine.
I'm trying to display the results of a simple SQL sum... I have the following SQL command on my .asp page using vb:
<%
Dim QtyTotal
QtyTotal = "SELECT SUM(Qty_SAL) FROM dbo.tbl_stock_at_locations"
Response.Write(QtyTotal)
%>
The output (QtyTotal) is written as the SQL statement itself and not the value.
Try adding something like this to connect to your database and to run your query.
Dim con As SqlConnection = New SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\MyDB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True")
Dim cmd As SqlCommand = New SqlCommand("SELECT SUM(Qty_SAL) FROM dbo.tbl_stock_at_locations", con)
con.Open()
cmd.ExecuteNonQuery()
con.Close()
There are tons of articles out there on how to do this, please refer to google.com
You have this value:
"SELECT SUM(Qty_SAL) FROM dbo.tbl_stock_at_locations"
That's just a string literal. Nothing more. Assigning it to QtyTotal just means the variable is a string with the SQL command text as it's value.
If you want to run the statement and get the result, you need to create an ADO.Connection object to the connect to a database server, create an ADO.Command object to hold your SQL statement, and associate the command with the connection. Then you can .Open the connection and .Execute the command to get an object back for reading results... the kind of object will depend on how you execute the command. Once you have this object, you have to actually read from it to assign the final value to QtyTotal.
I am new to this forum, please could you help me get this code to work, when i execute it, it simply does nothing and does not update the DB. If i remove the square brackets it gives an error: "SYNTAX ERROR in UPDATE statement"
Any help appreciated!
Dim connection As OleDbConnection
connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=UserDB.accdb;Jet OLEDB:Database;")
connection.Open()
Dim pass As String
pass = txtconfirm.Text
Dim user As String
user = LoginForm.UsernameTextBox.Text
Dim query As String = "UPDATE [Users] SET [Password]= '" & pass & "' WHERE [Username]= '" & user & "';"
Dim command As New OleDbCommand(query, connection)
command.ExecuteNonQuery()
connection.Close()
Given your actual connection string, the database that will be updated is the one in the directory where your application starts. This means that if you work with a WinForms application this folder is \BIN\DEBUG or x86 variant. If there is not error then you could get the return value of the ExecuteNonQuery call to verify if a record has been updated or not
Dim rowsUpdated = command.ExecuteNonQuery()
MessageBox.Show("Record updated count = " & rowsUpdated)
If this value is not zero then your database has been updated and you are looking for changes in the wrong database. Check the one in the BIN\DEBUG folder.
In any case your code has big problems. If your variables user or pass contain a single quote, then your code will crash again because your string concatenation will form an invalid SQL. As usual the only workaround is to use a parameterized query
Dim pass = txtconfirm.Text
Dim user = LoginForm.UsernameTextBox.Text
Dim query As String = "UPDATE [Users] SET [Password]= #p1 WHERE [Username]= #p2"
Using connection = New OleDbConnection("...........")
Using command As New OleDbCommand(query, connection)
connection.Open()
command.Parameters.Add("#p1", OleDbType.VarWChar).Value = pass
command.Parameters.Add("#p2", OleDbType.VarWChar).Value = user
command.ExecuteNonQuery()
End Using
End Using
The parameterized approach has many advantages. Your query text is more readable, there is no misunderstanding between your code and the values expected by your database engine. And while not easy to exploit with MS-Access there is no problem with Sql Injection
I think Steve presents a much better approach for you coding this...
Let me just throw out a few more things:
The reason you can't take those brackets out is some of your column names are reserved words; just FYI.
Since you report "it does nothing..." when you execute, it sounds like you have a valid connection and sql syntax, in which case my next step would be to copy the sql command text while in debug mode, change it to a select and run it in your DB. You should get one result when you do. If not, either your criteria or field contents are not what you think they are...
Just change the Update table SET field-value ... to SELECT * FROM table and leave the WHERE clause as is.
<%
postit = request.querystring("thispost")
response.write(postit)
%>
postit is the variable. The response.write works and this is all above the SQL statement below.
This is the SQL however when I add the postit variable I get this error message:
delCmd.CommandText="DELETE * FROM post WHERE (pos_ID = postit )"
Microsoft Access Database Engine error '80040e10'
No value given for one or more required parameters.
/student/s0190204/wip/deleterecord.asp, line 32
Add a parameter to the SQL:
delCmd.CommandText="DELETE * FROM post WHERE (pos_ID = ?)"
delCmd.Parameters.Append delCmd.CreateParameter("posid", adInteger, adParamInput) ' input parameter
delCmd.Parameters("posid").Value = postit
Couple of things that will help you in the future
Use Option Explicit to avoid hiding issues that will come back to bite you later on
Use ADODB.Command object, which is very versatile enabling to do a range of database calls, from simple dynamic SQL statements to Stored Procedures without the risk of SQL injection.
There are a few tips that can speed things up when using the ADODB.Command object in your code which will be demonstrated in the example below (assumes you already have a connection string stored in a global config call gs_connstr);
<%
Option Explicit
Dim postit
postit = Request.QueryString("thispost")
'Always do some basic validation of your Request variables
If Len(postit) > 0 And IsNumeric(postit) Then CLng(postit) Else postit = 0
Dim o_cmd, o_rs, a_rs, i_row, i_rows, l_affected
Dim SQL
'SQL statement to be executed. For CommandType adCmdText this can be any dynamic
'statement, but adCmdText also gives you an added bonus - Parameterised Queries
'instead of concatenating values into your SQL you can specify placeholders (?)
'that you will define values for that will get passed to the provider in the order
'they are defined in the SQL statement.
SQL = "DELETE * FROM post WHERE (pos_ID = ?)"
Set o_cmd = Server.CreateObject("ADODB.Command")
With o_cmd
'ActiveConnection will accept a Connection String so there is no need
'to instantiate a separate ADODB.Connection object the ADODB.Command object
'will handle this and also open the connection ready.
.ActiveConnection = gs_connstr
.CommandType = adCmdText
.CommandText = SQL
'When using Parameters the most important thing to remember is the order you
'appended your parameters to the Parameters collection as this will determine
'the order in which they are applied to your SQL query at execution. Because
'of this the name you give to your parameters is not important in terms of
'execution but I find specifying a meaningful name is best (especially when
'revisiting some code a few years down the line).
Call .Parameters.Append(.CreateParameter("#pos_ID", adInteger, adParamInput, 4))
'Parameter values can be passed in via the Execute() method using an Array
'without having to define the parameter values explicitly. You can also specify
'the records affected value to return number of rows affected by a DELETE,
'INSERT or UPDATE statement.
.Execute(l_affected, Array(postit))
End With
'Always tidy up after yourself, by releasing your object from memory, this will
'also tidy up your connection as it was created by the ADODB.Command object.
Set o_cmd = Nothing
%>
Try this code:
<% Dim postit, stringSQL, objectCon
postit = request.querystring("thispost")
Set objectCon = Server.CreateObject("ADODB.Connection")
objectCon.ConnectionString "Driver={SQL SERVER};Server=server_name;UID=user_name;PWD=password;Database=database_name" 'SET CONNECTION STRING OF YOUR DATABASE
stringSQL = "DELETE FROM post WHERE pos_id='" & postit & "'"
objectCon.Open
objectCon.Execute(stringSQL)
objectCon.Close() %>
You're not passing the value of postit to Access; instead, you're telling Access to find & use a variable called postit. Of course, said variable doesn't exist in Access -- it only exists in your code. The fix is just a couple of quote marks and a pair of ampersands.
delCmd.CommandText="DELETE * FROM post WHERE (pos_ID = " & postit & " )"
(Naturally, you should validate postit before you go sending it off to your database. A simple CDbl() can do the trick, assuming it's a numeric value.)
Here I'm trying to get the car_color of the car using the id of the car.
Now I can use the car_color record set in my code.
I would also recommend using CLng when passing in values, it'll prevent sql injections.
If the carID is not a number you'll get the following error:
"500 response from the server. Remember to open and close the sql connection."
Here is the code:
sql = "Select * from Cars Where ID = " & clng(carID)
rs.open
if not rs.eof then
carID = rs("car_ID")
carColor = rs("car_color")
end if
rs.close
More easy for delete, this way is useful when not need to check the recordset:
cn.open "yourconnectionstring"
cn.execute "DELETE * FROM post WHERE pos_ID = " & request.querystring("thispost")
cn.close
Just began using PostgresQL for a vb application (using visual studio 2005 pro) and connect via ODBC (there's a reason for using the ODBC connection and not the native PostgresQL connector) .
I'm used to using the #something and cmd.Parameters.Add("#something", data) format with MSSQL. I have 9 values i want to get from a form and use them in an insert statement but can't seem to figure the syntax for PostgresQL out.
Ideas? I've searched for two days trying to find an answer to this btw.
Edit: Sorry, I already deleted the code I was trying, but I kept getting "the column does not exist" error on column "name" which is my first paramater.
I know it's not a connection error or a naming convention issue or something like that because the following code does work. Here's how I'm doing it now for testing:
strSQL = "INSERT INTO tableb (name, extension, length,creationtime,lastaccesstime,lastwritetime,directoryname) VALUES ('Name','Extension','Length','CreationTime','LastAccessTime','LastWriteTime','DirectoryName')"
objConn.ConnectionString = strConnString
objConn.Open()
With objCmd
.Connection = objConn
.CommandText = strSQL
.CommandType = CommandType.Text
.ExecuteNonQuery()
End With
Oh, and the ODBC version I'm using is 8.03.02.00
More info:
The code causing the error:
strSQL = "INSERT INTO TABLEB (name) VALUES (#name)"
objConn.ConnectionString = strConnString
objConn.Open()
'Try
With objCmd
.Parameters.Add("#name", SqlDbType.Int)
.Parameters("#name").Value = "SomeText"
.Connection = objConn
.CommandText = strSQL
.CommandType = CommandType.Text
.ExecuteNonQuery()
End With
Code with parameters:
The exact error: ODBC Exception:
"ERROR [42703] ERROR: column "name" does not exist;
Error while executing the query"
The error occurs on the .ExecuteNonQuery
Thanks again!
problem is with below code
.Parameters.Add("#name", SqlDbType.Int)
.Parameters("#name").Value = "SomeText"
you set name as SqlDbType.Int but you set text value to it
give correct column type when declare the parameters and assign correct value which match with given data type.
And also give parameters as ? in sql statement and then add the command parameters in the same sequence given in the sql. ODBC do not support named parameters.
sample code :
strSQL = "INSERT INTO TABLEB (name) VALUES (?)"
objConn.ConnectionString = strConnString
objConn.Open()
With objCmd
.Parameters.AddWithValue("name", "SomeText")
.Connection = objConn
.CommandText = strSQL
.CommandType = CommandType.Text
.ExecuteNonQuery()
End With
As written that query is fine. Given the stated error, likely issues are:
Capitalization problems with quoting. If your column is defined as "Name" you need to refer to it as "Name" everywhere, not Name or name. See lexical structure.
Accessing the wrong database or an older version of the same database you set up and forgot, one that contains a tableb without a name column
In "anonymizing" the query you've hidden the real problem, or the error you quote doesn't match the code you're running. For example, quoting issues.
Are you sure the code you show is what you're getting the error from? You talk about #parameter etc in the text, but there's nothing like that in the code...
You should certainly be using parameterized queries instead of this approach to prevent SQL injection attacks, since I'm sure your real code doesn't hard code the values. Parameter use should be no different between psqlODBC and MS SQL Server's ODBC driver, that's half the point of query parameters. I don't speak Visual Basic (or ODBC if I can avoid it) and the SQL injection rosetta stone doesn't have details for VB.NET. Try doing what you do with MS SQL Server and if you have issues, follow up with a new question that includes the exact code and errors.