Through the exec in SQL Server, I want to retrieve the parameter's value dynamically. Please look into the below Example:
declare #p1 varchar(50) = '10'
declare #p2 varchar(50) = '20'
declare #p_nm varchar(50)
set #p_nm = '#p1' -- OR set #p_nm = '#p2'
declare #sql varchar(50) = 'select #p1'
declare #ans_val varchar(50)
set #ans_val = exec #sql
How could I get the result 10 if using set #p_nm = '#p1' and 20 if using set #p_nm = '#p2'?
In my case set #ans_val = exec #sql giving syntax error.
A variable only has scope within the batch it is inside. When you run dynamic SQL, the dynamic SQL has a different scope, so variables cannot be accessed if they are in a different one. For example, both of the following statements will generate an error:
DECLARE #SQL nvarchar(MAX) = N'SELECT #i;';
DECLARE #i int = 1;
EXEC (#SQL);
GO
DECLARE #SQL nvarchar(MAX) = N'DECLARE #i int = 1;';
EXEC (#SQL);
SELECT #i;
GO
If you are running dynamic SQL, you need to pass details of any variables as parameters, using sp_executesql. For example:
DECLARE #SQL nvarchar(MAX) = N'SELECT #n;';
DECLARE #i int = 1;
EXEC sp_executesql #SQL, N'#n int', #n = #i;
If you want the return scalar values to a variable, use an OUTPUT parameter (personally, I recommend against the syntax {Variable} = EXEC {Expression/Stored Procedure}, one reason being you are therefore limited to one scalar value).
So, again, as an example:
DECLARE #SQL nvarchar(MAX) = N'SET #a = #n + 1;';
DECLARE #i int = 1, #b int;
EXEC sp_executesql #SQL, N'#n int, #a int OUTPUT', #n = #i, #a = #b OUTPUT;
PRINT #b;
I'll do it like:
EXECUTE sp_executesql
N'SELECT #Var AS Result',
N'#Var VARCHAR(5)',
#Var = '12345';
Results:
+----+--------+
| | Result |
+----+--------+
| 1 | 12345 |
+----+--------+
Or
DECLARE #Out VARCHAR(5);
EXECUTE sp_executesql
N'SELECT #Out = #Var',
N'#Var VARCHAR(5) , #Out VARCHAR(5) OUTPUT',
#Var = '12345',
#Out = #Out OUTPUT;
SELECT #Out As Result;
Finally, please don't forgot to visit sp_executesql
Related
USE GDMDBNS_1720
GO
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'PROCEDURE'
AND ROUTINE_SCHEMA = 'dbo' AND ROUTINE_NAME = 'usp_RmsExecuteValidationRule')
BEGIN
DROP PROCEDURE dbo.usp_RmsExecuteValidationRule
END
GO
Create PROCEDURE [dbo].[usp_RmsExecuteValidationRule]
#nRuleId INT,
#FIPSName VARCHAR(5)
AS
BEGIN
DECLARE #strRuleQuery VARCHAR(MAX)
DECLARE #sqlstat AS NVARCHAR(MAX)
DECLARE #params AS NVARCHAR(MAX)
SET #strRuleQuery = N'SELECT RULE_QUERY from GdmValidationRuleMaster where
RULE_ID = #nRuleId'
SET #sqlstat = #strRuleQuery
SET #params = N'#FIPSName VARCHAR(5)'
EXEC sp_executesql #params,
#query = #sqlstat,
#FIPSName = #FIPSName
END
got error while Debugging must declare scalar variable #nRuleId . I have already declared. But error is pooping out always.
There appear to be a number of issues with the code, as is.
To return a value, you need to declare an OUTPUT parameter and the variable #FIPSName is not actually used in the code, and #strRuleQuery is superfluous in this code.
Here is the code from inside the SProc, that should be closer to your needs.
-- Parameters
DECLARE
#nRuleId INT = 1,
#FIPSName VARCHAR(5) = 'ITS'
-- Local variables
DECLARE #sqlstat AS NVARCHAR(MAX)
DECLARE #params AS NVARCHAR(MAX)
DECLARE #RULE_QUERY NVARCHAR(MAX)
SET #sqlstat = N'SELECT #RULE_QUERY=RULE_QUERY from GdmValidationRuleMaster where RULE_ID = #nRuleId'
SET #params = N'#nRuleId INT, #RULE_QUERY NVARCHAR(MAX) OUTPUT'
EXEC sp_executesql
#sqlstat,
#params,
#nRuleId = #nRuleId, #RULE_QUERY= #RULE_QUERY OUTPUT
-- Output
SELECT #RULE_QUERY
You must rewrite execution part:
SET #params = N'#FIPSName VARCHAR(5), #nRuleId int'
EXEC sp_executesql #strRuleQuery, #params, #FIPSName = #FIPSName, #nRuleId = #nRuleId
I don't understand, why do you pass #FIPSName as parameter, it is not used in your batch.
I'm trying to verify a job number exists on a linked server and get back a variable (#JobExists) indicating whether it does or not (1 for yes, 0 for no).
To do this I'm trying to use OPENQUERY along with sp_executesql as I have to pass in a parameter for the job number. I've tried the code below but get the error 'Procedure expects parameter '#statement' of type 'ntext/nchar/nvarchar'. For testing purposes I've declared and set the variable #JobNumber.
DECLARE #JobNumber as varchar(50)
SET #JobNumber = '2112111'
DECLARE #JobExists as BIT
DECLARE #JobCount as int
DECLARE #ParmDefinition as varchar(100)
DECLARE #sql as varchar(500)
SET #JobExists = 0
SET #ParmDefinition = N'#Result int output'
SET #sql = 'SELECT #Result = SELECT COUNT(*) FROM OPENQUERY(MYLINKEDSVR,''SELECT JOB_NUMBER FROM PROD.tbl1 WHERE JOB_NUMBER = ''''' + UPPER(RTRIM(LTRIM(#JobNumber))) + ''''''')'
exec sp_executesql #sql, #ParmDefinition, #Result = #JobCount output
IF #JobCount > 0
SET #JobExists = 1
SELECT #JobExists
I've read up sp_executesql here: http://technet.microsoft.com/en-us/library/ms188001.aspx
I've also done various searches but haven't come across any answers that work for me.
Is there something I'm missing?
The error message is clear: you must declare #sql as nvarchar and not as varchar.
The same for #ParamDefinition:
DECLARE #ParmDefinition as nvarchar(100)
DECLARE #sql as nvarchar(500)
I write a query in sql server i am getting value in a temporary variable, this is my query
declare #tacolumn1 varchar(50)='cargo'
declare #temp1 varchar(50)
declare #sql nvarchar(max)
print #tacolumn1
set #sql= ('select '+#tacolumn1+' from operatingincome where YEAR(createddate)= 2009')
exec sp_executesql #sql
print #temp1
from the above #sql has the value , now i want to save that value in #temp1 how can i do that one
sp_executesql procedure can have input and output parameters:
DECLARE #IntVariable int;
DECLARE #SQLString nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
DECLARE #max_title varchar(30);
SET #IntVariable = 197;
SET #SQLString = N'SELECT #max_titleOUT = max(JobTitle)
FROM AdventureWorks2008R2.HumanResources.Employee
WHERE BusinessEntityID = #level';
SET #ParmDefinition = N'#level tinyint, #max_titleOUT varchar(30) OUTPUT';
EXECUTE sp_executesql #SQLString, #ParmDefinition, #level = #IntVariable, #max_titleOUT=#max_title OUTPUT;
SELECT #max_title;
DECLARE #dbName nvarchar(128) = 'myDb'
DECLARE #siteId int
exec ('SELECT TOP 1 #siteId = Id FROM ' + #dbName + '..myTbl')
select #siteId
When I run the script above I get the following error
Msg 137, Level 15, State 1, Line 1
Must declare the scalar variable "#siteId".
(1 row(s) affected)
Why and how to fix it?
Thank you
You can use output parameters with sp_executesql.
DECLARE #dbName nvarchar(128) = 'myDb'
DECLARE #siteId int
DECLARE #SQL nvarchar(max) = N'SELECT TOP 1 #outputFromExec = Id FROM ' + quotename(#dbName) + N'..myTbl'
exec sp_executesql #SQL, N'#outputFromExec int out', #siteId out
select #siteId
The dynamic SQL is a different scope to the outer, calling SQL: so #siteid is not recognised
You'll have to use a temp table/table variable outside of the dynamic SQL:
DECLARE #dbName nvarchar(128) = 'myDb'
DECLARE #siteId TABLE (siteid int)
INSERT #siteId
exec ('SELECT TOP 1 Id FROM ' + #dbName + '..myTbl')
select * FROM #siteId
Note: TOP without an ORDER BY is meaningless. There is no natural, implied or intrinsic ordering to a table. Any order is only guaranteed by the outermost ORDER BY
You can try like below
DECLARE #sqlCommand NVARCHAR(4000)
DECLARE #ID INT
DECLARE #Name NVARCHAR(100)
SET #ID = 4
SET #sqlCommand = 'SELECT #Name = [Name]
FROM [AdventureWorks2014].[HumanResources].[Department]
WHERE DepartmentID = #ID'
EXEC sp_executesql #sqlCommand, N'#ID INT, #Name NVARCHAR(100) OUTPUT',
#ID = #ID, #Name = #Name OUTPUT
SELECT #Name ReturnedName
Source : blog.sqlauthority.com
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Andrew Foster
-- Create date: 28 Mar 2013
-- Description: Allows the dynamic pull of any column value up to 255 chars from regUsers table
-- =============================================
ALTER PROCEDURE dbo.PullTableColumn
(
#columnName varchar(255),
#id int
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #columnVal TABLE (columnVal nvarchar(255));
DECLARE #sql nvarchar(max);
SET #sql = 'SELECT ' + #columnName + ' FROM regUsers WHERE id=' + CAST(#id AS varchar(10));
INSERT #columnVal EXEC sp_executesql #sql;
SELECT * FROM #columnVal;
END
GO
A slight change in the execute query will solve the problem:
DECLARE #dbName nvarchar(128) = 'myDb'
DECLARE #siteId int
exec ('SELECT TOP 1 **''#siteId''** = Id FROM ' + #dbName + '..myTbl')
select #siteId
how to assign the integer value to nvarchar or varchar datatype in stored procedure
DECLARE #SQLString nvarchar(max)
SET #SQLString = N'declare #Identifier int;
SELECT COUNT(*) FROM ' + #batch+' where Identifier = #Identifier'
i need to check whether the #SQLString is 0 or not.
i.e i want to check -----> if(#SQLString =0). how to assign a integer val to nvarchar or varchar
You could try something like
DECLARE #IntVal INT,
#ParamDef NVARCHAR(MAX),
#SQLString nvarchar(max),
#batch VARCHAR(MAX)
SELECT #batch = 'Batch',
#SQLString = N'SELECT #IntVal = COUNT(*) FROM ' + #batch,
#ParamDef = '#IntVal INT OUTPUT'
EXECUTE sp_executesql #SQLString,#ParamDef, #IntVal=#IntVal OUT
SELECT #IntVal
Have a look at sp_executesql (Transact-SQL)
I think this way is best:
DECLARE
#Cnt int,
#SQL nvarchar(max),
#batch sysname,
#Identifier varchar(30)
-- set #batch and #Identifier
SET #SQL = 'SELECT #Cnt = Count(*) FROM ' + #batch
+ ' WHERE Identifier = #Identifier'
EXEC sp_executesql #SQL, N'#Cnt int OUT, #Identifier varchar(30)',
#Cnt OUT, #Identifier
IF #Cnt = 0 BEGIN
--do something
END
ELSE BEGIN
--do something else
END
Though if you only care whether it's 0 or not, then you should do this instead, which can stop after finding only one row, instead of having to count them all:
DECLARE
#HasRows bit,
#SQL nvarchar(max),
#batch sysname,
#Identifier varchar(30)
-- set #batch and #Identifier
SET #SQL = 'SET #HasRows = CASE WHEN EXISTS (SELECT 1 FROM '
+ #batch + ' WHERE Identifier = #Identifier) THEN 1 ELSE 0 END'
EXEC sp_executesql #SQL, N'#HasRows bit OUT, #Identifier varchar(30)',
#HasRows OUT, #Identifier
IF #HasRows = 0 BEGIN
--do something
END
ELSE BEGIN
--do something else
END
However, if there's any way you can avoid using dynamic SQL and changing table names, that would be best. Then it is a simple query:
IF NOT EXISTS (SELECT 1 FROM TableName WHERE Identifier = #Identifier) BEGIN
-- do something
END
You're setting #SQLString to a query... if you want to see if it's '0', then you can just do:
IF #SQLString = '0'
But I think you're trying to find out if there are 0 rows in your batch, in which case, you mean something more like:
DECLARE #Res TABLE (cnt int);
INSERT #Res exec sp_executesql #SQLString;
IF (SELECT MAX(cnt) FROM #Res) = 0 /* Means empty batch */
convert it:
SET #var = CONVERT(VARCHAR, #intval)
Sascha
I am assuming that you are trying to check how many rows the dynamic sql returned you can do something like this:
DECLARE #SQLString nvarchar(max)
SET #SQLString = N'declare #Identifier int;
SELECT * FROM ' + #batch+' where Identifier = #Identifier'
exec #SQLString
set #SQLString = ##ROWCOUNT
if #SQLString = 0
begin
...
end