I'm trying to convert legacy (VB.net) code that is using SqlConnection() to send parameters to a Stored Procedure. My main goal here is to rewrite this so that it utilizes OLEDB instead but I've come across multiple errors due to one of the parameters being a SqlDbType.Structured.
Is there a way to make SqlDbType.Structured pass through in a OLEDB connection?
Original Code:
mySQLConn = New SqlConnection()
mySQLConn.ConnectionString = strConn
mySQLConn.Open()
SQLcommand= New SqlCommand("stored_procedure", mySQLConn)
SQLcommand.CommandType = CommandType.StoredProcedure
SQLcommand.CommandTimeout = 0
mySqlTableTypeParam = SQLcommand.Parameters.Add("#InBoundData", SqlDbType.Structured) ' This line for reference
mySqlTableTypeParam.Value = AddUpdate
mySqlCleanupParam = SQLcommand.Parameters.Add("#sResponse", SqlDbType.VarChar)
mySqlCleanupParam.Value = strResponse
SQLcommand.ExecuteNonQuery()
My New OLEDB Code:
If oConnection Is Nothing Then oConnection = New Connection(Me.strConnection)
oConnection.Open()
cmd = New OleDbCommand
With cmd
.CommandType = CommandType.StoredProcedure
.CommandText = "stored_procedure"
.Connection = oConnection.Connection
.CommandTimeout = 0
.Parameters.Add("#sResponse", OleDbType.VarChar, 25)
.Parameters("#sResponse").Value = strResponse ' Expected to either be "N" or "Y"
.Parameters.Add("#InBoundData", System.Data.SqlDbType.Structured) ' I've run out of ideas
.Parameters("#InBoundData").Value = AddUpdate
End With
cmd.ExecuteNonQuery()
Errors:
Run Results: System Error:System.InvalidOperationException: Provider
encountered an error while sending command parameter[0] '' value and
stopped processing. Command parameter[1] '' data value could not be
converted for reasons other than sign mismatch or data overflow. --->
System.Data.OleDb.OleDbException: Invalid character value for cast
specification --- End of inner exception stack trace ---
Related
Dim sc = datagridview.rows(0).cells(0).value
cmd = New SqlCommand("insert into Schedule (Name) values(#sc)", con)
with cmd
.Connection = con
.CommandType = CommandType.Text
.Parameters.AddWithValue("#sc", sc.cells(0))
end with
The value from the datagrid view contains an apostrophe where I get an error in ('s). Any work around with this?
EDIT:
This is the error:
SqlException was unhandled. Incorrect syntax near 's'.
EDIT 2: i've revised the code to this:
for 1=0 to datagridview.rows.count -1
Dim tname = datagridview.Rows(i)
cmd = New SqlCommand("insert into Schedule (Name) values(#sc)", con)
with cmd
.Connection = con
.CommandType = CommandType.Text
.Parameters.AddWithValue("#sc", sc.cells(0).value)
end with
con.Close()
con.Open()
If Not cmd.ExecuteNonQuery() > 0 Then
con.Close()
Exit For
End If
next
Error is still the same.
As it goes through all the values quickly in one go, I would make the connection once and change the value of the parameter for each iteration, like this:
Dim sql = "INSERT INTO [Schedule] ([Name]) VALUES(#sc)"
Using conn As New SqlConnection("your connection string"),
cmd As New SqlCommand(sql, conn)
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "#sc",
.SqlDbType = SqlDbType.NVarChar,
.Size = -1})
conn.Open()
For i = 0 To dgv.Rows.Count - 1
Dim tname = dgv.Rows(i).Cells(0).Value.ToString()
cmd.Parameters("#sc").Value = tname
cmd.ExecuteNonQuery()
Next
End Using
Including the size of the parameter in its declaration helps SQL Server keep things tidy (it only needs one entry in the query cache).
The Using statement makes sure that the connection and command are disposed of properly when they are finished with.
The purpose of checking If Not cmd.ExecuteNonQuery() > 0 was not clear to me, so I didn't put that in.
(I used "dgv" as the name of the DataGridView.)
Try to replace the " ' " by " '' "
Dim sc = datagridview.rows(0).cells(0).value
cmd = New SqlCommand("insert into Schedule (Name) values(#sc)", con)
with cmd
.Connection = con
.CommandType = CommandType.Text
.Parameters.AddWithValue("#sc", replace(sc.cells(0), "'", "''")
end with
/**** EDIT ****/
I will consider by the way that your code have a problem with the affectation of the value. You get the value into SC then try to get again the value from cell
Dim sc = datagridview.rows(0).cells(0).value
cmd = New SqlCommand("insert into Schedule (Name) values(#sc)", con)
with cmd
.Connection = con
.CommandType = CommandType.Text
.Parameters("#sc").value = sc.replace("'", "''")
end with
Public Function Does_User_Exist(ByVal strEmpId As String) As Boolean
Try
Dim strSQL As String = "DATA.DOES_USER_EXIST"
Dim cmd As OracleCommand = dba.CreateStoredProcCommand(strSQL)
cmd.Connection.Open()
If cmd.Connection.State = ConnectionState.Open Then
With cmd
' CRASHING ON NEXT LINE. I CHANGED THE ORDER AND MADE IT ALL CAPS.
.Parameters.Add(name:="EMPLOYEE", dbType:=OracleClient.OracleType.VarChar, size:=8).Value = strEmpId
.Parameters.Add(name:="ROWCOUNT", dbType:=OracleClient.OracleType.Number).Direction = ParameterDirection.Output
End With
dba.ExecuteScaler(cmd)
If cmd.Parameters("RowCount").Value.ToString = 1 Then
Return True
Else
Return False
End If
End If
Catch ex As Exception
Dim DATAErr As New DATA_Errors("DATA_Users", "Does_User_Exist", ex)
Return False
Finally
End Try
End Function
I checked the connection state and it's Open
Message = "Object reference not set to an instance of an object."
"Oracle.DataAccess"
I am not sure what else to do. I am migrating to ODP.NET from the deprecated Microsoft/Oracle class.
I think the issue is coming from the Parameters. Not sure how to solve it
Public Function CreateStoredProcCommand(ByVal cmdtext As String) As OracleCommand
Dim Cmd As New OracleCommand ' command object ...
' create command ...
With Cmd
.Connection = Conn
.CommandText = cmdtext
.CommandType = CommandType.StoredProcedure
End With
Return Cmd
End Function
I updated the code above to look like this
With cmd
.Parameters.Add(New OracleParameter(parameterName:="EMPLOYEE", type:=OracleClient.OracleType.VarChar, size:=8)).Value = strEmpId
.Parameters.Add(New OracleParameter(parameterName:="ROWCOUNT", oraType:=OracleClient.OracleType.Number)).Direction = ParameterDirection.Output
End With
new Error message at runtime is
{"Specified argument was out of the range of valid values."}
What is out of range? How do I check the value?
Old Code
With cmd
' CRASHING ON NEXT LINE. I CHANGED THE ORDER AND MADE IT ALL CAPS.
.Parameters.Add(name:="EMPLOYEE", dbType:=OracleClient.OracleType.VarChar, size:=8).Value = strEmpId
.Parameters.Add(name:="ROWCOUNT", dbType:=OracleClient.OracleType.Number).Direction = ParameterDirection.Output
End With
New Code
Dim oracleParameter(1) As OracleParameter
oracleParameter(0) = New OracleParameter()
oracleParameter(1) = New OracleParameter()
oracleParameter(0) = cmd.Parameters.Add("EMPLOYEE", dbType:=Oracle.DataAccess.Client.OracleDbType.Varchar2, size:=8, val:=strEmpId, ParameterDirection.Input)
oracleParameter(1) = cmd.Parameters.Add("ROWCOUNT", dbType:=Oracle.DataAccess.Client.OracleDbType.Int16, val:=strEmpId, ParameterDirection.Output)
The actual cause was using the Microsoft Implementation of Oracle Type vs Oracle Type
I have this code:
comkonsultasi = New OleDbCommand("select count(idkonsultasi) from dkonsultasi where idgejala='" & idgejala & "'", conn)
drkonsultasi = comkonsultasi.ExecuteReader
jgejala = drkonsultasi.Item(0)
When it runs, I get this exception message on the last line:
InvalidOperationException was unhandled. No data exists for the row/column.
Can anyone can help to resolve this problem?
You have to Read() from the DataReader. It's also very bad to use string concatenation to put data into an SQL query like that. You must use query parameters instead:
Dim sql As String = "select count(idkonsultasi) from dkonsultasi where idgejala= ?"
Using conn As New OleDbConnection("connection string here"), _
comkonsultasi As New OleDbCommand(sql, conn)
'Use the actual type and length from the database for this line
comkonsultasi.Parameters.Add("idgejala", OleDbType.VarWChar, 50).Value = idgejala
conn.Open()
Using drkonsultasi As OleDbDataReader = comkonsultasi.ExecuteReader()
If drkonsultasi.Read() Then
jgejala = drkonsultasi.Item(0)
End Using
End Using
End Using
I really need help this time. I search everywhere, tried numerous solutions. but i can't seem to solve my problem. Now i'm going to ask, please help. I have been having this problem for a week now.
ExecuteSQL("select * from account_database where idnum= #idnum and password= #pass")
'Dim idnum As New SqlParameter("#idnum", SqlDbType.VarChar)
'Dim pass As New SqlParameter("#pass", SqlDbType.VarChar, -1)
'idnum.Value = idnumtxt.Text
'pass.Value = output
'cmd.Parameters.Add(idnum)
'cmd.Parameters.Add(pass)
cmd.Parameters.Add("#idnum", SqlDbType.VarChar).Value = idnumtxt.Text
cmd.Parameters.Add("#pass", SqlDbType.VarChar, -1, "password").Value = output
those commented out lines are the codes which i have tried, also there are codes which i implemented that also failed.
The error message concludes as "Must declare scalar variable #idnum"
i really need help please. Please shine some light.
This is the code what the function executeSQL contains :
Public Shared Sub ExecuteSQL(ByVal strSQL As String)
Try
If connection.State = 1 Then ' check connection if open
connection.Close()
End If
' connection
connection.ConnectionString = "Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Jr\documents\visual studio 2010\Projects\VotingSystem\VotingSystem\Resources\Database.mdf;Integrated Security=True;User Instance=True"
connection.Open()
Dim rowAffected As Integer = 0
'cmd = New SqlCommand(strSQL, connection) 'buiding the sql command with the use of strSQL (sql statement) and connection (database connection)
cmd = New SqlCommand(strSQL, connection)
DARec = New SqlDataAdapter(strSQL, connection) 'buiding the adapter
cb = New SqlCommandBuilder(DARec)
rowAffected = cmd.ExecuteNonQuery() 'executing of sql statement
successID = 1
connection.Close()
Catch ex As Exception
successID = 0
MsgBox(ex.Message)
End Try
End Sub
Thanks and please help.
Problem is simply you're doing this in the wrong order. You're attempting to execute your SQL statement before defining the parameters. You don't need ExecuteSQL() until you've defined your parameters. It likely breaks on the following line in ExecuteSQL()
' See how many rows the query will impact
' Since #idnum and #pass are not defined until the
' ExecuteSQL() sub is finished, this line breaks.
rowAffected = cmd.ExecuteNonQuery()
You need to build your SqlCommand() to first include the select statement, and then use AddWithValue() on the parameters you've defined in the string. Defining the datatypes is also unnecessary because your database already knows, and form validation should handle input.
' Define your connection
connection.ConnectionString = "Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Jr\documents\visual studio 2010\Projects\VotingSystem\VotingSystem\Resources\Database.mdf;Integrated Security=True;User Instance=True"
' Setup your SQL Command.
cmd = New SqlCommand("select * from account_database where idnum = #idnum and password = #pass", connection)
' Define the parameters you've created
cmd.Parameters.AddWithValue("#idnum", idnumtxt.Text)
cmd.Parameters.AddWithValue("#pass", output)
' Now execute your statement
connection.open()
cmd.ExecuteNonQuery()
connection.close()
And here is a better version of the above code, since you understand the order of events now. This ensures that in the event of exception the connection is closed.
strConn = "Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Jr\documents\visual studio 2010\Projects\VotingSystem\VotingSystem\Resources\Database.mdf;Integrated Security=True;User Instance=True"
strSQL = "select * from account_database where idnum = #idnum and password = #pass"
Using connection As New SqlConnection(strConn), cmd As SqlCommand(strSQL, connection)
cmd.Parameters.Add("#idnum", SqlDbType.VarChar).Value = idnumtxt.Text
cmd.Parameters.Add("#pass", SqlDbType.VarChar, -1, "password").Value = output
connection.Open()
cmd.ExecuteNonQuery()
End Using
Try this:
cmd.Parameters.AddWithValue("idnum", idnumtxt.Text)
Reference:
SqlParameterCollection.AddWithValue # MSDN.
It should just be a case of the following to add an input param
cmd.Parameters.Add("#idnum", idnumtxt.Text)
Except you'll need cmd.parameters.add() before the executesql as you're currently defining your params after executesql has ran.
I am trying to figure out why I am getting an error of 'Object reference not set to an instance of an object.' when my winforms code runs. I have set a breakpoint on the sql statement and stepped into the code and it shows as the line: Using dr = oledbCmd.ExecuteReader()
I am still learning vb.Net so would appreciate some help as to how to overcome this error. Many thanks
DBConnection.connect()
sql = "SELECT * from Boxes WHERE Customer = ? AND Status = 'I'"
Dim cmd As New OleDb.OleDbCommand
cmd.Parameters.AddWithValue("#p1", cmbCustomer.Text)
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
Using dr = oledbCmd.ExecuteReader()
While dr.Read()
Dim LV As New ListViewItem
With LV
.UseItemStyleForSubItems = False
.Text = dr(1).ToString()
.SubItems.Add(dr(2).ToString())
End With
lvSelectRequestItems.Items.Add(LV)
End While
End Using
cmd.Dispose()
dr.Close()
oledbCnn.Close()
DBConnect module
Imports System.Data.OleDb
Module DBConnection
Public connetionString As String = My.Settings.storageConnectionString
Public oledbCnn As New OleDbConnection
Public oledbCmd As OleDbCommand
Public dr As OleDbDataReader
Public sql As String
Sub connect()
'connetionString = My.Settings.storageConnectionString
oledbCnn.ConnectionString = connetionString
oledbCnn.Open()
End Sub
End Module
I saw several mistakes. Look to the comments for reasons for the changes
Dim sql As String = "SELECT * from Boxes WHERE Customer = ? AND Status = 'I'"
'.Net uses connection pooling, such that you're better using a new connection object for each query
'Also, a Using block will ensure the connection is closed, **even if an exception is thrown**
' The original code would leak connections when exceptions occured, eventually locking you out of the db
Using cn As New OleDb.OleDbConnection("Connection string here"), _
cmd As New OleDb.OleDbCommand(sql, cn) 'set CommandText BEFORE adding parameters
'Use explicit parameter types
cmd.Parameters.Add("?", SqlDbType.NVarChar, 50).Value = cmbCustomer.Text
cn.Open()
Using dr As OleDb.OleDbDataReader = cmd.ExecuteReader()
While dr.Read()
Dim LV As New ListViewItem
With LV
.UseItemStyleForSubItems = False
.Text = dr(1).ToString()
.SubItems.Add(dr(2).ToString())
End With
lvSelectRequestItems.Items.Add(LV)
End While
dr.Close()
End Using
End Using
You have failed to properly bind the SqlConnection to the SqlCommand object.
Using connection As New SqlConnection(connectionString)
connection.Open()
Dim command As New SqlCommand(queryString, connection)
Dim reader As SqlDataReader = command.ExecuteReader()
While reader.Read()
Console.WriteLine("{0}", reader(0))
End While
End Using
See: MSDN
Edit: Requested adjustment to aid in clarity:
Using connection As New Data.SqlClient.SqlConnection
Dim sql As String = "SELECT * from Boxes WHERE Customer = ? AND Status = 'I'"
connection.Open()
Using command As New Data.SqlClient.SqlCommand(Sql, connection)
command.Parameters.AddWithValue("#p1", cmbCustomer.Text)
dr = command.ExecuteReader()
While dr.Read()
Dim LV As New ListViewItem
With LV
.UseItemStyleForSubItems = False
MediaTypeNames.Text = dr(1).ToString()
.SubItems.Add(dr(2).ToString())
End With
lvSelectRequestItems.Items.Add(LV)
End While
End Using
End Using
Your code should look something like that.
you have a fair amount of potential issues going on here.
1-you are using your dr variable twice. once before the using, which is probably causing your error. then again in for using, which does not look right because it is not the cmd variable used to execute the reader. so change this part of your code:
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
Using dr = oledbCmd.ExecuteReader()
to this:
cmd.CommandText = sql
cmd.Connection = oledbCnn
Using dr = cmd.ExecuteReader()
2-you are not showing if oledbCnn has been opened yet. I'm assuming your DBConnection.connect() function is doing this and olebCnn is a variable that function sets and opens
3-I'm not sure if the question mark in your query string will work. Even if it does you should replace it with the parameter name. so your query string should be:
sql = "SELECT * from Boxes WHERE Customer = #p1 AND Status = 'I'"
lastly you should probably show all the code for the sub(or function) this is for so we can get a full picture. example dr must be declared before the using else you would get a build error.