Insert a single row and return its primary key

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)

Solution 1:

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.

Solution 2:

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.

Solution 3:

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)