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
Related
I am experiencing the problem on subject with the following code and cannot figure out what's wrong with it:
Stored procedure:
CREATE PROCEDURE [dbo].[spAddRateTypeRoomTypeCombination]
(
#RatePlanName NVARCHAR(50),
#OpenFrom DATE,
#OpenTo DATE,
#Active BIT,
#RoomTypeId INT)
AS
DECLARE #Result INT
BEGIN TRANSACTION
IF EXISTS (SELECT NULL FROM dbo.RateType WITH (UPDLOCK)
WHERE RatePlanName = #RatePlanName)
BEGIN
SELECT #Result = -1
END
ELSE
BEGIN
INSERT INTO dbo.RateType (RatePlanName, OpenFrom, OpenTo, Active)
VALUES (#RatePlanName, #OpenFrom, #OpenTo, #Active)
/****** return the last identity value inserted into an identity column ******/
DECLARE #RateTypeid INT
SET #RateTypeId = SCOPE_IDENTITY()
INSERT INTO dbo.RateRoomCombination(RateTypeId, RoomTypeId)
VALUES (#RateTypeId, #RoomTypeId)
SELECT #Result = ##ERROR
END
IF #Result <> 0
BEGIN
ROLLBACK
END
ELSE
BEGIN
COMMIT
END
RETURN #Result
GO
This is the function that I wrote in order to insert data into my 2 tables RateType and RateRoomCombination:
Function AddRateType(RatePlanName As String) As Integer
Using con As SqlConnection = New SqlConnection(GetConnectionString())
Dim cmd As New SqlCommand()
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "spAddRateTypeRoomTypeCombination"
cmd.Parameters.Add("#RatePlanName", SqlDbType.NVarChar).Value = TextBoxRateName.Text.Trim()
cmd.Parameters.Add("#Active", SqlDbType.Bit).Value = CheckBox3.Checked
cmd.Parameters.AddWithValue("#OpenFrom", Convert.ToDateTime(Textbox1.Text.Trim()))
cmd.Parameters.AddWithValue("#OpenTo", Convert.ToDateTime(Textbox2.Text.Trim()))
cmd.Parameters.Add(New SqlParameter("#Result", SqlDbType.Int))
cmd.Parameters("#Result").Direction = ParameterDirection.ReturnValue
For Each item As ListItem In chkRoomTypes.Items
cmd.Parameters.Add(New SqlParameter("#RateTypeId", SqlDbType.Int))
cmd.Parameters.Add(New SqlParameter("#RoomTypeId", SqlDbType.Int))
Next
Dim commandResult As Integer = 1
cmd.Connection = con
Try
con.Open()
cmd.ExecuteNonQuery()
commandResult = CType(cmd.Parameters("#Result").Value, Integer)
Catch ex As System.Data.SqlClient.SqlException
commandResult = ex.Number
' Use the following 3 lines to understand better the error
Dim msg As String = "Insert Error:"
msg += ex.Message
Throw New Exception(msg)
Finally
con.Close()
con.Dispose()
End Try
Return commandResult
End Using
End Function
Error I get:
System.Exception: 'Insert Error:Procedure or function spAddRateTypeRoomTypeCombination has too many arguments specified.'
If I execute my stored procedure from SQL with 1 RateTypeId and 1 RoomTypeId, my DB gets updated. If I add more than 1 RoomTypeId (being the case I am trying to perform on my page), SQL throws the same error as per above: too many arguments.
I really cannot figure out what is wrong.
Thanks
Two reasons for your error, and they're both right here:
For Each item As ListItem In chkRoomTypes.Items
cmd.Parameters.Add(New SqlParameter("#RateTypeId", SqlDbType.Int))
cmd.Parameters.Add(New SqlParameter("#RoomTypeId", SqlDbType.Int))
Next
Your stored procedure doesn't even have a #RateTypeId parameter (it has a local variable by that name). So you can't pass a parameter to it in your .net command.
The #RoomTypeId parameter in your stored procedure is of type INT. That means you can only pass ONE int value to it. You can't add multiple #RoomTypeId parameters to the .net command and pass it to this stored procedure. If you want to do that, you should look into making it a Table-Valued Parameter.
How would I create a query that returns a column in the database? The SQL select statement is easy. I'm having issues with the VB side.
SELECT UserNO
FROM UserTable
WHERE UserID = user;
I need to then get that UserNO and pass it to another T-SQL stored procedure. How would I go about running a SELECT query and getting the results back in Visual Basic?
Attached is some of my code. The code below adds the user to the DB however the UserNo (INTEGER) is automatically generated by SQL Server as the INSERT statement is run in the insert stored procedure, so I need to pull the UserNO after the user is created.
Public conwd As SqlConnection = New SqlConnection("Server=*****;Database=*****;User Id=****;Password=****")
Public conwp As SqlConnection = New SqlConnection("Server=*****;Database=*****;User Id=****;Password=****")
Dim cmdP As SqlCommand = New SqlCommand("EXECUTE [dbo].[AddNewUserWestonTemp] '" + user + "'", conwp)
Dim cmdD As SqlCommand = New SqlCommand("EXECUTE [dbo].[AddNewUserWestonTemp] '" + user + "'", conwd)
conmp.Open()
conmd.Open()
cmdP.ExecuteNonQuery()
cmdD.ExecuteNonQuery()
The Using..End Using blocks close and dispose of your data objects that might contain unmanaged code. The Parameters help prevent SQL injection.
Private Sub OPCode2()
Dim newID As Integer
Dim sql = "Insert Into UserTable (User) Values (#User); Select SCOPE_IDENTITY();"
Using cn As New SqlConnection("Your Connection String")
Using cmd As New SqlCommand(sql, cn)
cmd.Parameters.Add("#User", SqlDbType.NVarChar).Value = "Brian Weaver"
cn.Open()
newID = CInt(cmd.ExecuteScalar)
End Using
End Using
'Use the newID in your next command
UserStoredProcedure(newID)
End Sub
Private Sub UseStoredProcedure(id As Integer)
Dim sql = "InsertSomeUserInfo" 'the name of your stored procedure
Using cn As New SqlConnection("Your Connection String")
Using cmd As New SqlCommand(sql, cn)
cmd.CommandType = CommandType.StoredProcedure
'whatever parameter names and types your stored procedure uses
cmd.Parameters.Add("#UserID", SqlDbType.Int).Value = id
cmd.Parameters.Add("#Salary", SqlDbType.Decimal).Value = 50000
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End Sub
Dim cmdP As SqlCommand = New SqlCommand("EXECUTE [dbo].[AddNewUserWestonTemp] '" + user + "'" + "; SELECT CAST(scope_identity() AS int", conwp)
Dim userNo as Integer = cmdP.ExecuteScalar()
ExecuteScalar retrieves the first line of the result
I have a stored procedure in SQL Server that returns two values. When called from QA with the following SQL code:
exec TWEEPush_ValidateCO #CoFilter='CO IN(''1502'',''Mike'',''Clarkson'')', #TDate='09/18/`2017'
it works as expected by returning two values:
#TempCOID #TempDate
1502 09/10/2017
The stored procedure does some work and ends with the two values being set to non null values, with the stored procedure ending with:
SELECT
#TempCOID AS N'#TempCOID',
#TempDate AS N'#TempDate'
In VB.net (Visual Basic, not C), I've tried many different approaches to get the results but have had no luck. Either I get an error saying the named param doesn't exist, or it ends up returning empty values (everything is coded to prevent Nulls in the return data)
Dim sConnectStr As String = GetSQLConnectionString()
Try
Using Connection As New SqlConnection(sConnectStr)
Connection.Open()
Dim Command As New SqlCommand("dbo.TWEEPush_ValidateCO", Connection)
Command.CommandType = CommandType.StoredProcedure
Command.Parameters.AddWithValue("#CoFilter", Filter)
Command.Parameters.AddWithValue("#TDate", Now())
Dim PramCOIDRet As New SqlParameter
PramCOIDRet.ParameterName = "#TempCOID"
PramCOIDRet.SqlDbType = SqlDbType.NVarChar
PramCOIDRet.Size = 30
PramCOIDRet.Direction = ParameterDirection.Output
Dim PramDateRet As New SqlParameter
PramDateRet.ParameterName = "#TempDate"
PramDateRet.SqlDbType = SqlDbType.NVarChar
PramDateRet.Size = 30
PramDateRet.Direction = ParameterDirection.Output
Command.Parameters.Add(PramCOIDRet)
Command.Parameters.Add(PramDateRet)
Command.ExecuteNonQuery()
Dim COID as string = Command.Parameters("#TempCOID").Value
Dim CoDate as Date = CDate(Command.Parameters("#TempDate").Value)
End Using
Catch ex As Exception
End Try
No matter what code I've tried, the code never returns the data as expected.
What am I doing wrong? Can someone please shed some light on this please?
You didn't show us your stored procedure code - but most likely, it's something like this:
CREATE PROCEDURE dbo.dbo.TWEEPush_ValidateCO
#CoFilter VARCHAR(100), -- just guessing here!
#TDate DATE -- again - just guessing
AS
BEGIN
DECLARE #TempCOID INT;
DECLARE #TempDate DATE;
-- do some calculations here that define #TempCOID and #TempDate
-- this is just for demo purposes - I'm sure your calculation is a bit
-- more complex and involved...
SET #TempCOID = 1502;
SET #TempDate = '20170910';
-- return the values in a SELECT statement
SELECT
#TempCOID AS N'#TempCOID',
#TempDate AS N'#TempDate'
END
In this case, you're returning a RESULT SET - not two parameters!
You need to get your values like this:
static void Main(string[] args)
{
string connectionString = ConfigurationManager.ConnectionStrings["YourConnectionString"].ConnectionString;
int tempCoid;
DateTime tempDate;
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand("dbo.dbo.TWEEPush_ValidateCO", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#CoFilter", Filter);
cmd.Parameters.AddWithValue("#TDate", DateTime.Now);
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
tempCoid = rdr.GetFieldValue<int>(0);
tempDate = rdr.GetFieldValue<DateTime>(1);
}
}
conn.Close();
}
}
(I'm sure you get the idea - and you can easily translate this into VB.NET, too).
Hope that helps!
Marc
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.
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 ?