Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert a single row and return its primary key

Tags:

ssis

In SSIS, How do I use the execute SQL task to insert a single row with no parameters and get the primary key back so I can set it to user variable? My insert query is simply:

INSERT INTO [AdWords.ImportData] (EndDate) VALUES (null)
like image 395
Brad Urani Avatar asked Jan 18 '12 17:01

Brad Urani


3 Answers

Here is another alternative I think is very clean. It uses OUTPUT syntax and the Result Set instead of Parameter Mapping, which requires less configuration.

insert dbo.ImportData (EndDate) 
output inserted.Id 
values (NULL);
  • Replace Id in this statement with the name of your identity column.
  • Use "Single row" as the Resultset type.
  • No parameter mappings
  • Add this to the Result Set tab: Result Name: 0 (meaning the first column) and select your variable name e.g. User::tablePk (Variable type: Int32)
like image 107
H B Avatar answered Nov 20 '22 22:11

H B


Good question, took me a few tries to figure it out. Declare an SSIS variable of type Int32 (unless you need sizing for a bigint or numeric). I chose tablePk as mine.

Option 1

Execute SQL Task

  • General tab

ResultSet: None

SQL

INSERT INTO dbo.ImportData (EndDate) VALUES (NULL);
SELECT ? = SCOPE_IDENTITY()
  • Parameter Mapping tab

Variable Name: User::tablePk

Direction: Output

Data Type: Long

Parameter Name: 0

Parameter Size: -1

Option 2

This was the original solution as I couldn't grok how to get the placeholder ? in a normal query. It couldn't as simple as what I had above, except it was.

The only difference is the query used

SQL

DECLARE @sql nvarchar(500)
, @paramDef nvarchar(500)

SELECT
    @sql = N'INSERT INTO dbo.ImportData (EndDate) VALUES (NULL);
    SELECT @ident = SCOPE_IDENTITY();'
,   @paramDef = N'@ident int OUTPUT'
EXECUTE sp_executesql @sql, @paramDef, @ident = ? OUTPUT

Option 3

If you're using a data flow, I outline an approach on How to Add the Result Set from a T-SQL Statement to a Data Flow? In short, you need to add a column into the data flow prior to an OLE DB Command. Within the OLE DB Command, you will map that empty column into a OUTPUT parameter from your stored procedure and then as the stored procedure fires, it will replace the column with the value from the procedure.

like image 20
billinkc Avatar answered Nov 20 '22 23:11

billinkc


Alternatively to bilinkc's version, without parameters:

Execute SQL Task

General tab ResultSet: Single Row

SQL

INSERT INTO dbo.ImportData (EndDate) VALUES (NULL);
SELECT SCOPE_IDENTITY() AS LastId

In the mapping of the single-row result set, enter LastId in the result name box, and map to your variable.

May well be marginally faster with a single output parameter (bilinkc's version), depends on how SSIS does it 'under the covers' and whether it creates a full datareader versus a single sp_ExecuteSQL call with output parameter.

like image 6
Meff Avatar answered Nov 20 '22 21:11

Meff