How can I get the output of the below query in a variable without temp table?
DECLARE #Q1 NVARCHAR(300)
DECLARE #Q2 NVARCHAR(300)
DECLARE #Q3 NVARCHAR(300)
SET #Q1 = 'SELECT ' +' ' + #formfieldpath
SET #Q2 = 'FROM [TestDatabase].[details] WHERE id ' + '=''' + CAST(#id AS VARCHAR(10)) + '''';
SET #Q3 = #Q1 +' '+ #Q2
PRINT #Q3
EXEC sp_executesql #Q3
Tried 'How to get sp_executesql result into a variable?' and not able to get the results.
Assuming that you get a singleton value from your dynamic statement:
DECLARE #ID int, --Is set somewhere
#YourVariable nvarchar(30), --Use an appropriate data type
#formfieldpath sysname; --Is set somewhere
DECLARE #SQL nvarchar(MAX);
--I assume that the name [TestDatabase].[details] is wrong, as [TestDatabase] would be the name of the schema, not the database,
--and I ASSUME you haven't foolishy created a schema called "TestDatabase"
SET #SQL = N'SELECT #YourVariable = ' + QUOTENAME(#formfieldpath) + N' FROM dbo.Details WHERE id = #id';
--Use the correct datatype for #YourVariable
EXEC sys.sp_executesql #SQL, N'#id int, #YourVariable nvarchar(30) OUTPUT', #id, #YourVariable OUTPUT;
Never inject unsanitised values into a dynamic SQL statement. SQL injection is a huge problem that should have stopped existing over a decade ago. Dos and Don'ts of Dynamic SQL
Related
Can you tell me how to insert executed variable #name in my table?
I had some coding and this is what i managed to do but I do not know whats next:
DECLARE #Name nvarchar(200);
DECLARE #dbcatalog nvarchar(128);
declare #sql nvarchar(4000)
select #name = N' select ID from ' + #DbCatalog + '.dbo.Table2 ';
SET #sql = 'insert into Table2(Name) values (#name)'
exec Sp_executeSQL #sql
Are you trying to copy ID values from one table into another? If so, then:
INSERT INTO Table2 (Name)
EXEC(#Name)
I'm trying to write a dynamic query that produces the same results as the following, but replaces the fixed tablename with a variable.
SELECT *
WHERE tableName = 'Table2A'
works fine but
DECLARE #tablename AS NVARCHAR(100)
SET #tablename = N'Table2A'
DECLARE #execquery AS NVARCHAR(MAX)
SET #execquery = N'
SELECT *
WHERE tableName = ''' + QUOTENAME(#tablename) + N''''
EXECUTE sp_executesql #execquery
returns no records. What am I doing wrong?
Aside from the fact that your SQL statement is invalid, QUOTENAME() simply places brackets "[]" around the supplied variable. Replace the EXECUTE statement with a PRINT statement, and you'll get the following results:
DECLARE #tablename AS NVARCHAR(100)
SET #tablename = N'Table2A'
DECLARE #execquery AS NVARCHAR(MAX)
SET #execquery = N'
SELECT *
WHERE tableName = ''' + QUOTENAME(#tablename) + N''''
PRINT #execquery
--EXECUTE sp_executesql #execquery
RESULTS:
SELECT *
WHERE tableName = '[Table2A]'
I have the following SQL Server stored procedure:
CREATE PROCEDURE ispsDcOhcAgg #TmpTableName NVARCHAR(50), #ListItem NVARCHAR(50)
AS
IF EXISTS (SELECT name
FROM sys.tables
WHERE name = #TmpTableName)
DROP TABLE #TmpTableName; -- This will not work.
GO
This will clearly not work (see the comment in the above snippit). The only (and very ugly) way I have found to get around this problem is to do the following
CREATE PROCEDURE ispsDcOhcAgg #TmpTableName NVARCHAR(50), #ListItem NVARCHAR(50)
AS
DECLARE #SQL NVARCHAR(4000)
SET #SQL = N'IF EXISTS (SELECT name ' +
N'FROM sys.tables ' +
N'WHERE name = N' + N'''' + #TmpTableName + N''') ' +
N'DROP TABLE ' + #TmpTableName + N';'
EXEC sp_executesql #SQL;
GO
which truly stinks and for large stored procedures, it's horrendous!
Is there another way of doing this that I don't know about?
Thanks for your time.
No, if you want to use a table name dynamically like this, you need to use dynamic SQL.
So you should make sure you don't open yourself up to nasty SQL injection risks!
Try something like this:
SET #SQL = 'IF EXISTS (SELECT name ' +
N'FROM sys.tables ' +
N'WHERE name = #TableName) ' +
N'DROP TABLE ' + QUOTENAME(#TmpTableName) + ';'
EXEC sp_executesql #SQL, N'#TableName sysname', #TmpTableName;
No, if you want to determine the table to be dropped at runtime, there is no alternative to dynamic SQL.
There is a slightly less ugly way: you only use dynamic SQL for the command that needs to be dynamic (the DROP command):
DECLARE #SQL NVARCHAR(100)
IF EXISTS (SELECT name
FROM sys.tables
WHERE name = #TmpTableName)
BEGIN
SET #SQL = N'DROP TABLE ' + #TmpTableName + N';'
EXEC sp_executesql #SQL;
END
I've read several examples of how to return an output parameter with dynamic sql, but all were slightly different in that they created the variable within the procedure, instead of passing them in (I'm assuming this is the root of my problem). I get the error:
Must declare the table variable "#tbl".
When I try to run the procedure below (listed after the test code that executes it). Am I close?
DECLARE #tbl nvarchar(40)
DECLARE #bnch INT
SET #tbl = 'tblDailyPricingAndVol'
EXEC sprocReturnDataPointBenchmark #tbl, #bnch
sproc:
ALTER PROCEDURE [dbo].[sprocReturnDataPointBenchmark] #tblName NVARCHAR(50),
#benchmark BIGINT OUTPUT
AS
BEGIN
DECLARE #sql nvarchar(1000),
#parameters NVARCHAR(100) = N'#tbl NVARCHAR(50), #benchOUT BIGINT OUTPUT';
SET #sql = N'SELECT #benchOUT = Count(ID) FROM #tbl WHERE DateAdded = ' +
'(SELECT MAX(DateAdded) FROM tblDailyATR AS T2)';
EXEC sp_executesql #sql, #parameters, #tbl = #tblName, #benchOUT = #benchmark OUTPUT
SELECT #benchmark
END
There were a couple syntactical errors in my first pass listed above, but the conceptual issue that I needed to resolve was trying to pass the table name (input parameter) in the parameters variable within the dynamic sql. Good example here: Generate dynamic SQL statements in SQL Server
So, my revised, working code is:
ALTER PROCEDURE [dbo].[sprocReturnDataPointBenchmark] #tblName NVARCHAR(50),
#benchmark BIGINT OUTPUT
AS
BEGIN
DECLARE #sqlStatement nvarchar(500)
DECLARE #parameters NVARCHAR(100)
DECLARE #fullStatement NVARCHAR(500)
SET #parameters = '#benchmark BIGINT OUTPUT'
SET #sqlStatement = N'SELECT #benchmark = Count(ID) FROM ' + #tblName + ' WHERE DateAdded = ' +
'(SELECT MAX(T2.DateAdded) FROM ' + #tblName + ' AS T2)';
EXEC sp_executesql #sqlStatement, #parameters, #benchmark = #benchmark OUTPUT
SELECT #benchmark
END
I have a query that is dynamically fetching the stored proc names from all the databases.
Now I want to execute the stored procs and store the result in a temptable or table variable.
How to do that. Here is my SP so far
Declare #GetDBNames sysname
Declare #DynSql nvarchar(max)
Declare DBNames cursor for
Select '['+name+']' from master.dbo.sysdatabases
open DBNames
FETCH NEXT FROM DBNames into #GetDBNames
WHILE ##FETCH_STATUS=0
BEGIN
SET #DynSql = '
Select Specific_Catalog as Database_Name, Routine_Name as ''Stored Procedure Name''
From '+ #GetDBNames+'.Information_Schema.Routines '
EXEC (#DynSql)
FETCH NEXT FROM DBNames into #GetDBNames
END
Close DBNames
Deallocate DBNames
Please help.
Thanks in advance
Here's my soluton. Cursors are evil :)
Declare #DynSql nvarchar(max)
declare #result table ([Database_Name] nvarchar(128), [Stored Procedure Name] sysname)
SET #DynSql = ''
select #DynSql = #DynSql + '
Select SPECIFIC_CATALOG COLLATE DATABASE_DEFAULT as Database_Name, ROUTINE_NAME COLLATE DATABASE_DEFAULT as [Stored Procedure Name]
From ' + NAME + '.INFORMATION_SCHEMA.ROUTINES' + CHAR(13) + 'union all' + CHAR(13)
from master.dbo.sysdatabases
--remove last "union all"
SET #DynSql = left(#DynSql, LEN(#DynSql) - 10)
insert #result
exec sp_executesql #DynSql
select * from #result
INSERT [TableName] EXEC (#DynSql)
Note that if you introduce data you may want to use sp_ExecuteSQL, and you probably want to use [/] object-name escaping.