I'm looking for way to read data from user define type variable and when I do that:
I get this error:
Must declare the scalar variable "#mytabe".
Code:
CREATE TYPE CD_info AS TABLE
(
sestem_id nvarchar(10),
national_id nvarchar(14),
employee_name nvarchar(80),
salary money,
department nvarchar(80)
)
CREATE PROCEDURE Insert_CDInfo
#mytabe CD_info READONLY ,
#monthes int,
#TBname NVARCHAR(50)
AS
BEGIN
DECLARE #insertSql VARCHAR(MAX) = 'insert into' + #TBname +'(sestem_id, national_id,employee_name,salary,department)'+
'select top (1000000) sestem_id,national_id,employee_name,salary,department from '+ [#mytabe]
EXEC #insertSql
END
Thanks
The table valued parameter is only available in the scope in which it is declared so you cannot use it within the dynamic SQL EXECUTE statement.
Instead of EXECUTE, use a parameterized SQL statement and execute with sp_executesql. This will allow you to pass the TVP to the inner scope of the dynamic SQL as a parameter. For example:
CREATE PROCEDURE Insert_CDInfo
#mytabe CD_info READONLY ,
#monthes int,
#TBname NVARCHAR(50)
AS
BEGIN
DECLARE #insertSql nvarchar(MAX) =
N'INSERT INTO ' + QUOTENAME(#TBname) +' (sestem_id, national_id,employee_name,salary,department) '
+ N'SELECT TOP (1000000) sestem_id,national_id,employee_name,salary,department FROM #mytabe;';
EXEC sp_executesql
#insertSql
, N'#mytabe CD_info READONLY'
, #mytabe = #mytabe;
END
GO
Related
I need to execute below query
SELECT *, IDENTITY( int ) AS IDColumn INTO #SmootheningTable FROM #TableName
where #SmootheningTable is temporary table
and #TableName is name of table
I need to use command either EXEC or sp_executesql to execute.
If I use EXEC, I wont be able to use #SmootheningTable in later portion of my stored procedure.
And while trying sp_executesql, I am getting error stating #statement error.
How can I use sp_executesql for above given query.
Or is there any other way to execute?
this is the query I am using
DECLARE #TablePlaceHolder VARCHAR(50)='';
DECLARE #SmootheningQuery NVARCHAR(max) = 'SELECT *, IDENTITY( int ) AS IDColumn INTO #SmootheningTable FROM #TablePlaceHolder';
EXEC sp_executesql #SmootheningQuery, N'#TablePlaceHolder varchar(50)', #PlanDetailTempTableName
and i am getting below error
Must declare the table variable "#TablePlaceHolder".
Thanks in advance
There are two issues in your code:-
First : Putting the variable name inside the string, put in out like next:-
instead of this line:-
DECLARE #SmootheningQuery NVARCHAR(max) = 'SELECT *, IDENTITY( int ) AS
IDColumn INTO #SmootheningTable FROM #TablePlaceHolder';
Type this line:-
DECLARE #SmootheningQuery NVARCHAR(max) = 'SELECT *, IDENTITY( int ) AS
IDColumn INTO #SmootheningTable FROM ' + #TablePlaceHolder;
Second: Don't use local temp table within sp_executeSql,
The Local temporary table [with one hash # ] is visible in current session only, use global temporary tables instead [with two hashes ## ] are visible in all sessions,
So instead of
#SmootheningTable
Type
##SmootheningTable
Demo (All Code): -
Create table MyTable (id int , name nvarchar(100))
go
insert into MyTable values (1, 'Ahmed');
insert into MyTable values (2, 'Abdelqader');
go
declare
#TableName varchar(50),
#MyQuery nvarchar(200)
set #TableName = 'MyTable'
set #MyQuery = 'select * Into ##MYTempTable From ' + #TableName
exec sp_executesql #MyQuery
select * from ##MYTempTable
Result:-
id name
1 Ahmed
2 Abdelqader
Please Try This,
CREATE PROC usp_SmootheningTable
AS
BEGIN
SELECT *, IDENTITY( int ) AS IDColumn INTO #SmootheningTable FROM
TableName
SELECT * FROM #SmootheningTable
END
GO
Please try this out
CREATE TABLE #Temp
(
Columns
)
DECLARE #SQL NVARCHAR(MAX)
DECLARE #TableName VARCHAR(MAX)
SET #TableName = 'TableName'
SET #SQL = 'SELECT TOP 10 * FROM '+#TableName
INSERT INTO #Temp
EXEC SP_EXECUTESQL #SQL
SELECT * FROM #Temp
Is it possible to create a stored procedure that uses a parameter in the FROM clause?
For example:
CREATE PROCEDURE [dbo].[GetMaxId]
#id varchar(50)
#table varchar(50)
AS
BEGIN
SELECT MAX(#id)
FROM #table
END
You cannot pass identifiers as parameters into a query (neither table names nor column names). The solution is to use dynamic SQL. Your syntax suggests SQL Server, so this would look like:
CREATE PROCEDURE [dbo].[GetMaxId] (
#id varchar(50)
#table varchar(50)
)
AS
BEGIN
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'SELECT MAX(#id) FROM #table';
SET #sql = REPLACE(REPLACE(#sql, '#id', QUOTENAME(#id)), '#table', QUOTENAME(#table));
EXEC sp_executesql #sql;
END; -- GetMaxId
How can I pass temp table (#table) to EXEC sp_executesql #query
set #query = 'SELECT GsName, ' + #cols + ' from
(
select GSName, [THour], NumOfTransactions
from #table
) x
pivot
(
max([NumOfTransactions])
for [THour] in (' + #cols + ')
) p '
What you have here is not Temporary Table, but a Table-Valued Parameter.
Table-valued parameters are declared by using user-defined table
types. You can use table-valued parameters to send multiple rows of
data to a Transact-SQL statement or a routine, such as a stored
procedure or function, without creating a temporary table or many
parameters.
sp_executesql does support table-valued parameters, but they must be of declared type.
-- So, first we must declare User-Defined Table Type
CREATE TYPE udtYB_Test AS TABLE(GSName nvarchar(100), THour time, NumOfTransactions int);
GO
-- Now we can create Table-Valued Parameter
Declare #table udtYB_Test;
-- And store there some data
Insert Into #table (GSName, THour, NumOfTransactions)
Values ('Sample', SYSUTCDATETIME(), 1);
-- Just for the reference
Select * From #table;
-- To pass variable to sp_executesql we need parameters definition
DECLARE #ParmDefinition nvarchar(500) = N'#table udtYB_Test READONLY';
-- Please note: table-valued parameter must be READONLY
-- Here I use simplified query for demonstration only
DECLARE #query nvarchar(500) = 'SELECT * FROM #table';
-- and the result should be identical to the reference above
EXECUTE sp_executesql #query, #ParmDefinition, #table = #table;
-- User-Defined Table Type cleanup
DROP TYPE udtYB_Test;
GO
In most practical cases it is much easier to use a temporary table:
Create Table #table (GSName nvarchar(100), THour time, NumOfTransactions int);
Insert Into #table (GSName, THour, NumOfTransactions) Values ('Sample', SYSUTCDATETIME(), 1);
Select * From #table;
DECLARE #query nvarchar(500) = 'SELECT * FROM #table';
EXECUTE sp_executesql #query;
Drop Table #table;
I have the following query :
ALTER procedure [dbo].[jk_insertAllLocation]
#locationTbl as locationTable readonly,
#TableName varchar(100)
as
declare #tbl as locationTable,#sql varchar(max)
begin
set #sql = 'insert into ' + #TableName +'(location_id,name,address,latitude,longitude,distance,state,sub_cat,id_cat,icon_link,checkinsCount,IDSearch)
select * from ' + #locationTbl
exec sp_executesql #sql
end
I need to pass a table and a table name as parameter and I need to insert in the table name (#TableName) passed as parameter all the data in the table (#locationTbl) passed as parameter
but I know that I cannot concatenate the table (#locationTbl) in the query ...
so how can I fix this?
You can use temp tables (Temporary tables section on link):
ALTER procedure [dbo].[jk_insertAllLocation]
#locationTbl as locationTable readonly,
#TableName varchar(100)
as
begin
declare #tbl as locationTable,#sql varchar(max)
if object_id('#_tmp_location_table') is not null drop table #_tmp_location_table
select * into #_tmp_location_table from #locationTbl
set #sql = 'insert into ' + #TableName + '(location_id,name,address,latitude,longitude,distance,state,sub_cat,id_cat,icon_link,checkinsCount,IDSearch) select * from #_tmp_location_table'
exec sp_executesql #sql
end
I'm trying to pass a TABLE variable to the sp_executesql procedure:
DECLARE #params NVARCHAR(MAX)
SET #params = '#workingData TABLE ( col1 VARCHAR(20),
col2 VARCHAR(50) )'
EXEC sp_executesql #sql, #params, #workingData
I get the error:
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'TABLE'.
I tried omitting the column specification after 'TABLE'. I also tried to declare the table as a variable inside the dynamic SQL. But no luck...
Seems to me that TABLE variables aren't allowed to be passed as parameters in this procedure?. BTW: I'm running MSSQL2008 R2.
I'm not interested in using a local temp table like #workingData because I load the working data from another procedure:
INSERT INTO #workingData
EXEC myProc #param1, #param2
Which I cannot do directly into a temp varaible (right?)...
Any help appreciated!
If you are using SQL Server 2008, to pass a table variable to a stored procedure you must first define the table type, e.g.:
CREATE TYPE SalesHistoryTableType AS TABLE
(
[Product] [varchar](10) NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL
)
GO
or use an existing table type stored in the database.
Use this query to locate existing table types
SELECT * FROM sys.table_types
To use in an stored procedure, declare an input variable to be the table:
CREATE PROCEDURE usp_myproc
(
#TableVariable SalesHistoryTableType READONLY
)
AS BEGIN
--Do stuff
END
GO
Populate the table variable before passing to the stored procedure:
DECLARE #DataTable AS SalesHistoryTableType
INSERT INTO #DataTable
SELECT * FROM (Some data)
Call the stored procedure:
EXECUTE usp_myproc
#TableVariable = #DataTable
Further discussions here.
OK, this will get me what I want, but surely isn't pretty:
DECLARE #workingData TABLE ( col1 VARCHAR(20),
col2 VARCHAR(20) )
INSERT INTO #workingData
EXEC myProc
/* Unfortunately table variables are outside scope
for the dynamic SQL later run. We copy the
table to a temp table.
The table variable is needed to extract data directly
from the strored procedure call above...
*/
SELECT *
INTO #workingData
FROM #workingData
DECLARE #sql NVARCHAR(MAX)
SET #sql = 'SELECT * FROM #workingData'
EXEC sp_executesql #sql
There must be a better way to pass this temporary resultset into sp_executesql!?
Regards
Alex
While this may not directly answer your question, it should solve your issue overall.
You can indeed capture the results of a Stored Procedure execution into a temporary table:
INSERT INTO #workingData
EXEC myProc
So change your code to look like the following:
CREATE TABLE #workingData ( col1 VARCHAR(20),
col2 VARCHAR(20) )
INSERT INTO #workingData
EXEC myProc
DECLARE #sql NVARCHAR(MAX)
SET #sql = 'SELECT * FROM #workingData'
EXEC sp_executesql #sql
Regards,
Tim
Alter PROCEDURE sp_table_getcount
#tblname nvarchar(50) ,
#totalrow int output
AS
BEGIN
Declare #params nvarchar(1000)
Declare #sql nvarchar(1000)
set #sql = N'Select #cnt= count(*) From #tbl'
set #params = N'#tbl nvarchar(50) , #cnt int OUTPUT'
Exec sp_executesql #sql , #params ,#tbl=#tblname , #cnt = #totalrow OUTPUT
END
GO
Please note that the above code will not work as table as a object is out of the scope.It will give you the error: must declare table variable.In order to work around we can do the following.
Alter PROCEDURE sp_table_getcount
#tblname nvarchar(50) ,
#totalrow int output
AS
BEGIN
Declare #params nvarchar(1000)
Declare #sql nvarchar(1000)
set #sql = N'Select #cnt= count(*) From dbo.' + #tblname
set #params = N'#cnt int OUTPUT'
Exec sp_executesql #sql , #params , #cnt = #totalrow OUTPUT
END
GO
So-called TableType is tricky. #Alex version should work. However, to simplify and faster performance, go check sys.tables for matching table name while not compromise security and performance.
Here it is
create proc [dbo].Test11
#t1 AS nvarchar(250), #t2 nvarchar(250)
AS
BEGIN
SET nocount ON;
DECLARE #query AS nvarchar(MAX)
if exists (select * from sys.tables where name = #t1) and
exists (select * from sys.tables where name = #t2)
begin
SET #query = N'select * FROM '+ #t1 + N' join ' + #t2 + N' ON ...' ;
select 'Safe and fast'
print #query
exec sp_executesql #query
end
else
select 'Bad, no way Jose.'
SET nocount OFF;
END
GO