How to get current value of unique identifier,assigned it to global variable and map it in ssis execute SQL task - sql

I am using SSIS execute SQL task to execut a stored procedure.In the stored procedure I am passing certain input values and inserting it to a table.This table has got a unique identifier as primary key.As a return output i need the current value of the unique identifier.So I am taking that to a variable #logid as shown below
INSERT INTO logging.execution_log
(ParentLogID,
Description,
PackageName,
PackageGuid,
MachineName,
ExecutionGuid,
LogicalDate,
Operator,
StartTime,
EndTime,
Status,
FailureTask)
SELECT #ParentLogID,
#Description,
#PackageName,
Cast(#PackageGuid AS UNIQUEIDENTIFIER),
#MachineName,
Cast(#ExecutionGuid AS UNIQUEIDENTIFIER),
#logicalDate,
#operator,
Getdate(),
NULL,
#status,
NULL
SET #LogID = Cast(Scope_identity() AS INT) ----#logid is output variable from ssis
but it is not giving the intended result .Here the assignment of the global variable has been done using set operator
to #logid and mapped to execute sql ssis task variable.
After some research i found that
in order to assign the global variables i have to set SET NOCOUNT option ON as the first statement in the SQL query .I have done this as well.But it is not returning anything........by the way *why do we need to set this SET NOCOUNT parameter???*any help welcome

In order for a parameter to return the value assigned in the procedure body, the parameter must be declared with the OUT/OUTPUT keyword in the procedure, like this:
CREATE PROCEDURE procname (
#logID int OUTPUT,
other parameters
)
AS
body statements
Also, the corresponding argument in the EXEC statement should be supplied with that same keyword (OUT or OUTPUT), like this:
EXEC procname #someGlobalVar OUTPUT, other arguments

You could always SELECT SCOPE_IDENTITY() AS LogID at the end of your Execute SQL Task and then set your expected result set to single row and configure the result with the single column of LogID and map that to your SSIS global variable.
Let me know if you need me to clarify any of that.

You can use Scope_Identity to get a uniqueidentifier, that is used for Identity column.
To get a uniqueidentifier, you will need to assign it to a variable before using it
Set #LogID = NewID()
INSERT INTO logging.execution_log VALUES(...., #logID, ...)
Except if you misunderstand what a uniqueidentifier means
Identity columns are auto-generated sequence of integer 1,2,3,4... and works with Scope_Identity.

Related

Using SCOPE_IDENTITY result in another query

I'm having difficulties with this code
EXECUTE Environment.dbo.psu_some_psu
#instanceId = 1
,#serverId = 2
,#ip = '111.111.111.111'
,#clientName = 'dev-contact'
,#applicationId = 9
,#accountId = 35
,#userID = 22
DECLARE #restoreId INT
SET #restoreId = SCOPE_IDENTITY()
UPDATE Environment.dbo.restore_requests
SET Status = 1
WHERE Id = #restoreId
The stored procedure insert a row with indentity and with a status by default.
After the execution of the stored procedure i use scope_identity to get the ID of the inserted row.
But i cant get the update to work, i think there is a problem with the WHERE condition.
Thanks
It's called SCOPE_IDENTITY() because it returns the last identity value inserted in the current scope - and since each procedure has it's own scope - you do not get the expected results.
Returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, if two statements are in the same stored procedure, function, or batch, they are in the same scope.
Use an output parameter to return the scope_identity() from inside the procedure that actually executes the insert statement.
Also, please note that if you are inserting multiple records, the scope_identity() will return only the last value - in such cases you use the output clause on the insert statement to get a table containing all the newly inserted identity values.
DECLARE #MyTableVar table( NewScrapReasonID smallint,
Name varchar(50),
ModifiedDate datetime);
INSERT Production.ScrapReason
OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
INTO #MyTableVar
VALUES (N'Operator error', GETDATE());

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.

Inserting a row in a table and storing its scope identity in a variable in a stored procedure

I am a newbie in stored procedure and knows only basics of SQL. With the help of some SO questions I was able to figure out that SCOPE_IDENTITY() function can be used to get recently added row's identity value. Now I am trying to insert a row in a table using a stored procedure and I want that the identity of this newly inserted row must be assigned to a stored procedure's variable. Following is the code:
DECLARE #retID int = -1
SET #retID = (INSERT INTO [InfoValues]([InfoID],[Value],[UserID],[DateAdded],[DateUpdated]) VALUES(#item2,#item,#UserID,GETDATE(), GETDATE()); SELECT SCOPE_IDENTITY())
But this code is showing a syntax error at INSERT clause. So what is the correct way to do it?
You're close. You need to set the variable after the insert occurs.
DECLARE #retID int = -1;
INSERT INTO [InfoValues]
([InfoID],[Value],[UserID],[DateAdded],[DateUpdated])
VALUES
(#item2,#item,#UserID,GETDATE(), GETDATE());
SET #retID = SCOPE_IDENTITY();

SELECT Query selecting values based on a value in another table

I have 2 tables
Account(AccountId, Encoding)
DeviceAccountMap(AccountId, DeviceId)
Now I need to fetch the devices from the DeviceAccountMap. I pass a list of AccountId to a stored procedure and while fetching the DeviceId from the DeviceAccountMap table I need to compare the Encoding value for each account with a particular value.
Which is the easy way to do this? I am totally lost.
The select clause in the stored procedure will look something like this:
DECLARE #Accounts [usp].[Array]
and [usp].[Array] is defined as below
CREATE TYPE [usp].[Array] AS TABLE
(
Value VARCHAR(36) NULL
)
SELECT
DeviceId,
AccountEncoding = A.Encoding
FROM
usp.DeviceControllerAccountMap DCAM
INNER JOIN
usp.Account A ON (DCAM.AccountId = A.AccountId)
WHERE
DCAM.AccountId IN (SELECT Value From #AccountIds)
AND DCAM.IsShared = 1
AND AccountEncoding LIKE A.Encoding + '.%'
In other words I need to fetch the encoding value for each account and use that in this where clause.
So you can look up information on Table-Valued Parameters (TVPs) in T-SQL.
Here is an article by Erland Sommarskog.
You can refer to this StackOverflow answer to see an example of C# code calling a stored procedure that uses a TVP. I believe TVPs require SQL Server 2008 or higher.
TVPs, as far as I understand, provide a way to make your own data type in sql server that gets treated as if it was a table. You're doing this when you declare your Array type and then when you use the #AccountIds in your stored procedure's select statement.
CREATE TYPE [usp].[Array] AS TABLE -- maybe choose a more descriptive name than 'Array'
(
Value VARCHAR(36) NULL -- choose a more descriptive name than 'Value'
)
CREATE PROCEDURE [usp].[your_procedure_name]
#AccountIds [usp].[Array] READONLY -- use TVP as a parameter
AS
SELECT …
It is not clear form your question details whether you also mean to have a parameter in the stored procedure for the Encoding. It seems like you're looking for accounts whose Encodings start with a period '.'.
So first, create your type, like you're doing.
Then create your stored procedure.
Then test your stored procedure, something like this:
DECLARE #mylist Array -- make TVP sample data
INSERT #mylist(Value) VALUES(1),(11),(27),(123) -- insert some values
exec your_procedure_name #mylist -- run stored procedure
The following line is completely unnecessary. The JOIN to Account does this filter for you.
DCAM.AccountId IN (SELECT Value From #AccountIds)
Or am I missing something?

Insert into table stored procedure results plus variable

I need to insert into a table the results of a stored procedure(SP) plus a couple of other variables.
I know how to insert the SP results but not the variables as well. Is there a way I can do this without having to write a separate update query or pass/return the variable into the SP.
I.e.
INSERT INTO contacttable(name, address, telnum)
EXEC GetContactDetails #ContactId
UPDATE contacttable SET linkId = #LinkId where id = #ContactId
Can I pass the #linkId variable into the INSERT in anyway rather than having to do the separate update?
Thanks.
You can't do this the way you explain your current scenario is.
You either modify the proc to receive the extra parameter and you return it from there so that the insert statements already has this parameter, or you continue doing what you are doing.
Another possibility would be to change that proc into a table-valued function in a way that you can specifically select the columns you need from the resultset and you add the extra parameter in the insert. Something like:
INSERT INTO contacttable(name, address, telnum,linkid)
select name, address,telnum,#linkid from fnGetContactDetails(#ContactID)