Stored procedure with a parameter in FROM clause - sql

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

Related

How to write Select query with dynamic table name in Stored Procedure?

I am writing a stored-procedure. But the table name is dynamic in this procedure. I want to get row number from my variable table. But where will I set #rownumber with return of select query?
Create Proc update_eMail
(#tablename nvarchar(50),
#columnname nvarchar(50))
AS
Begin
Declare #q_getrowNumber NVARCHAR(MAX)
Declare #rownumber int
SELECT #rownumber = Count(ID) FROM quotename(#tablename) // doesnt work
END
Thanks in advance
Here is one way to achieve the goal using dynamic sql
declare #sql NVARCHAR(4000)= ''
set #sql = 'SELECT #rownumber = Count(ID) FROM '+ quotename(#tablename)
exec sp_executesql #sql, N'#rownumber int output',#rownumber output
You write wrong Procedure for dynamic query
Try This. It will Work.
ALTER PROC update_eMail(#tablename NVARCHAR(50))
AS
BEGIN
DECLARE #RowNumber NVARCHAR(MAX)=''
set #RowNumber='select Count(ID) FROM '+#tablename+''
exec(#RowNumber)
END
OR Try below Code in your Query
ALTER PROC update_eMail1
(
#tablename NVARCHAR(50)
)
AS
BEGIN
DECLARE #sql NVARCHAR(4000)= '',#rownumber INT
SET #sql = 'SELECT #rownumber = Count(ID) FROM '+quotename(#tablename)
EXEC sp_executesql #sql, N'#rownumber int output',#rownumber OUTPUT
SELECT #rownumber
END
This one will be easiest for you:
Create Proc update_eMail
#tablename nvarchar(50)
AS
Begin
EXEC ( 'SELECT Count(ID) FROM '+#tablename+'')
END

Dynamic SQL Result INTO #Temp Table

I have to Execute a dynamic SQL SELECT Query And put Results into a #TempTable.
DECLARE #StateId CHAR(3)='StateID';
DECLARE #DeptId CHAR(15)='DeptID';
DECLARE #Query VARCHAR(MAX)='Select Columns With Joins Passed From Front End'
DECLARE #Where VARCHAR(500);
DECLARE #FinalQuery VARCHAR(MAX)='';
SET #Where='Some Where Condition';
SET #FinalQuery='SELECT '+#Query+' '+#Where+''
EXEC(#FinalQuery) -- Want To INSERT THIS Result IN SOME `#TempTable`
-- SO that I can perform Some Operations On `#TempTable`
ALSO No Of columns returned From Dynamic SQL SELECT Are Dynamic.
Thanks,
try the below example
DECLARE #StateId CHAR(3)='StateID';
DECLARE #DeptId CHAR(15)='DeptID';
DECLARE #Query VARCHAR(MAX)='*' -- here you pass your query
DECLARE #Where VARCHAR(500);
DECLARE #FinalQuery VARCHAR(MAX)='';
SET #Where='from tablename where condition';
SET #FinalQuery='SELECT '+#Query+' INTO #temptablename '+#Where;
EXEC(#FinalQuery)
Note
:If you need to use temtable after sp execution then use ## rather than # then we can access it or we can use persistent temporary table
Please make sure that your query statements is correctly.
Try this in your stored procedure and check the output results ( copy the result and execute it)
....
SET #FinalQuery='SELECT '+#Query+' '+#Where+'
PRINT(#FinalQuery)
....
You can use the SQL Profiler tool to debug
Try this...
First create the temp table which you need for further calculation.
CREATE TABLE #TEMP
(
STATEID INT,
DEPTID INT
)
DECLARE #STATEID CHAR(10)='STATEID';
DECLARE #DEPTID CHAR(15)='DEPTID';
DECLARE #QUERY VARCHAR(MAX)='INSERT INTO #TEMP_TABLE
SELECT COLUMNS WITH JOINS PASSED FROM FRONT END'
DECLARE #WHERE VARCHAR(500);
DECLARE #FINALQUERY VARCHAR(MAX)=''
SET #WHERE='SOME WHERE CONDITION'
SET #FINALQUERY=+#QUERY+' '+#WHERE+'' -- REMOVED SELECT
EXEC(#FINALQUERY)

i want to pass a select query in a stored procedure as an argumnet

I made this procedure..
ALTER PROCEDURE [dbo].[MyProcedure]
#pSelect nvarchar
AS
BEGIN
SET NOCOUNT ON;
select #pSelect from tabel1
END
I want to pass a select query like from c# code to this stored procedure
MyProcedure("column1,column2");
How could I do this because stored procedure treat my parameter as a string and it behaves like
select N'column1,column2' from tabel1
pls help me
or provide a better option for this
You'll have to use dynamic sql inside the stored procedure.
ALTER PROCEDURE [dbo].[MyProcedure]
#pSelect nvarchar(max)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SQL nvarchar(max)
SET #SQL = 'select ' + #pSelect + ' from tabel1';
EXEC (#SQL)
END
Here's a script to test the above stored procedure:
CREATE TABLE tabel1 (id int, data varchar(50))
INSERT INTO tabel1 VALUES(1,'aaa'),(2,'bbb'),(3,'ccc')
EXEC [dbo].[MyProcedure] 'id'
EXEC [dbo].[MyProcedure] 'data'
EXEC [dbo].[MyProcedure] 'id,data'
You can use dynamic SQL for the purpose, but it is not recommended. (More info here - The Curse and Blessings of Dynamic SQL)
create procedure MyProcedure
#pSelect nvarchar
AS
begin
declare #sql nvarchar(4000);
set #sql='select ['+ #pSelect +'] from Table_1';
exec sp_executesql #sql
end
go
exec MyProcedure 'column1,column2'
go
If your #pSelect is having entire query then:
ALTER PROCEDURE [dbo].[MyProcedure]
#pSelect nvarchar
AS
BEGIN
SET NOCOUNT ON;
-- If you are#pSelect is having entire query
exec (#pSelect)
-- If you are passing only field list then following
DECLARE #SQL nvarchar(max)
SET #SQL = 'select ' + #pSelect + ' from tabel1';
END

sp_executesql and table output

I'm writing a stored procedure in SQL Server 2005, at given point I need to execute another stored procedure. This invocation is dynamic, and so i've used sp_executesql command as usual:
DECLARE #DBName varchar(255)
DECLARE #q varchar(max)
DECLARE #tempTable table(myParam1 int, -- other params)
SET #DBName = 'my_db_name'
SET q = 'insert into #tempTable exec ['+#DBName+'].[dbo].[my_procedure]'
EXEC sp_executesql #q, '#tempTable table OUTPUT', #tempTable OUTPUT
SELECT * FROM #tempTable
But I get this error:
Must declare the scalar variable "#tempTable".
As you can see that variable is declared. I've read the documentation and seems that only parameters allowed are text, ntext and image. How can I have what I need?
PS: I've found many tips for 2008 and further version, any for 2005.
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
SQL Server 2005 allows to use INSERT INTO EXEC operation (https://learn.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql?view=sqlallproducts-allversions).
You might create a table valued variable and insert result of stored procedure into this table:
DECLARE #tempTable table(myParam1 int, myParam2 int);
DECLARE #statement nvarchar(max) = 'SELECT 1,2';
INSERT INTO #tempTable EXEC sp_executesql #statement;
SELECT * FROM #tempTable;
Result:
myParam1 myParam2
----------- -----------
1 2
or you can use any other your own stored procedure:
DECLARE #tempTable table(myParam1 int, myParam2 int);
INSERT INTO #tempTable EXEC [dbo].[my_procedure];
SELECT * FROM #tempTable;
#tempTable's scope is limited to the current procedure.
You could replace the #tempTable with a global temporary table (i.e. ## table), but be very careful with the scope of that table and be sure to drop it when the procedure ends

Pass a TABLE variable to sp_executesql

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