vb.net procedure or function expects parameter which was not supplied - vb.net

This seems so simple, but I can't resolve the error
Procedure or function 'test' expects parameter '#id', which was not supplied.
I have tried a dataadapter instead of the reader, tried the {call test (?)} syntax, and several variants on how to add the parameter.
CREATE PROCEDURE [dbo].test (#id int)
AS
BEGIN
select * from tmptable where id=#id
END
Using conn = New OdbcConnection(connstring)
conn.Open()
Dim cmd As OdbcCommand = New OdbcCommand("test", conn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#id", 6)
Dim reader As OdbcDataReader = cmd.ExecuteReader()
reader.Close()
conn.Close()
End Using

Try dropping the # - so AddWithValue("id",6) instead. I usually explicitly create the parameter and add it to the collection, and when I do I drop the # sign from the parameter name.
Also, I'll modify your code to look like how I usually use it and edit it into my post in a few minutes, if dropping the # doesn't work you can try my style, maybe there are some subtle differences.
EDIT: Oops, my bad, I use the explicitly defined parameters with SQLcommands, not ODBC commands! You can try leaving out the #, but I don't have a working example I can share with you, sorry :-(
EDIT 2: OK, I don't have an example, but Microsoft has one that looks a lot more like how I call my stored procedures using SQLCommands, see
http://msdn.microsoft.com/en-us/library/system.data.odbc.odbcparametercollection%28v=vs.90%29.aspx
Basically, I think your code would look like
Using conn = New OdbcConnection(connstring)
conn.Open()
Dim cmd As OdbcCommand = New OdbcCommand("{ call test(?) }", conn)
cmd.CommandType = CommandType.StoredProcedure
' replace this with the following cmd.Parameters.AddWithValue("#id", 6) '
Dim ParamID As New OdbcParameter()
ParamID.DbType = DbType.Int32
ParamID.Value = 6
cmd.Parameters.Add(ParamID)
' end replace '
Dim reader As OdbcDataReader = cmd.ExecuteReader()
reader.Close()
conn.Close()
End Using
And you should also be aware that some ODBC drivers are not good at getting recordsets back from stored procedures. I use SmallTalk to query DB2 through ODBC, and I can get a recordset back from a function, but not from a stored procedure. You may be encountering a similar limitation. What database are you using?

Related

Parameterized SQL Command does not update my column

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.

'No value given for one or more required parameters.' Error, Can't get over it

I'm trying to take a Yes/No value from my database on Access and make it so if the Yes/No is checked on Access it will check it on the form. Although I keep getting
System.Data.OleDb.OleDbException: 'No value given for one or more required parameters.'
On the line Dim rs As OleDbDataReader = SQLCmd.ExecuteReader()
Sorry if it's a really easy and stupid mistake, I'm a college student and googling isn't helping me figure this one out.
cn.Open()
Dim SQLCmd As New OleDbCommand
SQLCmd.Connection = cn
SQLCmd.CommandText = "SELECT *, staffIn FROM Staff WHERE staffName = DarrenSloan"
Dim rs As OleDbDataReader = SQLCmd.ExecuteReader()
While rs.Read
Dim DisplayValue As String = rs("staffIn")
SQLCmd.Parameters.AddWithValue("#inorout", inOrOut.Checked)
SQLCmd.ExecuteNonQuery()
End While
cn.Close()
I know this is an old post but I seem to remember that OleDb does not support named parameters.
Also, pretty sure that DarrenSloan should be surrounded by single quotes, like any string value. And indeed, reusing the SQL command like this is not the way to do it.
The CommandText:
SQLCmd.CommandText = "SELECT *, staffIn FROM Staff WHERE staffName = DarrenSloan"
does not contain any parameter.
Thus, the parameter inorout has no effect:
SQLCmd.Parameters.AddWithValue("#inorout", inOrOut.Checked)
Either use two statements, one SELECT and one UPDATE.
Or use a different mechanism like a databound grid. Maybe you are using a datagridview control to display the data. Then there are different techniques to keep the data in sync. It depends on how you choose to render the data on your form.
Firstly, get rid of the loop. You would only use a loop if you were expecting more than one record. By the looks of it, you are expecting only one record, so no loop.
Secondly, stop calling ExecuteNonQuery. That is for making changes to the database, which you're obviously not trying to do. You obviously know how to get data from the query because you're doing it here:
Dim DisplayValue As String = rs("staffIn")
If you want to get data from another field, do the same thing. You can then use that data in whatever way you like, e.g.
Using connection As New OleDbConnection("connection string here"),
command As New OleDbCommand("SELECT * FROM Staff WHERE staffName = 'DarrenSloan'", connection)
connection.Open()
Using reader = command.ExecuteReader()
If reader.Read() Then
Dim inOrOut = reader.GetBoolean(reader.GetOrdinal("inorout"))
inOrOutCheckBox.Checked = inOrOut
End If
End Using
End Using
Notice that I have wrapped the text literal in the SQL in single-quotes? I would expect that you would normally not want to hard-code a name there, but use input from the user instead, In that case, you would use a parameter, e.g.
Using connection As New OleDbConnection("connection string here"),
command As New OleDbCommand("SELECT * FROM Staff WHERE staffName = #staffName", connection)
command.Parameters.Add("#staffName", OleDbType.VarChar, 50).Value = staffNameTextBox.Text
connection.Open()
Using reader = command.ExecuteReader()
If reader.Read() Then
Dim inOrOut = reader.GetBoolean(reader.GetOrdinal("inorout"))
inOrOutCheckBox.Checked = inOrOut
End If
End Using
End Using

please help retrieving data to put it on label

I want to retrieve the price from table Products to use it as label2 on the orderinfo form.
Dim con As New OleDb.OleDbConnection
Dim com As New OleDb.OleDbCommand
com = New OleDb.OleDbCommand("Select Price FROM Products WHERE ProductName='" & ListBox1.SelectedItem.ToString & "'", con)
con.ConnectionString = "PROVIDER = Microsoft.ACE.OLEDB.12.0; Data Source=Database_AntoninosCafe.accdb"
con.Open()
com.ExecuteNonQuery()
orderInfo.Label2.Text = retrieve data
con.Close()
The correct approach to your simple problem
Dim cmdText = "Select Price FROM Products WHERE ProductName=?"
Using con = New OleDb.OleDbConnection( ... connection string here ...)
Using com = New OleDb.OleDbCommand(cmdText, con)
com.Parameters.AddWithValue("#p1", ListBox1.SelectedItem.ToString)
con.Open()
Using reader = com.ExecuteReader()
if reader.Read() Then
orderInfo.Label2.Text = reader("Price").ToString
End If
End Using
End Using
End Using
The first thing is to use a parameterized query to avoid sql injections and parsin problems, then use the Using statement to encapsulate you disposable object in a block of code that ensures the closing and disposing of these objects.
Finally, to read data from a datatable you use the ExecuteReader command that returns an OleDbDataReader instance. It is this instance that could be used to extract the data from your database
As a side note, I have used, as placeholder for the parameter, a question mark. This is the predefined symbol used by OleDb. But, when adding the parameter value to the collection, I have used a different name (#p1). This is acceptable because OleDb do not use the parameter names to find the corresponding placeholders in the query text like the SqlClient or other providers, but use the position of the placeholder. So, first placeholder replaced by the first parameter and so on.

Cant save or update my SQL Server tables using vb.net

I am a complete beginner to .net and am confused at some basic things. Please help.
First of all the table I create and populate (by right clicking tables in server explorer) disappear once I restart the computer. how do I keep them.
Is there any better place/interface to type SQL queries in vb.net than the command prompt.
In the following code:
Dim cn As SqlConnection = New SqlConnection(strConnection)
cn.Open( )
' Create a data adapter object and set its SELECT command.
Dim strSelect As String = _
"SELECT * FROM Categories"
Dim da As SqlDataAdapter = New SqlDataAdapter(strSelect, cn)
' Load a data set.
Dim ds As DataSet = New DataSet( )
da.Fill(ds, "Categories")
This far the code runs fine but just to gain better understanding, I would like to ask that
while data from SQL Server database was saved into da in accordance to the query, why do we need to save/transfer it in the dataset object ds.
Is there any additional benefit of SqlCommand over SqlDataAdapter besides speed?
Dim autogen As New SqlCommandBuilder(da)
Dim dt As DataTable = ds.Tables("Categories")
' Modify one of the records.
Dim row As DataRow = dt.Select("CategoryName = 'Dairy Products'")(0)
row("Description") = "Milk and stuff"
gives an error when I use it with
da.Update(ds, "Categories")
regarding dt.select not returning any value.
What is the way out?
to answer your questions :
The tables you create with the server explorer are IN MEMORY. Same goes for dataset, they are in-memory representation of your table. As for your 2nd example, the DS you use isnt filled when you try to get the DT. hence why the DT is empty.
If your starting, I would suggest you go look into Linq-to-Sql (http://msdn.microsoft.com/en-us/library/bb425822.aspx) for a more up-to-date way of doing sql in .net ( I think its 4.0 framework)
As for the 2nd point, I'd say normally you should use store procedure for most of your sql commands .. the sqlcommand is use like this
Try
Cmd = New SqlClient.SqlCommand("st_InventoryStatus_Or_AnyStoreProcName_Or_ASqlQuery")
Cmd.CommandTimeout = 300 'not really needed'
Cmd.CommandType = CommandType.StoredProcedure 'you can type CommandType.Text here to use directly your "Select * from Category"'
Cmd.Parameters.Clear() 'just to be sure its empty, its not mandatory'
Cmd.Parameters.Add("#idCategory", SqlDbType.Int).Value = myCategory.Id 'here are the parameters of your store proc, or of your query ("select * from Category where Category.id = #Id")'
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Information)
End Try

External database path as parameter for parametrized query to Access

I'm writing small VB.Net app which should build reports based on data gathered from some external MDB-files (Access 2007). It was planned that this app will use parametrized SQL queries to collect data. One of the parameters for these queries is path to the external MDB-file.
Here goes sample code:
Dim conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source=C:\Temp\Temp.mdb;")
conn.Open()
Dim cmd As New OleDbCommand()
cmd.Connection = conn
cmd.CommandType = CommandType.Text
cmd.CommandText = "SELECT * INTO Trend FROM TI IN '?' WHERE TI.Id=?;"
With cmd.Parameters
.Add("#p1", OleDbType.VarChar).Value = "C:\Temp\Source.mdb"
.Add("#p2", OleDbType.Integer).Value = 5
End With
cmd.ExecuteNonQuery()
conn.Close()
Looks simple but it doesn't works. After launch my app throws following exception - System.Data.OleDb.OleDbException: Disk or network error.
Have spent a whole day to make it work with no success. What have I done wrong?
This is a comment that others have suggested is the answer to the question:
Nothing in an Access/Jet/ACE FROM clause is parameterizable (unless it's inside a subquery, of course).
With Access/Jet/ACE your only choice is to use some other method to write the FROM clause on-the-fly.