Pass a variable into a stored procedures SELECT command [duplicate] - sql

This question already has answers here:
SQL: Select dynamic column name based on variable
(3 answers)
Closed 8 years ago.
I have a web page with a link to a stored procedure and I want to pass a variable to the stored procedures select statement. The code so far is -
ALTER procedure [dbo].[RTO]
#Weeknumber int,
#asset nvarchar(50)
AS
Begin
SELECT #asset
FROM RTO_weeklyanalysis
Where weekNumber = #weeknumber
END
basically the #asset will be the name of the column but this will change depending on what the user selects on the page.

You will need to use Dynamic sql for this. Also use QuoteName() function when concatenating object names to your sql query. and use system stored procedure sp_executesql to execute the dynamic query the most safe and secure way of executing dynamic sql. Something as follows :
ALTER procedure [dbo].[RTO]
#Weeknumber int,
#asset sysname
AS
Begin
SET NOCOUNT ON;
DECLARE #Sql NVARCHAR(MAX);
SET #Sql = N' SELECT '+ QUOTENAME(#asset) + '
FROM RTO_weeklyanalysis
Where weekNumber = #weeknumber'
EXECUTE sp_executesql #Sql
,N'#Weeknumber int'
,#Weeknumber
END

You cannot use a column name dynamicly in this way. The simplest way to achiewe what you want will be to exec whole query from temporary variable, i mean:
declare #query
set #query = 'SELECT ' + #asset ' FROM RTO_weeklyanalysis Where weekNumber = #weeknumber'
exec sp_executesql #query

Related

how to pass table name as parameter to sql table valued function?

I want to pass the table name as a parameter to table_valued function in MS SQL Server
CREATE FUNCTION maxid
(
-- Add the parameters for the function here
#tblname sysname,
#feild nvarchar(max),
)
RETURNS TABLE
AS
RETURN
(
-- Add the SELECT statement with parameter references here
select ISNULL(max(#feild),0)+1 from #tblname
)
You cannot use dynamic SQL in table valued or any other TSQL function. However, the code you provide seems to be used to obtain the next value of some identifier or counter field. The way you want to do it is highly deprecated and leads to concurrency problems.
Indeed, SQL Server can do it using at least two standard methods:
using a sequences
creating an identity column
I have done it but with store procedure
CREATE procedure [dbo].[get_maxid]
#tblname nvarchar(max),
#col nvarchar(max)
as
Begin
declare #sql nvarchar(max);
set #sql='select ISNULL(MAX('+#col+'),0)+1 as id from '+ QUOTENAME( #tblname)
execute sp_executesql #sql
End
Now Execute Store Procedure
exec get_maxid #col='col_name',#tblname='tbl_name'

Table name variable in MS SQL query

I have dynamically created tables, like XXX_JOURNAL.
Where XXX - is table prefix (variable), and _JOURNAL - is constant in table name.
I need create UPDATE trigger on database, not on particular table, and use table name (prefix) as variable:
CREATE TRIGGER triggerName ON %_JOURNAL
FOR UPDATE
AS
UPDATE XXX_JOURNAL
SET COMPANY_ID = LEFT(tableName,3) //tableName = current table (XXX_JOURNAL)
WHERE ID = ID FROM inserted
So here I have two difficulties:
How to create one trigger for all tables LIKE %_JOURNAL?
How to use table name as the keyword for current table?
I know there are a lot of mistakes in syntax. For example, I cannot use '%_JOURNAL' as table name on trigger creation. It's just for explanation, that I need create one trigger for all dynamically created tables in future.
Any ideas?
You can use stored procedure with dynamic SQL:
CREATE PROCEDURE TriggerCreationForJournals
#XXX as nvarchar(3)
AS
BEGIN
DECLARE #sql nvarchar(max),
#triggerName nvarchar(max) = #XXX + N'_JOURNAL_UPDATE',
#objectCheck int,
#checkSQL nvarchar(max),
#params nvarchar(max) = N'#objectCheck int OUTPUT'
SELECT #checkSQL = N'SELECT #objectCheck = OBJECT_ID(N'''+#triggerName+''')'
EXEC sp_executesql #checkSQL, #params, #objectCheck = #objectCheck OUTPUT
IF #objectCheck IS NULL
BEGIN
SELECT #sql = N'
CREATE TRIGGER '+QUOTENAME(#triggerName)+' ON ['+#XXX+'_JOURNAL]
FOR UPDATE
AS
UPDATE x
SET COMPANY_ID = '''+#XXX+'''
FROM ['+#XXX+'_JOURNAL] x
INNER JOIN inserted i
ON i.ID = x.ID'
EXEC sp_executesql #sql
END
ELSE
BEGIN
PRINT 'Trigger '+QUOTENAME(#triggerName)+' already exists'
END
END
Then run this:
DECLARE #sql nvarchar(max)
SELECT #sql = (
SELECT 'EXEC TriggerCreationForJournals '''+LEFT([name],3) +''';' +CHAR(10)
FROM sys.tables
WHERE [name] LIKE '%JOURNAL'
FOR XML PATH('')
)
EXEC sp_executesql #sql
To create triggers for all tables.
In #sql there will be query like:
EXEC TriggerCreationForJournals 'AFG';
EXEC TriggerCreationForJournals 'DFG';
The purpose of stored procedure is to check if trigger on table exists - if so skip its creation, you can modify the SP to drop them if exists.
The second part is a creation of script and running the SP for all tables you need.
Hope, this answer helps you with your questions.

Using a variable to name query results column

Is there a way to use a variable to name a column in SQL query results? My example below gives an "Incorrect syntax" error?
declare #ColumnName varchar(100) = 'Column 1'
Select CustomerNumber as #ColumnName
from Customers
Generally, SQL isn't going to handle defining variables to use as column aliases. This means you'll likely have to resort to using dynamic SQL, which involves building your query and then executing it manually via the sp_executesql procedure.
The following is an example of your existing query executed dynamically using SQL Server :
-- Define your variable
DECLARE #ColumnName VARCHAR(100) = 'Column 1'
-- Define your SQL query
DECLARE #SQL NVARCHAR(200) = 'SELECT CustomerNumber AS ' + #ColumnName + ' FROM Customers'
-- Execute your query dynamically
EXEC sp_executesql #SQL

Dynamically get all parameter values in stored procedure

Is there any way to get all parameter values from a stored procedure dynamically?
In other words, iterate through all parameters in one stored procedure to get their values into one string. This is for a unified logging process for a bunch of stored procedures.
I can get the names of parameters:
SELECT PARAMETER_NAME
FROM INFORMATION_SCHEMA.PARAMETER
WHERE SPECIFIC_NAME = 'procedure_name';
Also, I tried to use dynamic SQL commands. I've generated a command with included parameter, but EXEC can't execute command.
#cmd = 'SELECT '#UserID' + CONVERT(NVARCHAR(MAX), #UserID)
+ '#Date' + CONVERT(NVARCHAR(MAX), #Date)'
EXEC #cmd
Is there any way to do this besides manually generating a list of parameter values for each stored procedure?
Since SQL Server 2014 there is sys.dm_exec_input_buffer a table valued function with an output column event_info that gives the full execution statement (including parameters).
I use this for error logging in stored procedures.
For example:
--include this inside the stored procedure
declare #statement nvarchar(max)
select #statement = event_info
from sys.dm_exec_input_buffer(##spid, current_request_id())
--this will print whatever you called the procedure with (including parameters)
print #statement
-- if you want to parse just the parameters from the statement, it can be done like this
declare #proc_name varchar(128) = object_name(##procid)
declare #param_idx int = charindex(#proc_name, #statement) + len(#proc_name)
declare #param_len int = len(#statement) - #param_idx
declare #params nvarchar(max) = right(#statement, #param_len)
select #params

Execute sp_executesql, Table Variabe not Declared

I am Using SQL server 2012 and i want to select random columns from my table by applying where condition in this query:
EXECUTE sp_executesql
N'SELECT *
FROM #table
WHERE #Col = #Value',
N'#Value nvarchar(44),#table nvarchar(55),#Col nvarchar(30)',
#Value = 'Cus_1',#Col='CustId',#table='SaleOrder';
But when I execute it, it shows error
Must declare the table variable "#table"
I also tried it to declare by this: #table table(Id nvarchar(30)), but thin it shows again an error on table type...
Please help
This is what you are trying to run:
EXECUTE sp_executesql
N'SELECT * FROM #table WHERE #Col = #Value',
N'#Value nvarchar(44), #table nvarchar(55), #Col nvarchar(30)',
#Value = 'Cus_1', #Col='CustId', #table='SaleOrder';
Alas. You cannot substitute in a table name or column name using parameter substitution. So, SQL Server is looking for a table variable called #table. You can fix this by putting the values directly into the string:
declare #Col = 'CustId', #table = 'SaleOrder';
declare #sql nvarchar(max) = N'SELECT * FROM ' + #table + ' WHERE ' + #Col + ' = #Value';
EXECUTE sp_executesql #sql,
N'#Value nvarchar(44)',
#Value = 'Cus_1';
Unfortunately, I cannot find a good reference in the documentation that explains what is happening. When a statement is compiled, it is allowed to have parameters. However, the parameters are for values in the statement, not for column, table, database, or UDF names or for keywords. The statement itself is compiled, with place holders for the parameters, and in order to be compiled, the SQL engine needs to resolve all object names.