SSIS Looping with Return Value from Stored Procedure - sql

I am trying to create a SSIS Package that loops based on the return value of a stored procedure run in the loop. I keep getting a super NOT helpful error of:
"Error: 0xC002F210 at Load Order, Execute SQL Task: Executing the query "EXEC ? = [Load_Focus_OrderNum] ?, 1" failed with the following error:
"Value does not fall within the expected range.".
Possible failure reasons:
Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly.
Task failed: Load Order"
Here is my setup:
The Load Order stored procedure loads a table with 500 orders at a time, then the last order number is returned (I have confirmed it returns correctly).
DECLARE #spOut int
EXEC #spOut = Load_Focus_OrderNum 1, 1
PRINT #spOut
Returns 638 as expected
I then want it to process the next 500 starting at the next order.
I'm calling my stored procedure with:
EXEC ? = sp_LoadOrders ?, 1
Procedure snippet:
ALTER PROCEDURE [dbo].[LoadOrders]
(#PK_ID INT, #OrdType INT)
AS
-- Loads OrderNumTbl table
RETURN (SELECT TOP 1 ID FROM OrderNumTbl ORDER BY ID DESC)
GO
My parameter mapping for it is:
And my expressions for the loop are:
What am I missing? Any help is appreciated!

In the parameter Mapping section, replace the parameter name value with the parameter index >> replace #OrderID with 0 and #T1_ID with 1
References
SSIS: Value does not fall within the expected range
SQL Server Central - SSIS: Value does not Fall Within the Expected Range
Parameters and Return Codes in the Execute SQL Task

Related

Execute SQL Task Error: Executing the query failed with the following error: "Incorrect syntax near ''."

I am working on a SSIS package that rejects already loaded files & load only new files to table.
I used for each loop and exceute SSQL to validate if the files are already loaded. When I evaluate
the expression of Execute SQL Task, it evaluates fine. But When I run the paackage I get the following error.
[Execute SQL Task] Error: Executing the query "DECLARE #FileName VARCHAR(100)
SET #FileName=Custo..." failed with the following error: "Incorrect syntax near ''.".
Possible failure reasons: Problems with the query, "ResultSet" property not set correctly,
parameters not set correctly, or connection not established correctly.
The Expression I used in the Execute SQL task is :
"DECLARE #FileName VARCHAR(100)
SET #FileName="+#[User::FileName]+"'
IF EXISTS (SELECT 1
FROM [dbo].[FileLoadStatus]
WHERE filename =#FileName)
BEGIN
SELECT 1 AS FileExistsFlg
END
ELSE
BEGIN
Select 0 AS FileExistsFlg
END"
screen shot of the execute SQL Task
I really apprecaite if you can tell where the problem is ?
You could simplify your expression a little bit to make clear where the SSIS variable is being used:
"SELECT COUNT(*) AS FileExistsFlg
FROM (
SELECT TOP(1) *
FROM
dbo.FileLoadStatus
WHERE
[filename] = '" + #[User::FileName] + "'
) x;"
On the other hand for the SQL Task you could use a standard parameterized query. Assuming you are using an OLEDB connection, the parameter placeholder is the ? sign. No expression is needed and the equivalent Direct Input for the task is:
SELECT COUNT(*) AS FileExistsFlg
FROM (
SELECT TOP(1) *
FROM
dbo.FileLoadStatus
WHERE
[filename] = ?
) x;
With OLEDB you have to map your variable to the placeholder by position (zero based) so in this case the Parameter Name is the number zero. The other properties depend on your metadata and correspond to the variable you would have declare in SQL...
This is less error prone, clearer and reusable for multiple calls as it generates a Prepared Statement.
If your connection type was ADO.Net, the mapping is name based. So check the documentation for the Parameter names and markers for each connection type.

SQL Server stored procedure: how to return column names/values of type failures in variable?

Ambiguous thread name, I apologize. I am not new to SQL, but I'm new to coding longer stored procedures so I don't deal with variables much outside of passing through maybe a table name or returning row count, etc.
I have a stored procedure that is executing an insert from a staging table to a fact table. There are a couple type casts in the insert.
If the insert fails due to a typecast. Is there any way to return the name of the column that failed, along with what the failed value was? How would I code that? I know that Try_parse would make it so the stored procedure doesn't fail on type cast failure, but I want to be able to pass back exactly what column and value failed.
I show an example here:
Create Procedure dbo.Example_Insert
#updateUser varchar(255)
As
Begin
Insert Into dbo.Energy_Costs (Energy_Cost_Id, Project_Id, Propane_Cost_Dollars,
Electricity_Cost_Dollars, Fuel_Savings_Evaluator)
Select
Next Value For energy_cost_id,
r.project_id,
Cast(r.propane_cost_dollars As Decimal(18,2)),
Cast(r.electricity_cost_dollars As Decimal(18,2)),
#update_user fuel_savings_evaluator
From
staging_table r
return ##ROWCOUNT
end
You can use CURSOR in sql then insert one line at a time. When insert fail return value currently row error.
I hope my idea suitable with you.

SQLRPGLE syntax for Exec sql from a varying length variable?

On IBMi (database is DB2 for i) in SQLRPGLE I have a program that builds a large SQL statement into a variable that I would like to run.
When I try to run it as a variable I receive a token error
Some background
Here is an example that works because it does not use a variable
Exec SQL
Create table MyLib/MyFile as(select * from XXLIB/XXFILE)
DATA INITIALLY DEFERRED REFRESH DEFERRED
maintained by user;
When I save this in a variable like #SQLStm and then try to execute as SQL
Exec SQL
:#SQLStm;
I get the error
Token : was not valid. Valid tokens: .
Also I am open to different approaches
https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_71/cl/runsqlstm.htm
Like RUNSQLSTM SRCFILE(MYLIB/MYFILE) SRCMBR(MYMBR)
Maybe there is a way to take a variable and save it to a source member?
Then use RUNSQLSTM over the source member
Showing some code:
Definition for the variable
d #SQLStm s A Len(6144) Varying(4)
Even when trying a portion of the SQL statement as a variable
#SQLStm = select * from XXLIB/XXFILE;
and then try:
Exec SQL
Create table MyLib/MyFile as( :#SQLStm)
DATA INITIALLY DEFERRED REFRESH DEFERRED
maintained by user;
I get the error
Token : was not valid. Valid tokens: .
I expect the SQLRPLE to compile
Instead of SQL precompile failed.
MSG ID SEV RECORD TEXT
SQL0104 30 236 Position 31 Token : was not valid. Valid tokens:
.
Message Summary
Total Info Warning Error Severe Terminal
1 0 0 0 1 0
30 level severity errors found in source
This is static SQL
Exec SQL
Create table MyLib/MyFile as(select * from XXLIB/XXFILE)
DATA INITIALLY DEFERRED REFRESH DEFERRED
maintained by user;
What you want is dynamic SQL
wSqlStmt = 'Create table MyLib/MyFile as(select * from XXLIB/XXFILE)'
+ ' DATA INITIALLY DEFERRED REFRESH DEFERRED'
+ ' maintained by user';
exec SQL
execute immediate :wSqlStmt;
Note that some statements can't be execute immediate instead you have to prepare then execute them.
more information can be found in the Embedded SQL programming manual.

How to count rows in SSIS based on specific conditions?

I have a Stored Procedure in SQL Server 2008 like below.
ALTER PROCEDURE myStoredProcedure
#Id int,
#hin varchar(30),
#checkValue varchar(30),
#CounterDeceasedPatients int=0 OUTPUT
insert into myTable
values (#Id, #hin, GETDATE())
if (#checkValue is not null)
BEGIN
set #CounterDeceasedPatients = #CounterDeceasedPatients + 1;
update myTable
set hin= #checkValue
where Id = #Id
RETURN;
END
I am calling this SP via SSIS, by using an OLE DB Command in Data Flow, which enables each rows in my file go to the SP - with the sql command: EXEC [dbo].[myStoredProcedure] ?,?,?. (The order of data (?) in my file is: Id, hin, checkValue)
What I want to do is to count how many different records (different rows) entered the if condition in my SP. SO I believe need to place a "row counter" somewhere, filtering its usage where #checkValue is not null. But I couldnt find it how. I am a newbie in SSIS, so I appreciate if someone helps me to figure this out. Thanks.
EDIT: I am trying to select only #checkValue as an input parameter for my ROW COUNT, but it is giving error:
EDIT2: I updated my SP. I added "CounterDeceasedPatients" variable as Int32 in SSIS and assigned it to 0. My sql execute command is: EXEC [dbo].[myStoredProcedure] ?,?,?,?,CounterDeceasedPatients
This is giving me the error:
Source: "Microsoft OLE DB Provider for SQL Server" Hresult:
0x80040E07 Description: "Error converting data type nvarchar to
int.".
When I use EXEC [dbo].[myStoredProcedure] ?,?,?,?,CounterDeceasedPatients output as SQL command, then I receive the error:
Description: "Cannot use the OUTPUT option when passing a constant to
a stored procedure.
I need help.
Use a script transformation and a DataFlow-level package variable.
Create the int-type variable with a default of 0, and in the script transformation, increment the variable if checkvalue is not null for the incoming row, and then use the value of the variable to set the value of your counter column.
Note that I am suggesting this INSTEAD of trying to update the counter with an OUTPUT variable in your stored procedure, and not as a way of trying to get that idea to work.

SQL - Raise error in Sproc when the select result set is empty

I am trying to execute a stored procedure within a SQL JOB step (SQL Server 2005).
I want to Raise error and fail the job step when the result set of the stored procedure I am executing is not empty.
what my stored procedure does is --I have a select statement where the rows are displayed if the current date is equal to the date in one of the columns of a table.
SELECT
Holiday_date
from tblHolidays
where
CONVERT(VARCHAR(10),GETDATE(),101) = CONVERT(VARCHAR(10),Holiday_date,101)
If the result set is empty, I want to succeed the job step and proceed with the next job step.
Any thoughts on how to get this working.
Thanks
You can try RAISERROR althought I can't remember if this will cause the whole job to fail, if it does try one of the warning severity levels.
IF ##ROWCOUNT > 0
RAISERROR ('found data', 16, 1)