I am having problems running sql server stored procedure. I using a dynamic sql.
I get the error "Must declare the scalar variable "#EmployeeId".
SQL QUERY
ALTER PROCEDURE [dbo].[GetLeaveDays] -- Add the parameters for the stored
procedure here
#LeaveType varchar(5000),
#AdminId int,
#EmployeeId int
AS
BEGIN
SET NOCOUNT ON;
DECLARE
#queryString nvarchar(MAX);
SET #queryString = 'SELECT ' + #LeaveType + ' FROM CompulsoryLeave WHERE
AdminId = #AdminId AND Id=(SELECT LeaveStructureId FROM Employee WHERE
Id=#EmployeeId)';
EXECUTE sp_executesql #queryString,
N'#AdminId int',
N'#EmployeeId int',
#AdminId = #AdminId,
#EmployeeId=#EmployeeId
END
The second sp_executesql parameter should be a single string with all parameter definitions. Try:
EXECUTE sp_executesql #queryString,
N'#AdminId int, #EmployeeId int',
#AdminId = #AdminId,
#EmployeeId = #EmployeeId;
Related
I am trying to create views using stored procedure and passing dynamic SQL in SQL Server.
ALTER PROCEDURE sp_businessUnit_totalRequests
(#ViewName AS VARCHAR(50),
#RequiredBU AS VARCHAR(50))
AS
BEGIN
DECLARE #Req_View_Name AS SYSNAME;
DECLARE #sql NVARCHAR(MAX);
SET #Req_View_Name = #ViewName
SET #sql = '
CREATE VIEW [Req_View_Name]
As
BEGIN
Select [Reviewer], Count([Reviewer]) as Total_Requests From [dbo].[reviews_not_sent] where [BU] = #RequiredBU Group By [Reviewer];
END
'
SET #sql = REPLACE(#sql, '[Req_View_Name]', QUOTENAME(#Req_View_Name));
EXEC sp_executesql #sql,
N'#RequiredBU VARCHAR(50)',#RequiredBU=#RequiredBU
END;
EXEC sp_businessUnit_totalRequests 'Annuities_Requests', 'Annuities';
The stored procedure gets created. But when I tried to execute the stored procedure, it says:
Incorrect Syntax near View
This code should work:
ALTER PROCEDURE [dbo].[sp_businessUnit_totalRequests]
(
#ViewName AS VARCHAR(50),
#RequiredBU AS VARCHAR(50)
)
AS
BEGIN
Declare #Req_View_Name AS SYSNAME;
DECLARE #sql NVARCHAR(MAX);
Set #Req_View_Name = #ViewName
set #sql = '
CREATE VIEW [Req_View_Name]
As
Select [Reviewer], Count([Reviewer]) as Total_Requests From [dbo].[reviews_not_sent] where [BU] = ''' + #RequiredBU + ''' Group By [Reviewer];
'
SET #sql = REPLACE(#sql, '[Req_View_Name]', QUOTENAME(#Req_View_Name));
EXEC sp_executesql #sql
END;
This Code works although it suffers from SQL Injection. Parametrized SQL View creation is not possible.
CREATE PROCEDURE spCountTableRowWHere
#TblName VARCHAR(50),
#TblID VARCHAR(10) = 'Id',
#WhereClause NVARCHAR(500) = '1=1'
AS
BEGIN
DECLARE #Query NVARCHAR(500)
DECLARE #ParamDefinition NVARCHAR(40)
DECLARE #Count INT
SET #Query = 'SELECT #C = COUNT('+#TblID+') FROM '+#TblName+' WHERE '+#WhereClause
SET #ParamDefinition = '#C INT OUTPUT'
EXECUTE SP_EXECUTESQL #Query, #ParamDefinition, #C = #Count OUTPUT
SELECT #Count
END
I am wondering if this kind of procedure is better than a separate procedures for different tables.
The short answer is no.
The long answer is that it is an opening to sql injection attacks.
Think what will happen if someone will put the following string in your where clause argument: 1=1; drop table myTable.
I have a query which returns a single result.
#query='select name from studtable where id=1'
How should I write query so that result is saved in string and #result contains result.
#result=exec(#query)
To execute a string, we recommend that you use the sp_executesql stored procedure
instead of the EXECUTE statement. Because this stored procedure supports parameter
substitution, sp_executesql is more versatile than EXECUTE; and because
sp_executesql generates execution plans that are more likely to be reused by SQL
Server, sp_executesql is more efficient than EXECUTE.
Read more here:http://technet.microsoft.com/en-us/library/ms175170(v=sql.105).aspx
So you can write as"
DECLARE #SQLString NVARCHAR(500)
DECLARE #ParmDefinition NVARCHAR(500)
DECLARE #IntVariable INT
DECLARE #name varchar(30)
SET #SQLString = N'SELECT #nameOUT = name
from studtable where id=#id'
SET #ParmDefinition = N'#id tinyint,
#nameOUT varchar(30) OUTPUT'
SET #IntVariable = 1
EXECUTE sp_executesql
#SQLString,
#ParmDefinition,
#id = #IntVariable,
#nameOUT=#name OUTPUT
SELECT #name
You can do something like below to store the result using sp_executesql with output parameter. Observed from here Assign result of dynamic sql to variable
declare #ret int
set #ret = 0
set #query='select name from studtable where id=1'
exec sp_executesql #query, N'#var int out', #ret out
select #ret
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
I was reviewing a stored procedure where I found piece of code below. Looking at the code, my perception is that we are creating a variable named #QuestionInclude and passing its value in dynamic sql statement. But how this code is working?
This is something strage and new to me.
declare #QuestionInclude varchar(10)
select #sqln = 'select #QuestionInclude = 1 from ##Stg_Prelim'
exec sp_executesql #sqln,N'#QuestionInclude varchar(10) output',#QuestionInclude output
may be this will help you
http://msdn.microsoft.com/en-us/library/ms188001.aspx
procedure sp_executesql have parameters #stmt, which is actual statement to run, #params - declaration of parameters, and then all parameters declared in #params
It's also better to pass parameters by names
declare #QuestionInclude varchar(10), #stmt nvarchar(max), #params nvarchar(max)
select #stmt = 'select #QuestionInclude = 1 from ##Stg_Prelim'
select #params = '#QuestionInclude varchar(10) output'
exec sp_executesql
#stmt = #stmt,
#params = #params,
#QuestionInclude = #QuestionInclude output