SSIS execute sql task returncode from SP - sql-server

I am trying to get a returncode from my SP and then based on its value (0 or 1) it will go to next task.
Create Procedure sp_test
AS
DECLARE #cmdline VARCHAR(500),
#ReturnCode INT
SELECT #cmdline = 'dir z:'
CREATE TABLE #temp (SomeCol VARCHAR(500))
INSERT #temp
EXEC #ReturnCode = master.dbo.xp_cmdshell #cmdline
IF #ReturnCode <> 0
BEGIN
SELECT SomeCol
FROM #temp
WHERE SomeCol IS NOT NULL
END
DROP TABLE #temp
RETURN #ReturnCode
GO
Now inside my Execute SQL task of SSIS, Here is what I type and specify ResultSet = Single Row
DECLARE #return_value int
EXEC #return_value = [dbo].[sp_test]
SELECT 'ReturnValue' = #return_value
Here is the error I am getting,
[Execute SQL Task] Error: An error occurred while assigning a value to variable "Variable": "Unable to find column ReturnValue in the result set.".
I need that ReturnCode Value so that I can use it for my next task.

Assuming OLE DB provider, the Result Name should be 0 as it's the zeroeth element of the result set. Also, ensure your Result Set type on the General tab is ... Single Row or whatever the label is.
Also, no need for a Parameter Mapping as your stored procedure does not accept parameters (input or output)

You have to try below logic...
Put the below code into SQL Statement .
DECLARE #return_value int
SET #return_value=?
EXEC ? = [dbo].[sp_test]
SELECT 'ReturnValue' = ?
And set the result set as in snapshot..

Related

SSIS OLE DB SQL COMMAND - Getting return value from nested stored procedure

In SSIS I have an OLE DB SQL Command in my Dataflow that executes a stored procedure which in turn executes a 'nested' stored procedure (uspMyNestedSP). I can't seem to get the RETURN from the nested stored procedure. All SSIS returns is the int #RETURN_VALUE and not the string returned in the stored procedure.
Note, I cannot change uspMyNestedSP.
I have tried using OUTPUT parameters and setting the RETURN to this but all I get back is an empty string.
I need to do it in a OLE DB SQL Command on a row by row basis.
The only other way I can think of is to split the Data flow into two Data Flows and have a SQL TASK do it in between?
Here is the stored procedure:
ALTER PROCEDURE [dbo].[uspMyMainSP]
#_EthnicityIOCode NCHAR(20),
#_EthnicityDescription NVARCHAR(60)
AS
DECLARE #EthnicityCode NCHAR(8)
DECLARE #EthnicityDescription NVARCHAR(60)
DECLARE #AuditMessage NVARCHAR(128)
SET NOCOUNT ON;
IF LEN(TRIM(#_EthnicityIOCode)) > 0 AND LEN(TRIM(#_EthnicityDescription)) > 0
BEGIN
SELECT
#EthnicityCode = ethEthnicityCode,
#EthnicityDescription = ethDescription
FROM
TC36sp1.dbo.Ethnicity
WHERE
(ethIOCode = #_EthnicityIOCode)
IF ##ROWCOUNT = 0
BEGIN
-- Insert
EXEC uspMyNestedSP '*df', #_EthnicityDescription, #_EthnicityIOCode, 1
SET #AuditMessage = ''''
END
ELSE
IF #_EthnicityDescription <> #EthnicityDescription
BEGIN
-- Update
EXEC uspMyNestedSP '*df', #_EthnicityDescription, #_EthnicityIOCode, 1
SET #AuditMessage = ''''
END
-- This is what I want to return back to SSIS!...
RETURN #EthnicityCode
END
The #EthnicityCode string is what I want to return. This works fine and returns when run manually in SSMS.
Here is my SQL Command in SSIS:
EXEC ? =uspMyMainSP ?, ?
Here's how to do it with script component:
string sql = "dbo.uspMyNestedSP";
using (OleDbConnection conn = new OleDbConnection(cstr))
{
using (OleDbCommand cmd = new OleDbCommand(sql, conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#p1", Row.[ColumnName]);
cmd.Parameters.AddWithValue("#p2", Row.ColumnName);
conn.Open();
string EthnicityCode = cmd.ExecuteScalar();
}
}
The RETURN can only return int so it cannot be used to return a string value. Spec:
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/return-transact-sql?view=sql-server-ver15
Try this in SSMS and you'see you'll get this error message:
Conversion failed when converting the nvarchar value 'test ' to data type int.
ALTER PROCEDURE [dbo].[uspMyMainSP]
AS
BEGIN
DECLARE #EthnicityCode NCHAR(8) = 'test'
RETURN #EthnicityCode
END
GO
EXEC [dbo].[uspMyMainSP]
Instead of that you can return SELECT #EthnicityCode as EthnicityCode as a single record result set and process it down in the data flow.
Or use an OUTPUT parameter with a little trick: To be able to use OUTPUT parameter, you need to map it to an INPUT parameter, thus you need a dummy input parameter. Define a dummy string parameter (Derived Column Name, set it as NULL(DT_STR))
See here for a more detailed explanation
https://radacad.com/output-parameter-of-stored-procedure-in-ole-db-command-ssis
ALTER PROCEDURE [dbo].[uspMyMainSP]
#_EthnicityIOCode NCHAR(20),
#_EthnicityDescription NVARCHAR(60),
#EthnicityCode NCHAR(8) OUTPUT ----added
AS
-- DECLARE #EthnicityCode NCHAR(8) ---removed
....
EXEC [dbo].[uspMyMainSP] ?, ?, ? output

SQL Server stored procedure evaluating JSON_VALUE out of execution order

In the below procedure, I am trying to return a value based on an input that is in JSON format. To protect against an invalid JSON input, I am using the ISJSON() function. However, SQL Server appears to be evaluating JSON_VALUE() in the 2nd statement prior to the ISJSON() validation check in the 1st statement.
CREATE TABLE dbo.Table1(
ColKey integer NOT NULL,
ColText nvarchar(255) NOT NULL,
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED ([ColKey] ASC));
GO
INSERT INTO dbo.Table1(ColKey, ColText)
VALUES (1, 'Test String');
GO
CREATE PROCEDURE [dbo].[usp_GetTextFromJSON]
#JSON nvarchar(255),
#TextOut nvarchar(255) OUTPUT
AS
BEGIN
IF ISJSON(#JSON) <> 1
THROW 50000, 'Invalid JSON', 1; -- Alternatively: RETURN -1;
SELECT TOP 1 #TextOut = ColText
FROM dbo.Table1
WHERE ColKey = JSON_VALUE(#JSON, N'$.Col1Key')
RETURN 0;
END;
GO
Executing the procedure with an invalid JSON string does not trigger the expected exception.
DECLARE #return_value int,
#TextOut nvarchar(255);
EXEC #return_value = [dbo].[usp_GetTextFromJSON]
#JSON = N'{Col1Key:1}', -- Invalid JSON: ISJSON(N'{Col1Key:1}') = 0
#TextOut = #TextOut OUTPUT;
SELECT #TextOut;
returns:
Msg 13609, Level 16, State 1, Procedure dbo.usp_GetTextFromJSON, Line 10 [Batch Start Line 29]
JSON text is not properly formatted. Unexpected character 'C' is found at position 1.
Changing the execution code to the following returns successfully.
DECLARE #return_value int,
#TextOut nvarchar(255);
EXEC #return_value = [dbo].[usp_GetTextFromJSON]
#JSON = N'{"Col1Key":1}', -- Valid JSON
#TextOut = #TextOut OUTPUT;
SELECT #TextOut;
Why is SQL Server evaluating JSON_VALUE() in the 2nd statement before evaluating ISJSON in the 1st statement?
It''s a compilation issue not an execution issue. When you run the good one first the plan is generated and cached and the bad one then works as you want.
Probably it tries to evaluate JSON_VALUE(#JSON, N'$.Col1Key') against the initial parameter value so it can then use the histogram on ColKey to get row estimates.
You can try assigning the parameter to a local variable to avoid this.
CREATE PROCEDURE [dbo].[usp_GetTextFromJSON] #JSON NVARCHAR(255),
#TextOut NVARCHAR(255) OUTPUT
AS
BEGIN
DECLARE #vJSON NVARCHAR(255) = #JSON;
IF ISJSON(#vJSON) <> 1
THROW 50000, 'Invalid JSON', 1; -- Alternatively: RETURN -1;
SELECT TOP 1 #TextOut = ColText
FROM dbo.Table1
WHERE ColKey = JSON_VALUE(#vJSON, N'$.Col1Key')
RETURN 0;
END;

SQL Server: stored proc tries to convert varchar OUTPUT into int #Return_Value

I have this stored procedure:
create proc Sponsors.GetLightBoxAd
(
#SponsorID varchar(30),
#ADIDOut varchar(30) OUTPUT,
#UserID varchar(30),
#ProjectID varchar(50),
#PlatformID int
)
as
begin
SELECT TOP 1 #ADIDOut = AD.ADID --my output. AD.ADID is a varchar(30) column
FROM Sponsors.AD
WHERE AD.Active = 1 and AD.SponsorID = #SponsorID
ORDER by NEWID() -- I want the first one picked at random
IF ISNULL(#ADIDOut,-1) != -1 --if the result set wasn't null, run some update queries with the result
BEGIN --These queries do not have output variables.
EXEC Sponsors.proc1 #ADIDOut, #SponsorID
EXEC Projects.proc2 #ProjectID,#ADIDOut,#UserID,#PlatformID
END --end the if
end --end the proc
go
This should return either a null value or a varchar.
However when I try to execute the query, SSMS auto-generates this code for me to run the query:
USE [MyDB]
GO
DECLARE #return_value int, --Why is this here???
#ADIDOut varchar(30) -- this should be my only output
EXEC #return_value = [Sponsors].[GetLightBoxAd]
#SponsorID = N'Alienware',
#ADIDOut = #ADIDOut OUTPUT,
#UserID = N'127.0.0.1',
#ProjectID = N'TestProject',
#PlatformID = 1
SELECT #ADIDOut as N'#ADIDOut'
SELECT 'Return Value' = #return_value --why is this here?
GO
And then it gives me an error because it appears to try to convert the result of ADIDOut into an int... Why is there an int #Return_Value variable and why is it trying to put my actual OUTPUT result into it?
The error was in this line:
IF ISNULL(#ADIDOut,-1) != -1
It seems since I put just -1 without quotes as the comparison, sql reads this as an integer and cannot compare it to a nullable string so the error is raised. Putting the -1's into quotes fixes the error and the query runs. Thanks for the help!

Procedure or function 'sp_InsertImages' expects parameter '#Img_path', which was not supplied

i have passed img_path in my code nd procedure but it show me error please anyone help me.
my procedure is :
create proc sp_InsertImages
(
#Img_path nvarchar(max),
#product_id numeric(18,0),
#IsCover_Img bit
)
as
begin
if(select COUNT(*) from tbl_productImg where product_id=#product_id)<5
begin
insert into tbl_productImg(Img_path,product_id,IsCover_Img)values(#Img_path,#product_id,#IsCover_Img)
select ##IDENTITY
end
else
begin
select -1
end
end
Your Command Type must be set to StoredProcedure like this
cmd.CommandType = CommandType.StoredProcedure;
To get the Product ID from the Procedure, call ExecuteScalar() instead of ExecuteNonQuery() like below
product_ID = Convert.ToDouble(sql.ExecuteScalar());

Microsoft sql stored procedure not executing select statement properly

I'm pretty new to Microsoft T-sql (Use to Oracle PL/SQL) and I ran into a annoying problem with a very simple procedure.
I created the following procedure
CREATE PROCEDURE [dbo].[ele_test] #productId INT
AS
DECLARE #productCode VARCHAR(100);
DECLARE #productDescription VARCHAR(100);
DECLARE #error VARCHAR(100);
--Fetch product
IF #productId != NULL
BEGIN
SELECT #productCode = ProductCode
,#productDescription = ProductDescription
FROM d_afterpay.dbo.Product
WHERE ProductId = #productId
END
IF ##ROWCOUNT = 0
BEGIN
SET #error = 'Product not found: ' + cast(#productId AS VARCHAR(19))
RAISERROR (#error,16,1);
END
And when I run it this way:
exec ele_test 5
I get:
Msg 50000, Level 16, State 1, Procedure ele_test, Line 20
Product not found. Productid : 5
Yet when I run just the query like this:
SELECT * FROM d_afterpay.dbo.Product
WHERE ProductId = 5
I do get a proper result...
Any idea what I am doing wrong?
Your query syntax is slightly wrong, change the query to read:
IF (#productId IS NOT NULL)
instead of using !=
This meant your SELECT statement was never being called hence why the product was always missing.

Resources