Stored procedure with table name as parameter - sql-server-2008

I have a stored procedure, and I would like to assign the number of rows of that table to a variable and later use that variable.
I am calling the procedure like:
EXEC TEST.dbo.myProc nameOfTable
The procedure is something like:
CREATE PROCEDURE myProc #table_name varchar(1024) AS
BEGIN
DECLARE #Nval INT
/* SOME INSTRUCTIONS */
SELECT #Nval = COUNT(*) FROM #table_name
END
When executing I am getting an error:
Msg 156, Level 15, State 1, Procedure nLQ, Line 57
Incorrect syntax near the keyword 'FROM'.
How would I assign the variable #Nval?

You can't parameterise a table name like that, FROM #table_name. Only way is to execute dynamic TSQL.
Before you do that, read: The Curse and Blessings of Dynamic SQL

try this
ALTER PROCEDURE [dbo].[sp_tablenametest]
#table_name varchar(50),
#PMId int,
#ValueEq int
AS
BEGIN
SET NOCOUNT ON;
DECLARE #cmd AS NVARCHAR(max)
SET #cmd = N'SELECT * FROM ' + #table_name +
' WHERE Column1 = ''' + #PMId + '''' +
' AND Column2= ''' + #ValueEq + ''''
EXEC sp_executesql #cmd
END

Related

Store a table column name as variable in sql server

I have a sql server stored procedure where I want the table column name to be stored as variable.But I am finding it difficult.
CODE
ALTER PROCEDURE [dbo].[GetLeaveDays]
-- Add the parameters for the stored procedure here
#LeaveType varchar,#AdminId int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT #LeaveType FROM CompulsoryLeave WHERE AdminId =#AdminId
END
Where the #Leavetype is the name of the table column.
EDIT
This is how I execute the stored procedure
GetLeaveDays 'Maternity',1
Use dynamic SQL as suggested. In your case you could use the following T-SQL.
You can read docs for dynamic SQL at Dynamic SQL in SQL Server
Keep in mind to always use sp_executesql to execute your dynamically formed queries since it's more secure that using EXEC (#query).
DECLARE #queryString nvarchar(MAX);
SET #queryString = 'SELECT ' + #LeaveType + ' WHERE AdminId = #AdminId';
EXECUTE sp_executesql #queryString,
N'#AdminId int',
#AdminId = #AdminId;
Using the above approach, your stored procedure would now look like the following.
ALTER PROCEDURE [dbo].[GetLeaveDays] -- Add the parameters for the stored procedure here
#LeaveType varchar(5000),
#AdminId int
AS
BEGIN
SET NOCOUNT ON;
DECLARE #queryString nvarchar(MAX);
SET #queryString = 'SELECT ' + #LeaveType + 'FROM CompulsoryLeave WHERE AdminId = #AdminId';
EXECUTE sp_executesql #queryString,
N'#AdminId int',
#AdminId = #AdminId;
END
you can use sp_executesql command for this purpose. You can read this Article to get a nice review on dynamic SQL.
DECLARE #sqlCommand nvarchar(max);
SET #sqlCommand = 'SELECT ' + #LeaveType + ' FROM CompulsoryLeave WHERE AdminId = '''+#AdminId+''''
EXECUTE sp_executesql #sqlCommand, N'#AdminId int', #AdminId = #AdminId;

How to Update values in sql by Muliple Column name in Sql

I want add values to multiple columns
ALTER PROCEDURE DynamicInsertQuery
#ColumnName VARCHAR(MAX),
#RiD VARCHAR(50)
AS
BEGIN
DECLARE #DynamicQuery NVARCHAR(MAX)
SET #DynamicQuery = 'UPDATE tbl_route_info SET ('+ #ColumnName +') = (1) WHERE RouteId=('+#RiD+')'
EXEC(#DynamicQuery)
END
This is the code I tried.
I run this procedure like this
DynamicInsertQuery '(1,2)','10'
I suspect you want something like this:
ALTER PROCEDURE DynamicInsertQuery (
#ColumnName VARCHAR(MAX),
#RiD VARCHAR(50)
) AS
BEGIN
DECLARE #DynamicQuery NVARCHAR(MAX);
SET #DynamicQuery = 'update tbl_route_into set #ColumnName = 1 where RouteId = #RiD';
SET #DynamicQuery = REPLACE(#DynamicQuery, '#ColumnName', #ColumnName);
EXEC sp_executesql #DynamicQuery, N'#RiD VARCHAR(50)', #RiD = #RiD;
END;
Notes:
You have too many parentheses in your version.
If you are learning to use dynamic SQL, then learn sp_executesql -- and how to use it to pass parameters.
You cannot pass names of things (columns, tables, etc.) as parameters, so that has to be placed directly in the string.
You can pass values into the string, such as #RiD.

the name is not a valid identifier error in function

Create FUNCTION [dbo].[fngetname]
(
#OrganisationID int=null,
#UserID int=null,
#ClientTypeID int
)
RETURNS varchar(500)
BEGIN
DECLARE #Name VARCHAR(500)
DECLARE #dbName VARCHAR(500)
set #dbName=(select ClientDataBase from dbo.ClientType where ClientTypeID=#ClientTypeID)
begin
set #Name='select UserName from ['+ #dbName+'].dbo.Users where UserID='+convert(varchar,#UserID)
exec #Name
end
return #Name
end
There are two issues here, first if you want to execute dynamic sql, you need to encapsulate your statement variable in parenthesises:
you need to add parenthesises to the exec #Name in your function declaration.
The function gets written but cannot execute it stops at the exec
replace that exec #Name with exec (#Name)
you can easily reproduce this error by just trying two simple lines (ofc replace the table and db-name with something you have ;)):
DECLARE #statement VARCHAR(MAX) = 'SELECT * FROM [nana].dbo.Fruits'
exec #statement
This should throw the exact same error.
Then add () around the #statement and it will work.
The second issue is, that you cannot use dynamic sql in a function, because they have to be deterministic (look here).
To get around this, rewrite that function behaviour into a stored procedure and then it should work ;).
One way to rewrite your function into a procedure might look like this(untested, because I do not have your database structure set up):
CREATE PROCEDURE spGetName #OrganisationID INT = NULL, #UserID INT = NULL, #ClientTypeID INT
AS
BEGIN
DECLARE #Name VARCHAR(500)
DECLARE #dbName VARCHAR(500)
SET #dbName = (SELECT ClientDataBase FROM dbo.ClientType WHERE ClientTypeID = #ClientTypeID)
SET #Name = 'select UserName from [' + #dbName + '].dbo.Users where UserID=' + CONVERT(VARCHAR, #UserID)
exec(#Name)
END
GO
Try using
exec sp_executesql #statement

When getting maxid from table name

Declare #Id bigint
EXEC procGetMaxNumber #Id output,'employee'
I'm getting an error message
Error converting data type varchar to bigint
when I execute the procedure with the above parameters
-- =============================================
-- Description: <Fetches Max Id for a particular table>
-- =============================================
CREATE PROCEDURE [dbo].[procGetMaxNumber]
(
#Id BIGINT OUTPUT,
#TblName nvarchar(50)
)
AS
BEGIN
SET NOCOUNT ON;
Declare #Query nvarchar(max) = ''
set #Query = 'SELECT ' + #Id + ' = isnull(Max(Id),0)+ 1 from ' + #TblName
--print #Query
Exec (#Query)
END
This looks extremely dangerous to me. What exactly are you going to do with the "next" Id value once you get it? You know that immediately after you retrieve this value, someone could insert a row and take it (or even fail to insert a row, and still take it even if the transaction rolled back), right? If you want to reserve an Id value and be sure that is the number you get, just run the insert, don't do any of this max+1 to insert later.
Anyway you can't use EXEC to retrieve an output parameter from dynamic SQL, you'll need to use sp_executesql:
DECLARE #query NVARCHAR(MAX) = N'SELECT #Id = COALESCE(MAX(Id),0)+1
FROM dbo.' + QUOTENAME(#TblName) + ';';
EXEC sp_executesql #query, N'#Id INT OUTPUT', #Id OUTPUT;

Column name set in stored procedure but not working

Column name set in stored procedure but not working. But when I run this script empty rows appears. What I do this for run this script?
Create Procedure Test
()
AS
BEGIN
Declare #columnName nvarchar(50);
set #columnName ='StoreName';
SELECT *
FROM testtable
WHERE #columnName = 'storemanager'
END
You need to use dynamic SQL because you can't reference a column with a variable - T-SQL just doesn't parse things in that order. Try something like:
CREATE PROCEDURE dbo.Test
#columnName NVARCHAR(50),
#value NVARCHAR(4000)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'SELECT * FROM dbo.testtable WHERE '
+ QUOTENAME(#columnName) + ' = #value;';
EXEC sp_executesql #sql, N'#value NVARCHAR(4000)', #value;
END
GO
QUOTENAME() wraps the column in [square brackets] and hopefully protects you from SQL injection. You should also read these posts:
Bad habits to kick : using SELECT * / omitting the column list
Bad habits to kick : avoiding the schema prefix
My stored procedure "best practices" checklist