SQL Server : how to insert using variable - sql

I am trying to insert data into a SQL Server table using a variable. I tried
DECLARE #table NVARCHAR(50) = 'ToolList',
#val NVARCHAR(50) = 'test'
EXEC ('INSERT INTO ' + #table + 'SELECT ' + #val)
and
EXEC ('INSERT INTO ' + #table + '([col1]) VALUES(' + #val +')'
but still get an error that says
Incorrect syntax near 'test'.

you missed a space before SELECT and the #val should enclosed in single quote
DECLARE #table nvarchar(50) = 'ToolList',
#val nvarchar(50) = 'test'
EXEC ( 'INSERT INTO ' + #table + ' SELECT ''' + #val + '''')
when you use Dynamic SQL, it is easier to form the query in a variable so that you can print out , inspect the value before execution
select #sql = 'INSERT INTO ' + #table + ' SELECT ''' + #val + ''''
print #sql
exec (#sql)

You'd better use sp_executesql that allows for statements to be parameterized, to avoid the risk of SQL injection.
DECLARE #Query NVARCHAR(1000),
#table NVARCHAR(50) = 'ToolList'
SET #Query = 'INSERT INTO ' + #table + ' SELECT #val'
EXEC sp_executesql #Query, N'#val nvarchar(50)', #val = 'test'
sp-executesql-transact-sql

You can also use CHAR(39) instead of adding single quotes every time for better readability. And also, you have not added a space after the variable which contains the table name.
Query
declare #table nvarchar(50) = 'ToolList',
#val nvarchar(50) = 'test2';
declare #sql as varchar(max) = 'insert into ' + #table
+ ' select ' + char(39) + #val + char(39);
exec(#sql);

You need 4 singlequotes before the #val field as it is a string and all strings needs to be encapsulated in single quotes.
You can print the dynamic string using PRINT command check what the final string you are going to execute.
DECLARE #table VARCHAR(50) = 'ToolList'
DECLARE #val VARCHAR(50) = 'test'
DECLARE #DSQL AS VARCHAR(MAX) = ''
SET #DSQL = #DSQL + ' INSERT INTO [' + #table + ']' + '
SELECT ' + '''' + #val + ''''
--PRINT #DSQL
EXEC(#DSQL)

Related

Like in dynamic function

The code below works well. I however have issues trying to turn it into a like statement that I need some assistance with
CREATE PROCEDURE [dbo].[searcher]
#deliverer nvarchar (100)
AS
BEGIN
DECLARE #sql nvarchar(1000)
SET #sql = 'SELECT location, deliverer, charger FROM Store where 1=1'
IF (#deliverer IS NOT NULL)
SET #sql = #sql + ' and deliverer =#pt'
DECLARE #t1 as TABLE
(
location varchar(1000),
deliverer varchar(100),
charger varchar(100)
)
INSERT INTO t1
EXEC sp_executesql #sql,
N'#pt nvarchar(100)',
#pt=location
SELECT * FROM t1
END
So far, I have tried the code below but with not much success
DECLARE #pt nvarchar (100)
SET #pt = '%' + #pt + '%'
IF (#deliverer IS NOT NULL)
SET #sql = #sql + ' and deliverer like #pt'
I have also tried;
DECLARE #pt nvarchar (100)
IF (#deliverer IS NOT NULL)
SET #sql = #sql + ' and deliverer like ''% + #pt + %'''
If your stored procedure parameter is #deliverer and your dynamic SQL parameter is #pt, I believe your sp_executesql execution should assign the parameter as #pt = #deliverer.
As for adding wildcards, you can either add them before the call with
SET #deliverer = '%' + #deliverer + '%'
or add them in the dynamic SQL with
SET #sql = #sql + ' and deliverer like ''%'' + #pt + ''%'''
Note the doubled up quotes around the %. The variable #pt is not quoted

How to pass table name and column name dynamic in SQL

I was trying to pass table name and column name dynamic, this is as part of SSIS process I am trying this stored procedure below.
CREATE PROCEDURE [lnd].[Get_ANCNotullColumn]
(#PassedTableName AS NVarchar(255),
#PassedColumnName AS NVARCHAR(100))
AS
BEGIN
DECLARE #ActualTableName AS NVarchar(255)
SELECT #ActualTableName = QUOTENAME( TABLE_NAME )
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = #PassedTableName
DECLARE #sql AS NVARCHAR(MAX)
SELECT #sql = 'SELECT COUNT(*) FROM ' + #ActualTableName + ';'
DECLARE #final AS NVARCHAR(MAX)
SELECT #final = #sql + 'WHERE ' + #PassedColumnName + ' IS NULL OR ' + #PassedColumnName + '='''
EXEC(#SQL)
END
On executing this, I am NOT getting count as result, instead I am getting execution success.
EXEC [lnd].[Get_ANCNotullColumn] 'lnd.ANC_LND_ItemOverride', 'comments'
I need to get the count as output.
Also my simple direct query is like this
SELECT COUNT(*)
FROM lnd.ANC_LND_ItemOverride
WHERE Comments IS NULL OR Comments = '' -- 3 is the output
I think you may need to modify you value passing and your concatenation values.
from this statement you need to remove the semi colon as it will throw error
SELECT #sql = 'SELECT COUNT(*) FROM ' + #ActualTableName + ';'
While passing blank values you need additional quotes
SELECT #final = #sql + 'WHERE ' + #PassedColumnName + ' IS NULL OR ' + #PassedColumnName + '= '''''
While execution I believe you wanted to execute final instead of SQL
I think below should give your output:
CREATE PROC [lnd].[Get_ANCNotullColumn]( #PassedTableName as NVarchar(255),#PassedColumnName AS
NVARCHAR(100))
AS
BEGIN
DECLARE #ActualTableName AS NVarchar(255)
SELECT #ActualTableName = QUOTENAME( TABLE_NAME )
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = #PassedTableName
DECLARE #sql AS NVARCHAR(MAX)
SELECT #sql = 'SELECT COUNT(*) FROM ' + #ActualTableName + ' '
DECLARE #final AS NVARCHAR(MAX)
SELECT #final = #sql + 'WHERE ' + #PassedColumnName + ' IS NULL OR ' + #PassedColumnName + '='''''
EXEC(#final)
END

Assign result from dynamic SQL in a parameter to another parameter

I'm having to build my query dynamically, firstly, it gets the maxlogid from the log, and appends this to the temporary table name. Then it does a COALESCE to return the distinct values into a string.
However, the output of the string, I want to have in a parameter, so I can use it again later on within a dynamic sql query.
Here is my code;
DECLARE #maxLogId VARCHAR(10)
SELECT #maxLogId = (SELECT Max(id) FROM dbo.tLog)
DECLARE #PolicyTempTable VARCHAR(100)
SET #PolicyTempTable = '##tPols' + #maxLogId
DECLARE #emailParm NVARCHAR(1000)
SET #emailParm = N'DECLARE #email VARCHAR(MAX)
SELECT COALESCE(#email+'','' ,'''') + '''''''''''' + EMAIL + ''''''''''''
FROM (SELECT DISTINCT EMAIL FROM ' + #PolicyTempTable + ') d'
EXEC sp_executesql #emailParm
The results are returned as follows;
"abc#a.co.uk",""abc#b.co.uk"
I want to be able to write the sp_executesql into a seperate parameter, so I can use for a dynamic query like below;
DECLARE #StrSQLEmail VARCHAR(8000)
SET #StrSQLEmail = 'SELECT * FROM OPENQUERY(ATOM,''Select * from ATOMS.EMAILS WHERE EMAIL IN (' + '' EXEC sp_executesql #emailParm + '' + ')'')'
However, I can't use the sp_executesql within my dynamic query.
You can use parameters with sp_executesql
DECLARE #emailParm NVARCHAR(1000)
DECLARE #emailOut NVARCHAR(MAX)
SET #emailParm = N'SELECT COALESCE(#email+'','' ,'''') + '''''''''''' + EMAIL + ''''''''''''
FROM (SELECT DISTINCT EMAIL FROM ' + #PolicyTempTable + ') d'
EXEC sp_executesql #emailParm, N'#email VARCHAR(1000) OUTPUT', #email = #emailOut OUTPUT
Then you can build your second dynamic sql
DECLARE #StrSQLEmail VARCHAR(8000)
SET #StrSQLEmail = 'SELECT * FROM OPENQUERY(ATOM,''Select * from ATOMS.EMAILS WHERE EMAIL IN (' + #emailOut + ')'')'

Return Row Count Using Dynamic SQL

I'm trying to run the following Dynamic SQL statement:
#Tbl, #Fld, and #LookupValue have all been set according to Table to search, Field (Or Column) to search and column value to compare.
DECLARE #Sql AS VARCHAR(500)
SET #Sql = 'SELECT COUNT(*)
FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + ''''
EXEC(#Sql)
I want to store the result into a variable so I can check to see if there are any returned rows. This statement is in the middle of a WHILE construct that is checking several tables and fields.
If records are found, then I want to display:
SET #Sql = 'SELECT ' + #Fld +
' FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + ''''
EXEC(#Sql)
Yes, you can store it in a typed variable and use sp_executesql like
DECLARE #Sql AS NVARCHAR(500);
DECLARE #cnt INT;
SET #Sql = 'SELECT #cnt = COUNT(*)
FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + '''';
EXEC sp_executesql #Sql, N'#cnt INT OUTPUT', #cnt OUTPUT;
SELECT #cnt;
you can create a temporary table and store the count value.
if object_id('tempdb.#mycount') is null
create table #mycount ( countVal int);
DECLARE #Sql AS VARCHAR(500)
SET #Sql = 'INSERT INTO #mycount
SELECT COUNT(*)
FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + ''''
EXEC(#Sql)
select countVal from #mycount
-- once the temp table usage is done, you can delete it
drop table #mycount

Dynamic SQL Output variable

Please see the SQL code below:
declare #Classification as varchar(5)
set #Classification =''
declare #ClassificationSQL as nvarchar(4000)
set #ClassificationSQL=''
declare #cnt int
declare #counts int
DECLARE NicheDeletionOffenderCursor CURSOR FOR
select classification from dbnicheoffenderclassificationlookup
Open NicheDeletionOffenderCursor
FETCH NEXT FROM NicheDeletionOffenderCursor INTO #Classification
WHILE ##FETCH_STATUS = 0
BEGIN
If #ClassificationSQL=''
set #ClassificationSQL='classification like ' + char(39) + '%' + #Classification + '%' + char(39)
else
set #ClassificationSQL=#ClassificationSQL + ' OR classification like ' + char(39) + '%' + #Classification + '%' + char(39)
FETCH NEXT FROM NicheDeletionOffenderCursor INTO #Classification
END
CLOSE NicheDeletionOffenderCursor
DEALLOCATE NicheDeletionOffenderCursor
SET #ClassificationSQL = 'select count(*) as cnt from person where id=903 and (' + #ClassificationSQL + ')'
EXECUTE sp_executesql #ClassificationSQL, N'#cnt int OUTPUT', #cnt=#Counts OUTPUT
How do I assign the count output from #ClassificationSQL to a variable to use in the next part of the TSQL?
There are several things to mention here:
No need to declare the variable used inside of the dynamic sql (i.e. #cnt) outside of it (i.e. at the top)
No need for a cursor as a simple SELECT #var = #var + column construct will concatenate
With no cursor, there is no need to declare the variable used with it (i.e. #Classification)
Single-quotes can be escaped by using two of them (i.e. ''). However, it could simply be preference to use CHAR(39) instead as some people find it to be more readable.
Setting a variable in dynamic SQL is just like regular SQL (i.e. SELECT #var = expression FROM...)
End result:
DECLARE #ClassificationSQL NVARCHAR(4000)
DECLARE #Counts INT
SET #ClassificationSQL = COALESCE(#ClassificationSQL + N' OR ', '')
+ N'classification LIKE ''%'
+ classification
+ N'%'''
FROM dbnicheoffenderclassificationlookup
SET #ClassificationSQL =
N'SELECT #TempCount = COUNT(*) FROM person WHERE id = 903 AND ('
+ #ClassificationSQL
+ N')'
EXECUTE sp_executesql
#ClassificationSQL,
N'#TempCount INT OUTPUT',
#TempCount = #Counts OUTPUT
SELECT #Counts
See a below sample about how you can get the output of a dynamic query (tested in SQL Server 2008 R2). Actual post from where the idea is taken How to get sp_executesql result into a variable?
DECLARE #retval int;
DECLARE #SQL nvarchar(500);
DECLARE #Param nvarchar(500);
DECLARE #table nvarchar(50)
SELECT #table = N'newperson'
SELECT #SQL = N'SELECT #retvalOUT = MAX(salary) FROM ' + #table;
SET #Param = N'#retvalOUT int OUTPUT';
EXEC sp_executesql #SQL, #Param, #retvalOUT=#retval OUTPUT;
SELECT #retval;
You can make changes to your procedure accordingly.