vb.net Procedure or function expects parameter, which was not supplied - sql-server

I am receiving this error:
Procedure or function 'usp__SingleSelectServerRackName' expects parameter '#chvServerName', which was not supplied.
I looked up the error and did not find any applicable solutions.
I was successfully able to run the Proc and retrieve out put information, and was able to successfully retrieve value of cbserver.valuemember in command window.
Any suggestions to correct this problem?
Here is my code:
Imports System.Data.SqlClient
Try
Dim connString As String = "server=ServerName;database=DatabaseName;trusted_connection=yes"
Using connection As New SqlConnection(connString)
'Create the command and set its properties.
Dim SingleSelectServerRackName As SqlCommand = New SqlCommand
SingleSelectServerRackName.Connection = connection
SingleSelectServerRackName.CommandText = "usp__SingleSelectServerRackName"
SingleSelectServerRackName.CommandType = CommandType.StoredProcedure
'Add the input parameter and set its properties
Dim ParamSingleSelectServerName As New SqlParameter()
ParamSingleSelectServerName.ParameterName = "#chvServerName"
ParamSingleSelectServerName.SqlDbType = SqlDbType.VarChar
ParamSingleSelectServerName.Direction = ParameterDirection.Input
ParamSingleSelectServerName.Value = cbServer.SelectedValue.ToString()
Dim ParamSingleSelectServerRackName As New SqlParameter
ParamSingleSelectServerName.ParameterName = "#numServerRackName"
ParamSingleSelectServerRackName.SqlDbType = SqlDbType.VarChar
ParamSingleSelectServerRackName.Direction = ParameterDirection.Output
ParamSingleSelectServerRackName.Size = 50
'Add the parameters to the Parameters collection
SingleSelectServerRackName.Parameters.Add(ParamSingleSelectServerName)
SingleSelectServerRackName.Parameters.Add(ParamSingleSelectServerRackName)
'Open database connection
connection.Open()
'Execute data reader
Dim readerSingleSelectServerRackName As SqlDataReader = SingleSelectServerRackName.ExecuteReader()
readerSingleSelectServerRackName.Close()
cbRackName.ValueMember = SingleSelectServerRackName.Parameters("#numServerRackName").Value.ToString
'Close database connection
connection.Close()
End Using
Catch ex As Exception
MsgBox(ex.Message)
MsgBox(ex.StackTrace)
End Try
Proc:
CREATE Procedure usp__SingleSelectServerRackName
(
#chvServerName AS varchar(50), ---Input variable #chvServerName displays
#numServerRackName AS varchar(50) OUTPUT ---Output variable #numServerRackName
)
AS Begin
IF #chvServerName is null or len(ltrim(#chvServerName)) = 0 ---Check for null value
RAISERROR('Servername cannot be blank.',16,1)
SELECT Rcknm.nm
FROM Rcknm
INNER JOIN Srvr
on srvr.fk_rcknm = Rcknm.ID
WHERE srvr.nm = #chvServerName
End

Looks like you missed something on your copy/paste of parameters.
ParamSingleSelectServerName.ParameterName = "#numServerRackName"
ParamSingleSelectServerName.ParameterName = "#chvServerName"
Your second parameter is overwriting your first. Try this instead.
ParamSingleSelectServerRackName.ParameterName = "#numServerRackName"

Name of the 2nd parameter is same so overwriting it

Look at these two lines
Dim ParamSingleSelectServerRackName As New SqlParameter
ParamSingleSelectServerName.ParameterName = "#numServerRackName"
You are declaring the second parameter, but then you set the name intended for the second parameter to the first parameter.
That's the missing parameter, you have no more a parameter called #chvServerName
You are really making your life difficult. Why not just calling the twos #Rack and #Server ?

Related

How to fix "Multiple-stop OLE DB operation..." errors when using ADO Command to run stored procedure in SQL Server

I'm trying to run a SQL Server stored procedure that returns records using an ADO Command object. I'm able to connect to the database (my connection is used elsewhere in my code and, when tested in the following function, the state property returns 1 -- connected) but get the following error at the point where the command is executed.
Run-time error '-2147217887 (80040e21)':
Multiple-stop OLE DB operation generated errors. Check each OLD DB status value, if available. No work was done.
From what I've read online, it may be something to do with the parameter, but I can't see anything wrong with it (I've added a watch and inspected each item in the params collection in debug mode).
Here's the function that is intended to return the stored procedure results in an ADODB Recordset:
Public Function GetRecordset(CmdType As String, CmdText As String, Optional InputParams As Collection) As ADODB.Recordset
Dim prm As ADODB.Parameter
Select Case CmdType
Case "proc"
If cmd Is Nothing Then
Set cmd = New ADODB.Command
With cmd
Set .ActiveConnection = GetConnection
For Each prm In InputParams
.Parameters.Append prm
Next prm
Select Case CmdType
Case "proc": .CommandType = adCmdStoredProc
Case "sql": .CommandType = adCmdText
End Select
.CommandText = CmdText
Set rs = .Execute
End With
Set GetRecordset = rs
End If
Case "sql"
End Select
End Function
As above, the error occurs on the line:
Set rs = .Execute
The expected input parameter in the stored procedure is of type numeric(6,0). The parameter passed to the function is as follows:
prm.Direction = adParamInput
prm.Name = "#ISOWk"
prm.NumericScale = 6
prm.Precision = 0
prm.Type = adNumeric
prm.Value = 201613
I'm able to execute the stored procedure directly in SSMS so I am confident that it is not the issue here.
Any suggestions welcome.
Thanks
You have your .Precision and .Scale backwards:
prm.NumericScale = 6
prm.Precision = 0
A value with a precision of 0 can store 0 digits. If the data-type is NUMERIC(6, 0) the parameter should be:
prm.NumericScale = 0
prm.Precision = 6
Precision is the number on the left.

ADO.Net Get Inserted Row's ROW ID without designer wizard

I have a generic update function that takes a datatable, select query and uses this to update the database tables.It is working fine. I need to know is there a way to get back the inserted row's ID (identity field) by changing something in the below code.
Public Function UpdateDataTable_GetID(ByVal dt As DataTable, ByVal SQL As String, ByVal connString As String) As Integer
Dim conn As SqlConnection = Nothing
Dim cmd As SqlCommand
Dim adp As SqlDataAdapter = Nothing
Dim cmdBuilder As SqlCommandBuilder = Nothing
Dim UpdatedID As Integer
If SQL.Length <= 0 Then
Return False
End If
conn = New Data.SqlClient.SqlConnection(connString)
cmd = New Data.SqlClient.SqlCommand
cmd.Connection = conn
cmd.CommandText = SQL
cmd.CommandType = CommandType.Text
adp = New Data.SqlClient.SqlDataAdapter(cmd)
cmdBuilder = New Data.SqlClient.SqlCommandBuilder(adp)
Try
UpdatedID = Convert.ToInt32(adp.Update(dt)) ' What to do here to get the just inserted ID instead of number of records updated
adp.Dispose()
cmdBuilder.Dispose()
Return UpdatedID
Catch ex As System.Data.SqlClient.SqlException
' Closing connection
Return -1
Finally
End try
End function
I am aware of solutions wherein I can append "select scope_identity()" to the insert Command of data adapter's query using designer as well as editing the adapter's insertcommand text and then doing an ExecuteScalar(). I want to know if the generic adapter.Update() can be tweaked to get the inserted row's ID.
you can subscribe to this event in code like this : (C# I dont know VB)
adp.RowUpdated += adapter_RowUpdated;
and write the event yourself :
void adapter_RowUpdated(object sender, SqlRowUpdatedEventArgs e)
{
if (e.StatementType == StatementType.Insert)
{
object id = e.Command.Parameters["#ID"].Value;
e.Row[_identityFieldName] = id;
}
}
In this example the following has been added to the commandtext first :
SET #ID = SCOPE_IDENTITY()
and a private variable _identityFieldName has been filled.
Maybe this can help you.
EDIT: I noticed you also use an SqlCommandBuilder that makes things easier to add the Scope identity :
SqlCommand inserter = new SqlCommand();
inserter = cmdBuilder.GetInsertCommand(true).Clone();
inserter.CommandText += " SET #ID = SCOPE_IDENTITY()";
SqlParameter param = new SqlParameter();
param.Direction = ParameterDirection.Output;
param.Size = 4;
param.DbType = DbType.Int32;
param.ParameterName = "#ID";
inserter.Parameters.Add(param);
adp.InsertCommand = inserter;

Error in XML Parameter Mapping

I have a stored procedure that returns xml. This result is stored in a variable (of type object) in SSIS. This variable is passed as parameter to another stored procedure in execute sql task. The parameter mapping is done as varchar. I am getting the following error:
[Execute SQL Task] Error: Executing the query "exec uspDeleteLiveRecordAfterArchival ?" failed with the following error: "An error occurred while extracting the result into a variable of type (DBTYPE_STR)".
Note: I am sure there is nothing wrong in the stored procedure as it is working fine when tested alone.
What’s wrong in this parameter mapping and how to correct this?
I searched a lot but I am not seeing any useful answers.
Variable
Package
Parameter Mapping
I couldn't get it work with Execute SQL task so far. Now I am calling the stored procedure from a script task and assigning to a variable, until I get a better solution.
Script Task
Public Sub Main()
Dim tableName As String = Dts.Variables("User::CurrentTable").Value.ToString()
Dim sourceConnection As SqlConnection
Dim destinationConnection As SqlConnection
Try
Dim cmSource As ConnectionManager
cmSource = Dts.Connections("ADOSourceConnection")
sourceConnection = DirectCast(cmSource.AcquireConnection(Dts.Transaction), System.Data.SqlClient.SqlConnection)
Dim cmDestination As ConnectionManager
cmDestination = Dts.Connections("ADOACIConnection")
destinationConnection = DirectCast(cmDestination.AcquireConnection(Dts.Transaction), System.Data.SqlClient.SqlConnection)
Using destinationConnection
Dim cmd As New SqlCommand()
cmd.Connection = destinationConnection
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "uspGetIncompleteMoveFromArchival"
cmd.Parameters.AddWithValue("#TableName", tableName)
Dim result As String = Convert.ToString(cmd.ExecuteScalar())
Dts.Variables("User::IncompleteMoveXML").Value = result
'Release Connection'
cmSource.ReleaseConnection(sourceConnection)
cmDestination.ReleaseConnection(destinationConnection)
'Success'
Dts.TaskResult = Dts.Results.Success
End Using
Catch ex As Exception
Dim exceptionVariable As Microsoft.SqlServer.Dts.Runtime.Variables = Nothing
Dts.VariableDispenser.LockOneForWrite("User::ScriptException", exceptionVariable)
exceptionVariable("User::ScriptException").Value = ex.Message
exceptionVariable.Unlock()
Dts.Events.FireError(-1, "Task Name", ex.Message, String.Empty, 0)
Dts.TaskResult = Dts.Results.Failure
End Try
End Sub
Stored Procedure Psuedo Code
DECLARE #Result XML
SELECT #Result =
(
SELECT
'SKULocationsSnapShot' AS '#tableName',
(
SELECT CONVERT(VARCHAR(20), SnapShotID) AS SnapShotID,
CONVERT(VARCHAR(20), LocationID) AS LocationID
FROM dbo.SKULocationsSnapShot CurrentTable (NOLOCK)
WHERE IsMoveComplete = 'N'
FOR XML PATH('CurrentRow'), TYPE
)
FOR XML PATH('root')
)
SELECT CAST(
#Result
AS VARCHAR(MAX)
) AS IncompleteMoveXML

Return result set from SQL Server stored procedure to vb.net

The following stored procedure works as I want in the Visual Studio designer. The result is a table containing all the race distances for the input #CourseName
ALTER PROCEDURE [dbo].[getCourseDistancesProc]
#CourseName nvarchar(50)
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT
RaceDistances.RaceDistance
FROM
RacingMaster
JOIN
RaceDistances ON RacingMaster.Dist_Of_Race_FK = RaceDistances.PKRaceDistancesId
JOIN
Courses ON RacingMaster.RM_Course_FK = Courses.PKCourseId
WHERE
CourseName = #CourseName
END
I want to call the stored procedure from a vb.net application. What data type do I declare as the output variable so that the full result set is returned to the calling app?
There was obviously more work to be done than I had realized, but just in case anyone else stumbles across this question the solution I finally adapted from elsewhere is:-
Dim myConn As SqlConnection
Dim myCmd As SqlCommand
Dim results As String
Dim ConnectionString As String
' Create the connection string.
ConnectionString = "Data Source=*********;" & _
"Initial Catalog=*******;" & _
"Integrated Security=SSPI;"
myConn = New SqlConnection(ConnectionString)
myConn.Open()
Dim InputName As String
InputName = TextBox1.Text
myCmd = New SqlCommand()
myCmd.CommandText = "getCourseDistancesProc"
myCmd.CommandType = CommandType.StoredProcedure
myCmd.Parameters.AddWithValue("#CourseName", Odbc.OdbcType.NVarChar).Value = InputName
myCmd.Connection = myConn
Dim myReader As SqlDataReader = myCmd.ExecuteReader()
If myReader.HasRows Then
Do While myReader.Read()
Dim var As String
var = myReader.GetString(0)
MsgBox(var)
Loop
Else
MsgBox("No rows found.")
End If
myReader.Close()
Obviously, the above is just to demonstrate that the requested data is indeed coming back from the database. But now I know that it is I can handle it in a more useful way.

Parameter gets lost in query

Ok, I'm stumped here - the following code throws an error
Procedure or function 'importsp_CreateDiallerBatch' expects parameter '#BatchName, which was not supplied`
Code:
Dim cmd As SqlCommand = New SqlCommand()
cmd.CommandText = "importsp_CreateDiallerBatch"
cmd.Connection = cnSQL
cmd.Parameters.AddWithValue("#BatchName", BatchName)
Dim IdParameter As SqlParameter = New SqlParameter()
IdParameter.Direction = ParameterDirection.InputOutput
IdParameter.SqlDbType = SqlDbType.Int
IdParameter.Value = -1
IdParameter.ParameterName = "#BatchID"
cmd.Parameters.Add(IdParameter)
cnSQL.Open()
cmd.ExecuteNonQuery()
When debugging the code, BatchName definitely has a value, and checking the parameters collection of cmd right before executing the query shows 2 params, both named and with values set exactly as expected. I must have written code like this a thousand times - am I missing something here?
Ok appears that I forgot the line cmd.CommandType = CommandType.StoredProcedure. Adding this in made it work.

Resources