Having trouble understanding the # parameter in a SQL command - vb.net

Good morning,
I am having trouble understanding the # parameter in vb.net. if we take the example code for the msdn:
' Update the demographics for a store, which is stored
' in an xml column.
Dim commandText As String = _
"UPDATE Sales.Store SET Demographics = #demographics " _
& "WHERE CustomerID = #ID;"
Using connection As New SqlConnection(connectionString)
Dim command As New SqlCommand(commandText, connection)
' Add CustomerID parameter for WHERE clause.
command.Parameters.Add("#ID", SqlDbType.Int)
command.Parameters("#ID").Value = customerID
' Use AddWithValue to assign Demographics.
' SQL Server will implicitly convert strings into XML.
command.Parameters.AddWithValue("#demographics", demoXml)
There seem to be no problem at all, however when you try to add more parameters into the mix, it does not seems to work. What would be the correct syntax to add more than one parameter?
Here is my piece of code:
query &= "INSERT INTO "
query &= imageProcAlgo.GetSqlTable()
query &= " ( #dateTimeStampCol , #numberOfBlobsCol , #AvgLengthCol , #avgWidthCol ) "
query &= "Values (#dtsvalue, #nbOfBlobsValue, #avgLengthValue, #avgWidthValue)"
and here where I try to add values to those parameters:
Using conn As New SqlConnection(connectStr)
Using comm As New SqlCommand(query)
With comm
.Connection = conn
.CommandType = CommandType.Text
.Parameters.AddWithValue("#dateTimeStampCol", "DateTimeStamp")
.Parameters.AddWithValue("#numberOfBlobsCol", "NumberOfBlob")
.Parameters.AddWithValue("#AvgLengthCol", "AvgWidth")
.Parameters.AddWithValue("#avgWidthCol", "AvgLength")
.Parameters.AddWithValue("#dtsvalue", "CURRENT_TIMESTAMP")
.Parameters.AddWithValue("#nbOfBlobsValue", imageProcAlgo.GetnumberOfBlobs().ToString())
.Parameters.AddWithValue("#avgLengthValue", imageProcAlgo.GetAvgWidth())
.Parameters.AddWithValue("#avgWidthValue", imageProcAlgo.GetAvgLength())
End With
Try
conn.Open()
comm.ExecuteNonQuery()
conn.Close()
Catch ex As SqlException
MessageBox.Show(ex.Message.ToString(), "Error Message")
End Try
End Using
When I try to execute this piece of code, I get an error saying that #datetimestampcol and so on are not valid column names.
I don't seem to understand what is the difference between the MSDN anf my code but i feel pretty close.. Any pointers for me to understand a bit better? to figure out where I went wrong?
Thanks,

Related

get last inserted primary key record in database

Please help to get the primary key of the last insert record as the one which i have gives me duplicate rows in the database and return 0
Try
If Conn.State = ConnectionState.Open Then Conn.Close()
'insert the new customer data
Conn.Open()
cmd = New SqlCommand("insert into Quote values ('" & dateOFCreat & "','" & Emp & "','" & Customer_no & "' )", Conn)
Dim a As Integer = cmd.ExecuteNonQuery()
Dim results As Integer
Dim cmd_results As SqlCommand
'Get the last created Quote in the Database
cmd_results = New SqlCommand("Select ##Identity from Quote", Conn)
results = cmd.ExecuteScalar
TxtLastQuoteID.Text = results
If a = 0 Then
MsgBox("Error")
End If
Conn.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
You can make use of the batch commands supported by Sql Server. Just put together the two instructions and just use ExecuteScalar. However, before that, you need to fix ASAP your Sql Injection vulnerability. Do not concatenate strings to build an sql command, but use parameters.
Try
Using con as SqlConnection = new SqlConnection(....constringhere...)
Conn.Open()
Dim sqlText = "insert into Quote values (#dat,#emp,#cusno); SELECT SCOPE_IDENTITY()"
cmd = New SqlCommand(sqlText,Conn)
cmd.Parameters.Add("#dat", SqlDbType.NVarChar).Value = dateOFCreat
cmd.Parameters.Add("#end", SqlDbType.NVarChar).Value = emp
cmd.Parameters.Add("#cusno", SqlDbType.NVarChar).Value = Customer_no
Dim lastID As Integer = cmd.ExecuteScalar()
TxtLastQuoteID.Text = lastID.ToString()
Conn.Close()
End Using
Catch ex As Exception
MsgBox(ex.Message)
End Try
Notice also that is a very bad thing to keep a global connection object. You don't need that because ADO.NET implements Connection Pooling that makes opening a connection a very fast operation. Instead keeping a connection around requires a lot of effort to work correctly around it
Finally you can look here to better understand the difference between SCOPE_IDENTITY and ##IDENTITY and why is usually better to use the first one.

how to insert a row to my db table from vb.net

am using vb.net, and i want to insert a row to my db Table "adwPays" from my windows form.
this is my code:
Dim CC, EngName, FreName, LanCode As String
Dim DialCode As Integer
CC = txtCC.Text
EngName = txtEN.Text
FreName = txtFN.Text
LanCode = txtLC.Text
DialCode = txtDC.Text
Dim MyConn As New SqlConnection("Server=(local);Database=dbAjout;Integrated Security=True")
Dim query As String
query = "INSERT INTO adwPays (CC, Anglais,Francais,CodeLangue,IndicInter) VALUES ( ' " & CC & "','" & EngName & "','" & FreName & "','" & LanCode & "','" & DialCode & " ');"
Dim cmd As New SqlCommand(query, MyConn)
MyConn.Open()
cmd.ExecuteScalar()
MyConn.Close()
BUT its giving me this error
"An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: String or binary data would be truncated.
The statement has been terminated."
any help?
Use a parameterized query like this
Dim query = "INSERT INTO adwPays (CC, Anglais,Francais,CodeLangue,IndicInter) " &
"VALUES (#cc, #ename, #fname, #lan, #dial)"
Using MyConn = New SqlConnection("Server=(local);Database=dbAjout;Integrated Security=True")
Using cmd = New SqlCommand(query, MyConn)
cmd.Parameters.AddWithValue("#cc", CC)
cmd.Parameters.AddWithValue("#ename", EngName)
cmd.Parameters.AddWithValue("#fname", FreName)
cmd.Parameters.AddWithValue("#lan", LanCode)
cmd.Parameters.AddWithValue("#dial", DialCode)
MyConn.Open()
cmd.ExecuteNonQuery()
End Using
End Using
Using a parameterized query allows to avoid problems with Sql Injections and clears the command text from the formatting quotes around strings and dates and also let the framework code pass the correct decimal point for the numeric types when need
I have also added a Using Statement around the SqlConnection and the SqlCommand to be sure that the objects are closed and destroyed. The parameters are all passed as strings, this could be wrong if any of your database fields are not of text type.
It sounds like you have a String value that is longer than the database type size allows. Can you verify the type and size of each of the following fields:
cc
ename
fname
lan
Now cross-reference those sizes with what the values are in the textbox fields you are pulling them from in the UI.
My money is on one of those exceeding the database size limits.
If that is the case, then you need to introduce length checking before you attempt to save to the database.

Data type mismatch in criteria expression. -Microsoft JET DATABASE ENGINE

In the code below, it was a "delete" button used in OLEDB connection.
My database table name is tblinformation.
Btw, the error shows:
Data type mismatch in criteria expression. `-Microsoft JET DATABASE ENGINE`, and it was in a form of msgbox..
Imports System.Data.OleDb
Imports System.String
Public Class frmbookinfo
Dim cnn As New OleDb.OleDbConnection
Dim Str As String
If CheckId() = False Then
MsgBox("Id : Integer Value Required!!!")
Exit Sub
End If
Try
Str = "delete from tblinformation where bcode="
Str += txtbookcode.Text.Trim
Con.Open()
Cmd = New OleDbCommand(Str, Con)
Cmd.ExecuteNonQuery()
Dst.clear()
Dad = New OleDbDataAdapter("SELECT * FROM tblinformation ORDER BY bcode", Con)
Dad.Fill(Dst, "tblinformation")
MsgBox("Record deleted successfully...")
If CurrentRow > 0 Then
CurrentRow -= 1
ShowData(CurrentRow)
End If
Con.Close()
Catch ex As Exception
MessageBox.Show("Could Not delete Record!!!")
MsgBox(ex.Message & " - " & ex.Source)
Con.Close()
End Try
Probably your field bcode in the database is of type text.
You use a string concatenation to build your command text and this cannot be helped if you fail to treat your values correctly.
Instead use parametrized queries and leave the task to correctly parse your parameters to the database framework code
Str = "delete from tblinformation where bcode=?"
Con.Open()
Cmd = New OleDbCommand(Str, Con)
Cmd.Parameters.AddWithValue("#p1", txtbookcode.Text.Trim)
Cmd.ExecuteNonQuery()
Now your sql command contains a parameter placeholder (?) and the correct parameter value is assigned in the parameter collection. The framework code handles correctly this parameter
EDIT If your bcode field is a text field, you cannot build your command in that way. You should encapsulate your value between single quotes. Something like this.
IT WORKS BUT IT IS WRONG - VERY WRONG -
Str = "delete from tblinformation where bcode='" & txtbookcode.Text.Trim & "'"
But this is wrong from the start.
First - If your txtbookcode contains a single quote, the whole
command text becomes invalid and you get a Syntax Error
Second - String concatenation is bad because you can't trust your user.
If it enters some malicious text you could face a Sql Injection
problem
So, I really suggest you to use the parametrized query approach illustrated in the first example

How do I assign the results of an SQL query to multiple variables in VB.NET?

This is my first attempt at writing a program that accesses a database from scratch, rather than simply modifying my company's existing programs. It's also my first time using VB.Net 2010, as our other programs are written in VB6 and VB.NET 2003. We're using SQL Server 2000 but should be upgrading to 2008 soon, if that's relevant.
I can successfully connect to the database and pull data via query and assign, for instance, the results to a combobox, such as here:
Private Sub PopulateCustomers()
Dim conn As New SqlConnection()
Dim SQLQuery As New SqlCommand
Dim daCustomers As New SqlDataAdapter
Dim dsCustomers As New DataSet
conn = GetConnect()
Try
SQLQuery = conn.CreateCommand
SQLQuery.CommandText = "SELECT Customer_Name, Customer_ID FROM Customer_Information ORDER BY Customer_Name"
daCustomers.SelectCommand = SQLQuery
daCustomers.Fill(dsCustomers, "Customer_Information")
With cboCustomer
.DataSource = dsCustomers.Tables("Customer_Information")
.DisplayMember = "Customer_Name"
.ValueMember = "Customer_ID"
.SelectedIndex = -1
End With
Catch ex As Exception
MsgBox("Error: " & ex.Source & ": " & ex.Message, MsgBoxStyle.OkOnly, "Connection Error !!")
End Try
conn.Close()
End Sub
I also have no problem executing a query that pulls a single field and assigns it to a variable using ExecuteScalar. What I haven't managed to figure out how to do (and can't seem to hit upon the right combination of search terms to find it elsewhere) is how to execute a query that will return a single row and then set various fields within that row to individual variables.
In case it's relevant, here is the GetConnect function referenced in the above code:
Public Function GetConnect()
conn = New SqlConnection("Data Source=<SERVERNAME>;Initial Catalog=<DBNAME>;User Id=" & Username & ";Password=" & Password & ";")
Return conn
End Function
How do I execute a query so as to assign each field of the returned row to individual variables?
You probably want to take a look at the SqlDataReader:
Using con As SqlConnection = GetConnect()
con.Open()
Using cmd As New SqlCommand("Stored Procedure Name", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("#param", SqlDbType.Int)
cmd.Parameters("#param").Value = id
' Use result to build up collection
Using dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection Or CommandBehavior.SingleResult Or CommandBehavior.SingleRow)
If (dr.Read()) Then
' dr then has indexed columns for each column returned for the row
End If
End Using
End Using
End Using
Like #Roland Shaw, I'd go down the datareader route but an other way.
would be to loop through
dsCustomers.Tables("Customer_Information").Rows
Don't forget to check to see if there are any rows in there.
Google VB.Net and DataRow for more info.

Selecting an integer from an Access Database using SQL

Trying to select an integer from an Access Database using an SQL statement in VB
Dim cmdAutoTypes As New OleDbCommand
Dim AutoTypesReader As OleDbDataReader
cmdAutoTypes.CommandText = "SELECT * FROM AutoTypes WHERE TypeId = '" & cboTypeIds.Text & "'"
AutoTypesReader = cmdAutoTypes.ExecuteReader
Error message says: "OleDbException was unhandled: Data type mismatch in criteria expression." and points to the AutoTypesReader = cmdAutoTypes.ExecuteReader line
Rather make use of OleDbParameter Class
This will also avoid Sql Injection.
You don't need the quotes in the query string. You're searching for a number, not a string.
cmdAutoTypes.CommandText = "SELECT * FROM AutoTypes WHERE TypeId = " & cboTypeIds.Text
Hi In access SQL you can't use single quote around your Integer type.
so
command text will be.. "SELECT * FROM AutoTypes WHERE TypeId = " & cboTypeIds.Text & " and .... "
In Access SQL, don't quote numeric constants.
And test whether IsNull(cboTypeIds). You can't do what you were planning to do until a value has been chosen.
Do not use string concatenation when you build your SQL query, use parameters instead.
Dim cmd As OledbCommand = Nothing
Dim reader as OleDbDataReader = Nothing
Try
Dim query As String = "SELECT * FROM AutoTypes WHERE TypeId = #Id"
cmd = New OledbCommand(query, connection)
//adding parameter implicitly
cmd.Parameters.AddWithValue("#Id", cboTypeIds.Text)
reader = cmd.ExecuteReader()
Catch ex As Exception
Messagebox.Show(ex.Message, MsgBoxStyle.Critical)
End Try
You can also explicitly state the parameter data type.
cmd.Parameters.Add("#Id", OleDbType.Integer).Value = cboTypeIds.Text
Hope this helps.