DECLARE @nvcSQL NVARCHAR(MAX)
DECLARE @pvcTableName VARCHAR(255)
DECLARE @pvcColumn VARCHAR(255)
DECLARE @pvcValue NVARCHAR(MAX)
--This is used to actually get the primary key for identity record
DECLARE @dvcPrimaryKey VARCHAR(255)
SET @dvcPrimaryKey = ''
DECLARE @dintPrimaryKey INT
SELECT @dvcPrimaryKey = ISNULL(NAME,'') FROM SYS.COLUMNS WHERE OBJECT_NAME(OBJECT_ID) = @pvcTableName AND Is_Identity = 1
-- Only execute when there is a @pvcValue.
IF @pvcValue <> ''
BEGIN
SELECT @nvcSQL = 'INSERT INTO ' + @pvcTableName + '(' + @pvcColumn+ ') VALUES (' + @pvcValue + ')'
SELECT @nvcSQL = @nvcSQL + ';' + 'SELECT @dintPrimaryKey = SCOPE_IDENTITY()'
--PRINT @nvcSQL
EXEC sp_executesql @query = @nvcSQL, @params = N'@dintPrimaryKey INT OUTPUT', @dintPrimaryKey = @dintPrimaryKey OUTPUT
--EXEC (@nvcSQL)
END
IF @dvcPrimaryKey <> ''
BEGIN
SELECT (@dvcPrimaryKey + ' = ' + CAST(@dintPrimaryKey AS VARCHAR(10))) AS PrimaryKey
END
ELSE
BEGIN
SELECT '' AS PrimaryKey
END
Question: Why do we need to use sp_executesql instead of EXEC? Because EXEC just execute a SQL command without returning/expecting any result from it.
How to set a variable in a Dynamic SQL query
Here is the scenario, You have a stored procedure that builds dynamic insert SQL which means the "INSERT" statement is being composed on the fly based on the table name but at the same time you need to get SCOPE_IDENTITY or the last identity number inserted for further processing (e.g History table)