I have a problem with that statement
SELECT GENDER
FROM tableName
WHERE (SELECT COL_NAME(OBJECT_ID('[tableName ]'), 5)) = 'M'
It should return all the GENDER from the table where the sex is equal to M
But it returns nothing!
This is the same select but with 'classical' parameters
SELECT GENDER
FROM tableName
WHERE GENDER = 'M'
I also tried using a variable, but with the same blank result!
DECLARE #var NVARCHAR(MAX)
SET #var = (select COL_NAME(OBJECT_ID('[MD_PRODUCT].[TABSOURCE]'), 5))
SELECT GENDER FROM MD_PRODUCT.TABSOURCE WHERE #var = 'M'
I need to use the COL_NAME (or in alternative the COLUMN_NAME of the INFORMATION_SCHEMA) because whole the parameters in the select are generated dynamically...
Can anyone help me?
Thank you
I'm working with SQL Server in SSMS
You seem to be looking for dynamic SQL. You need to prepare your query in a string and use EXEC() to run it.
Consider:
DECLARE #sqlCommand varchar(1000)
DECLARE #columnName varchar(75)
SET #columnName = 'foo'
SET #sqlCommand = 'SELECT GENDER FROM tableName WHERE ' + #columnName + ' = M'
EXEC (#sqlCommand)
Why in the world are you using COL_NAME here??? You should reference the column.
SELECT GENDER
FROM tableName
WHERE GENDER = 'M'
Thank You all i found the solution with the help of GMB answer.
Here is the correct code:
DECLARE #columnName varchar(75)
DECLARE #tableName varchar(75)
declare #sqlCommand varchar(75)
SET #columnName = (select COL_NAME(OBJECT_ID('tableName'), 1))
set #tableName = 'tableName'
SET #sqlCommand = 'SELECT ' +#columnName+ ' FROM ' +#tableName+ ' WHERE ' +#columnName+ ' = 1'
print #sqlCommand --just for print out the the sql command variable #sqlCommand
EXEC (#sqlCommand)
Related
I want to make a simple SQL query like:
SELECT * FROM table WHERE $variable_2 = $variable_1
instead of a default one:
SELECT * FROM table WHERE column_name = $variable_1
It seems like first example doesn't work at all. Is it even possible to modify SQL query syntax in such way?
as this reference answer for:
in link:
Use Variable as SQL column Name in query
answer1:
declare #ColumnName varchar(50)
declare #sql nvarchar(max)
set #ColumnName = 'SalesData_' + convert(varchar(2),datepart(dd,getdate()))
set #sql = 'select ' + #ColumnName + ' from SalesTable'
print #sql
EXEC sp_sqlexec #sql
answer 2:
declare #ColumnName varchar(50)
declare #sql nvarchar(max)
set #ColumnName = 'SalesData_' + convert(varchar(2),datepart(dd,getdate()))
set #sql = 'select ' + #ColumnName + ' from yourschema.SalesTable'
print #sql
I am trying to create optional parameters in a stored process in which I group by the parameters under certain conditions.
For example:
SELECT
TP.ProductID,
case
when #passangers='Y' then (TP.Passangersgroup)
when #fareclass='Y' then (TP.Fareclass)
when #ispriorbooking='Y' then (TP.IsPriorBooking)
end
INTO ##B
FROM ##A TP
GROUP BY
TP.ProductID,
case
when #passangers='Y' then (TP.Passangersgroup)
when #fareclass='Y' then (TP.Fareclass)
when #ispriorbooking='Y' then (TP.IsPriorBooking)
end
In this case, I would be able to select 'Y' for any of the 3 parameters, and I would want to add them to select statement and group by.
Any ideas?
You need to do this with dynamic SQL; something like:
declare #sql varchar(max) = 'SELECT
TP.ProductID, ' +
case when #passangers='Y' then 'TP.Passangersgroup'
when #fareclass='Y' then 'TP.Fareclass'
when #ispriorbooking='Y' then 'TP.IsPriorBooking'
else ''
end
+ ' INTO ##B
FROM ##A TP'
--ETC
Exec(#sql)
If you want to add up to all three columns, you need three case statements:
declare #sql varchar(max) = 'SELECT
TP.ProductID, ' +
case when #passangers='Y' then 'TP.Passangersgroup' else '' end
+ case when #fareclass='Y' then 'TP.Fareclass' else '' end
--ETC.
+ ' INTO ##B
FROM ##A TP'
Dynamic SQL will be the best bet, but I would figure out the column you want and then pass in the one column as a variable. Less likely to suffer SQL injection and more readable.
DECLARE #passangers CHAR(1), #fareclass CHAR(1), #ispriorbooking CHAR(1)
SET #passangers='Y'
DECLARE #SQLCMD NVARCHAR(MAX), #YValue NVARCHAR(1000)
--set the select and group by field
SELECT #YValue=
case
when #passangers='Y' then N'TP.Passangersgroup'
when #fareclass='Y' then N'TP.Fareclass'
when #ispriorbooking='Y' then N'TP.IsPriorBooking'
else NULL
end
IF #YValue IS NOT NULL
BEGIN
SET #SQLCMD=N'
SELECT
TP.ProductID,'+#YValue+'
INTO ##B
FROM ##A TP
GROUP BY
TP.ProductID, '+#YValue
PRINT #SQLCMD
--EXEC sp_executesql #SQLCMD
END
ELSE
PRINT 'INVALID PARAMETER PASSED IN'
You have to use dynamic sql but case statement mentioned in Steve Mangiameli code will not work in case when more than one column is selected as 'Y'. The below code will be working fine for multiple columns selected as 'Y'-
create procedure proc1
#passangers varchar(100) = null,
#fareclass varchar(100) = null,
#ispriorbooking varchar(100) = null
as
begin
declare #sql nvarchar(100)
declare #var varchar(100)
if #passangers = 'y'
set #var = tp.Passangersgroup + ', '
if #fareclass = 'y'
set #var = #var + TP.Fareclass + ', '
if #ispriorbooking = 'y'
set #var = #var + TP.IsPriorBooking
set #sql = 'select ' + #var + ' into ##b from ##a as TP group by ' + #var + 'option(recomplile)'
exec sp_executesql #sql
end
I was wondering if there is a way to select a column by using a SQL variable. Eg. Table is -
ID, Name, Address
DECLARE #Column varchar(25)
SET #Column = 'Name' -- This can be another column also
SELECT #Column
FROM MyTable
This shows me 'Name' as many times as there are rows in my table.
Is it even possible to do what I want ?
thanks.
Can do this with dynamic SQL:
DECLARE #Column varchar(25)
,#sql VARCHAR(MAX)
SET #Column = 'Name' -- This can be another column also
SET #sql = 'SELECT '+#Column+'
FROM MyTable
'
EXEC (#sql)
You can test your dynamic sql queries by changing EXEC to PRINT to make sure each of the resulting queries is what you'd expect.
You can use dynamic SQL for that:
DECLARE #Column nvarchar(25)
SET #Column = 'Name' -- This can be another column also
DECLARE #sql nvarchar(max) = N'SELECT ' + #Column + N' FROM MyTable'
exec(#sql)
Sql is currently interpreting your variable as a string.
From a previous answer on stack overflow:
DECLARE #Column varchar(25)
SET #Column = 'Name' -- This can be another column also
SET #sqlText = N'SELECT ' + #Column + ' FROM MyTable'
EXEC (#sqlText)
create procedure sp_First
#columnname varchar
AS
begin
select #columnname from Table_1
end
exec sp_First 'sname'
My requirement is to pass column names as input parameters.
I tried like that but it gave wrong output.
So Help me
You can do this in a couple of ways.
One, is to build up the query yourself and execute it.
SET #sql = 'SELECT ' + #columnName + ' FROM yourTable'
sp_executesql #sql
If you opt for that method, be very certain to santise your input. Even if you know your application will only give 'real' column names, what if some-one finds a crack in your security and is able to execute the SP directly? Then they can execute just about anything they like. With dynamic SQL, always, always, validate the parameters.
Alternatively, you can write a CASE statement...
SELECT
CASE #columnName
WHEN 'Col1' THEN Col1
WHEN 'Col2' THEN Col2
ELSE NULL
END as selectedColumn
FROM
yourTable
This is a bit more long winded, but a whole lot more secure.
No. That would just select the parameter value. You would need to use dynamic sql.
In your procedure you would have the following:
DECLARE #sql nvarchar(max) = 'SELECT ' + #columnname + ' FROM Table_1';
exec sp_executesql #sql, N''
Try using dynamic SQL:
create procedure sp_First #columnname varchar
AS
begin
declare #sql nvarchar(4000);
set #sql='select ['+#columnname+'] from Table_1';
exec sp_executesql #sql
end
go
exec sp_First 'sname'
go
This is not possible. Either use dynamic SQL (dangerous) or a gigantic case expression (slow).
Create PROCEDURE USP_S_NameAvilability
(#Value VARCHAR(50)=null,
#TableName VARCHAR(50)=null,
#ColumnName VARCHAR(50)=null)
AS
BEGIN
DECLARE #cmd AS NVARCHAR(max)
SET #Value = ''''+#Value+ ''''
SET #cmd = N'SELECT * FROM ' + #TableName + ' WHERE ' + #ColumnName + ' = ' + #Value
EXEC(#cmd)
END
As i have tried one the answer, it is getting executed successfully but while running its not giving correct output, the above works well
You can pass the column name but you cannot use it in a sql statemnt like
Select #Columnname From Table
One could build a dynamic sql string and execute it like EXEC (#SQL)
For more information see this answer on dynamic sql.
Dynamic SQL Pros and Cons
As mentioned by MatBailie
This is much more safe since it is not a dynamic query and ther are lesser chances of sql injection . I Added one situation where you even want the where clause to be dynamic . XX YY are Columns names
CREATE PROCEDURE [dbo].[DASH_getTP_under_TP]
(
#fromColumnName varchar(10) ,
#toColumnName varchar(10) ,
#ID varchar(10)
)
as
begin
-- this is the column required for where clause
declare #colname varchar(50)
set #colname=case #fromUserType
when 'XX' then 'XX'
when 'YY' then 'YY'
end
select SelectedColumnId from (
select
case #toColumnName
when 'XX' then tablename.XX
when 'YY' then tablename.YY
end as SelectedColumnId,
From tablename
where
(case #fromUserType
when 'XX' then XX
when 'YY' then YY
end)= ISNULL(#ID , #colname)
) as tbl1 group by SelectedColumnId
end
First Run;
CREATE PROCEDURE sp_First #columnname NVARCHAR(128)--128 = SQL Server Maximum Column Name Length
AS
BEGIN
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT ' + #columnname + ' FROM Table_1'
EXEC(#query)
END
Second Run;
EXEC sp_First 'COLUMN_Name'
Please Try with this.
I hope it will work for you.
Create Procedure Test
(
#Table VARCHAR(500),
#Column VARCHAR(100),
#Value VARCHAR(300)
)
AS
BEGIN
DECLARE #sql nvarchar(1000)
SET #sql = 'SELECT * FROM ' + #Table + ' WHERE ' + #Column + ' = ' + #Value
--SELECT #sql
exec (#sql)
END
-----execution----
/** Exec Test Products,IsDeposit,1 **/
SQL 2008
Hello,
I have a rather different task I have to do in SQL. It's a bit more involved than this, but I'm going to try to make it simple.
I need to somehow SELECT a column dynamically. Like this:
declare #ColName varchar(50)
select #ColName = 'Column1' --This is an actual column name in a real table called 'MyTable'
select #ColName from MyTable where Column2 = 123
Is there a way to do something like this? Any help or direction would be greatly appreciated!
Thanks,
Jason
you need dynamic SQL, but first read The Curse and Blessings of Dynamic SQL to make sure you don't open yourself up for SQL Injection
DECLARE #colNameIn AS varchar(50) = 'Column1'
DECLARE #template AS varchar(MAX) = 'select {#ColName} from MyTable where Column2 = 123' -- This template can be expanded
-- Protect yourself from injection or invalid columns:
DECLARE #ColName AS varchar(50)
SELECT #ColName = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MyTable'
AND COLUMN_NAME = #ColNameIn
IF #ColName IS NOT NULL
BEGIN
DECLARE #sql AS varchar(MAX)
SET #sql = REPLACE(#template, '{#ColName}', QUOTENAME(#ColName))
EXEC (#sql)
END
Read the link in #SQLMenace answer!
declare #ColName varchar(50)
select #ColName = 'Column1'
declare #sql varchar(MAX)
select #sql = 'select ' + #ColName + ' MyTable where Column2 = 123'
exec (#sql)
You can do this as using a CASE statement if you have predefined all of the acceptable column names in the procedure.
DECLARE #ColName varchar(50)
SET #ColName = 'Column1'
SELECT CASE #ColName
WHEN 'Column1' THEN Column1
WHEN 'Column2' THEN Column2
END
FROM MyTable
WHERE Column2 = 123