using Table variable with sp_executesql
Here's an example of how to pass a table-valued parameter to sp_executesql
. The variable has to be passed readonly
:
if exists (select * from sys.types where name = 'TestTableType')
drop type TestTableType
create type TestTableType as table (id int)
go
declare @t TestTableType
insert @t select 6*7
exec sp_executesql N'select * from @var', N'@var TestTableType readonly', @t
This prints the Answer to the Ultimate Question of Life, the Universe, and Everything.
Table variable in sp_executesql parameter list
You need to create a named type that your table variable will use:
create type dbo.myTableType as table (id int)
Then you can use it as a typed argument to sp_executesql:
declare @m dbo.myTableType;
insert @m values (1), (2)
exec sp_executesql
N'select 99 where 1 in (select id from @m)',
N'@m dbo.myTableType readonly',
@m
If you don't want to create a new type, you can use a #temp table:
declare @t table(id int);
insert @t values (1), (2);
select * into #t from @t;
exec sp_executesql N'select 99 where 1 in (select id from #t)';
How to pass a table variable using sp_executesql
Figured out the problem.
Apparently sp_executesql expects the parameter definition for a table to be of a table type (see this answer for an example: https://stackoverflow.com/a/4264553/21539).
An easier way to solve this problem was to insert the variables names directly into the SQLStatement string as follows:
DECLARE @SQLString NVARCHAR(MAX),
@TableName NVARCHAR(MAX);
SET @TableName = N'[dbo].[MyTable]';
SET @SQLString = N'SELECT * FROM ' + @TableName + ';';
SET @ParamDefinition = N'@_TableName NVARCHAR(max);
EXEC sp_executesql @SQLString;
How to use sp_execute passing table parameter
Typically you don't pass a table variable to execute SQL with sp_executesql. You make a statement up out of text and execute that. Like so:
IF OBJECT_ID('tempdb..#People') IS NOT NULL
DROP TABLE tempdb..#People
CREATE TABLE #People (PersonId INT IDENTITY, PersonName VARCHAR(128));
INSERT INTO #People (PersonName) VALUES ('Brett'), ('John'), ('Mark'), ('Shawn'), ('Ryan'), ('Kevin');
DECLARE @SQL NVARCHAR(Max) = 'Select * from #People'
EXEC sp_executesql @Sql
UPDATE 1-27-17
IF OBJECT_ID('tempdb..#People') IS NOT NULL DROP TABLE tempdb..#People
IF OBJECT_ID('tempdb..#People2') IS NOT NULL DROP TABLE tempdb..#People2
CREATE TABLE #People (PersonId INT IDENTITY, PersonName VARCHAR(128));
CREATE TABLE #People2 (PersonId INT IDENTITY(7,1), PersonName VARCHAR(128));
SET NOCOUNT ON;
INSERT INTO #People (PersonName) VALUES ('Brett'), ('John'), ('Mark'), ('Shawn'), ('Ryan'), ('Kevin');
INSERT INTO #People2 (PersonName) VALUES ('Emily'), ('Beth'), ('Jane'), ('Hannah');
--I. getting an output for a single output variable dynamically
--Say I just want to get Ryan by his Id dynamically and output it
--I need to define one or many parameters OUTSIDE the scope of the Dynamic Sql
DECLARE @Output VARCHAR(8)
DECLARE @PersonId INT = 5
--I then need to associate the parameters as an array, for the purposes of explanation I will use DIFFERENT NAMES you may use the same
DECLARE @ParmDefinition NVARCHAR(500) = N'@PersonIdInside Int, @OutputInside varchar(8) OUTPUT'
--I then use the names ABOVE in the dynamic sql
DECLARE @SQL NVARCHAR(Max) = N'Select @OutputInside = PersonName from #People Where PersonId = @PersonIdInside'
-- I then do the following AFTER the sp_executesql 1. The Dynamic sql nvarchar, 2. The params nvarchar 3. one or many variables and how they associate
EXEC sp_executesql @Sql, @ParmDefinition, @PersonIdInside = @PersonId, @OutputInside = @Output OUTPUT
-- I have an output so now it should show what I want
SELECT @Output
-- II. getting a result set dymamically to another record set or table OUTSIDE the scope of the internal
-- Create another table, I use a #table for example purposes
IF OBJECT_ID('tempdb..#Output') IS NOT NULL DROP TABLE tempdb..#Output
CREATE TABLE #Output (PersonId INT IDENTITY, PersonName VARCHAR(8))
--Get a truncated list for an 'in' statement later of person Id's in a variable
DECLARE @People NVarchar(32) = N'1, 5, 10'
--I then use the @People ABOVE in the dynamic sql putting it together and then do an 'insert statement first'
DECLARE @SQL2 NVARCHAR(Max) = N'Insert Into #Output SELECT PersonName FROM (SELECT * FROM #People UNION SELECT * FROM #People2) as x Where PersonId in (' + @People + ')'
--execute yields nothing
EXEC sp_executesql @Sql2
-- or does it?
Select *
From #Output
-- !!! WARNING !!!
-- With dynamic sql you cannot nest multiple dynamic sql statements inside of procs. EG: Proc1 cannot call Proc2 and both of them have dynamic sql in them. Engine limitation.
How to use table variable in dynamic sql? OR create temporary table from user defined table type?
I can think of the following workarounds to solve this using your UDTT:
1. Declare the UDTT variable within your dynamic script and then you can as well retrieve results from there:
EXECUTE SP_EXECUTESQL
N'
DECLARE @dynvariable [UDTT];
insert @dynvariable values (1);
select * from @dynvariable';
2. Pass the UDTT variable to the SP_EXECUTESQL
, but then it is readonly, meaning you can only select
within the dynamic script:
DECLARE @variable [UDTT];
insert @variable values (1);
EXECUTE SP_EXECUTESQL
N'select * from @dynvariable',
N'@dynvariable [UDTT] READONLY',
@dynvariable=@variable;
3. I think it's not possible to 'create a temp table from UDTT' so your approach would be to dynamically create the temp table using system information for your UDTT (columns, types, etc.).
4. Reading that you want to have a "dynamic" pivot code, the most appropriate would be to dynamically generate the pivot statement based on the columns info and values of the target table.
How to use table variable in a dynamic sql statement?
Your EXEC executes in a different context, therefore it is not aware of any variables that have been declared in your original context. You should be able to use a temp table instead of a table variable as shown in the simple demo below.
create table #t (id int)
declare @value nchar(1)
set @value = N'1'
declare @sql nvarchar(max)
set @sql = N'insert into #t (id) values (' + @value + N')'
exec (@sql)
select * from #t
drop table #t
How to use Table Variable in Dynamic Query
Try This :
CREATE TYPE IntegerTableType AS TABLE (ID INT);
go
DECLARE @TempVehicles IntegerTableType;
INSERT @TempVehicles
values (1);
DECLARE @SQL NVARCHAR(MAX);
SET @SQL ='SELECT *
FROM @TempVehicles;';
EXECUTE SP_EXECUTESQL @SQL,N'@TempVehicles IntegerTableType READONLY',
@TempVehicles;
sp_executesql and table output
Resolved, thanks to all for tips:
DECLARE @DBName varchar(255)
DECLARE @q varchar(max)
CREATE table #tempTable(myParam1 int, -- other params)
SET @DBName = 'my_db_name'
SET @q = 'insert into #tempTable exec ['+@DBName+'].[dbo].[my_procedure]'
EXEC(@q)
SELECT * FROM #tempTable
drop table #tempTable
Related Topics
SQL Ignore Part of Where If Parameter Is Null
How to Copy SQL Server 2008 R2 Database from One MAChine to Another
SQL Server Decimal(30,10) Losing Last 2 Decimals
SQL Find Difference Between Previous and Current Row
SQL Query of Haversine Formula in SQL Server
SQL Server Rounding Error, Giving Different Values
Perform Join Query in Google Cloud Firestore
How to Detect Query Which Holds the Lock in Postgres
How to Have Multiple "With As" in Single SQL - Oracle SQL
Best Practice on Users/Roles on SQL Server for a Web Application
SQL Statement Using Where Clause with Multiple Values
How to Get a Plain Text Postgres Database Dump on Heroku
Generate a Random Number in the Range 1 - 10
Sqlite - Replace Part of a String
Grant Privileges on Future Tables in Postgresql