Get column value from string column name sql - sql

Is this possible to get multiple columns value when we have column name as string
Like if i have a table Test and i have columns FirstName , LastName , Address .
Now what i want to get value of all three columns but i want to make this dynamic so that i just pass string column name i get values for that columns
Example
Select
(select column_name from metadata )
from source table

Pass the column names as parameters
DECLARE #COLS NVARCHAR(MAX)
DECLARE #TABLE NVARCHAR(MAX)
SET #COLS = 'COL1,COL2'
SET #TABLE = 'TABLENAME'
Now execute the query
DECLARE #QRY NVARCHAR(MAX)
SET #QRY = 'SELECT (SELECT '+#COLS+' FROM '+#TABLE+') FROM sourcetable'
EXEC SP_EXECUTESQL #QRY

You can build the query in code dynamically. However it needs to be robust so that it does not gets prone to SQL injection. Something like this:
string commandString = "select {0} from SomeTable";
SqlCommand command = new SqlCommand();
command.CommandText = string.Format(commandString, "selected column names");
command.EndExecuteReader();
In SQL:
declare #query nvarchar(500)
set #query = replace('select 0 from author','0','column names from some parameter')
execute sp_executesql #query
Update 2: Does this do what you need?
declare #query nvarchar(500)
DECLARE #columnNames varchar(1000)
set #columnNames = ''
SELECT #columnNames = #columnNames + column_name + ',' FROM metadata
set #query = replace('select 0 from source_table','0',SUBSTRING(#columnNames,0,LEN(#columnNames)-1))
execute sp_executesql #query

Related

Passing a variable out of a SQL query

Is it possible to pass a variable out of a SQL query?
I am building up the initial query using a variable. I have added a simplified subset of my query below.
Thanks
declare #query Nvarchar(max)
declare #ColumnName Nvarchar(max)
set #ColumnName = 'MyColumn'
SET #query = 'Select ' + #ColumnName + ' from [MyTable] WHERE [MyCondition]'
EXECUTE sp_executesql #query
Can I return this result as a variable to pass to another query?
Yes. You use an output parameter:
declare #query Nvarchar(max);
declare #ColumnName Nvarchar(max);
declare #outval <type>; -- whatever type
set #ColumnName = 'MyColumn'
set #query = 'Select #outval =' + #ColumnName + ' from [MyTable] where [MyCondition]';
execut sp_executesql #query,
N'#outval <type> output',
#outval = #outval output;
Store the results in table variable and then convert it into XML.
Declare #xml XML
declare #query Nvarchar(max)
declare #ColumnName Nvarchar(max)
set #ColumnName = 'MyColumn'
declare #Table as TABLE(
MyColumn varchar(Max)-- Your Column datatype
)
SET #query = 'Select ' + #ColumnName + ' from [MyTable] WHERE [MyCondition]'
INSERT INTO #Table
EXECUTE sp_executesql #query
select #xml=MyColumn from #Table for XML PATH('')
How you want to pass returned result to other query?
What i can think of create a function return a table and call that function on other query:
CREATE FUNCTION test (#id int)
RETURNS #testTable TABLE(id int)
AS
begin
insert into #testTable select id from #your_table where id = #id
return
end
This will return a table you can check using :
select * from test(2); --will give you a table
If you want to use in a query:
`select * from #second_table where id in (select * from test2(#id parameter))` --- will filter query by id returned by function.

Substitute Column name in dynamic queries

I have a procedure , in which i am receiving a parameter column name and creating the dynamic query by substituting column name.
when i am directly running this dynamic query its working fine.
declare #a datetime,
#b varchar(50) ='CREATED_DATE',--column name
#query varchar(500);
select #a= CONVERT(datetime,LAST_RUN_PROC,121) from TEST_TABLE_MASTER
exec( 'select '+#b+' from TEST1 where '+#b+' = '+''''+#a+'''' )
But when i am storing query in a variable and then executing,its showing error.
Below code showing error
declare #a datetime,
#b varchar(50) ='CREATED_DATE',--column name
#query varchar(500);
select #a= CONVERT(datetime,LAST_RUN_PROC,121) from TEST_TABLE_MASTER
SET #query= 'select '+#b+' from TEST1 where '+#b+' = '+''''+#a+'''' --this line showing error Conversion failed when converting date and/or time from character string.
exec (#query)
I got stuck here.please help
Concatenating SQL string is not the best idea, because of multiple '''' needed. It is error-prone and hard to debug.
Use correct types (table name, column name) - SYSNAME, query -NVARCHAR(MAX).
You can use REPLACE placeholder to fill values or pass them as parameter to EXEC dbo.sp_executesql.
Always quote table/column names.
SELECT #a= CONVERT(datetime, LAST_RUN_PROC,121) FROM TEST_TABLE_MASTER; will set #a last read value from table, you should add TOP 1 and ORDER BY.
Code:
DECLARE #a DATETIME,
#b SYSNAME ='CREATED_DATE',
#query NVARCHAR(MAX);
SELECT #a= CONVERT(datetime, LAST_RUN_PROC,121) FROM TEST_TABLE_MASTER;
SET #query =
N'SELECT <col_name>
FROM TEST1
WHERE <col_name> = ''<col_value>'';';
SET #query = REPLACE(#query, '<col_name>', QUOTENAME(#b));
SET #query = REPLACE(#query, '<col_value>', #a);
--SELECT #query;
EXEC [dbo].[sp_executesql]
#query;
SqlFiddleDemo
Recommended version with parameter passing and dbo.sp_executesql instead of EXEC:
DECLARE #a DATETIME,
#b SYSNAME ='CREATED_DATE',
#query NVARCHAR(MAX);
SELECT #a= LAST_RUN_PROC FROM TEST_TABLE_MASTER;
SET #query =
N'SELECT <col_name>
FROM TEST1
WHERE <col_name> = #a;';
SET #query = REPLACE(#query, '<col_name>', QUOTENAME(#b));
EXEC [dbo].[sp_executesql]
#query
,N'#a DATETIME'
,#a;
SqlFiddleDemo2
Warning:
Using Dynamic-SQL is great resposibility. If you don't understand it, don't use Dynamic-SQL at all.
EDIT:
I've managed to run your example, but I strongly recommend to use one of the solution above:
SET #query= 'select '+#b+' from TEST1 where '+#b+' = '+''''+CONVERT(varchar(19),#a, 121)+''''
SqlFiddleDemo3

Select a column using a variable?

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)

Getting output in a variable from dynamic SQL

I am using a dynamic sql i.e.
DECLARE #searchstring VARCHAR(500)
DECLARE #str VARCHAR(MAX)
SELECT #str = 'SELECT * FROM Table1 WHERE ' + #searchstring
EXECUTE #str
What I need is I want to select one column value from above dynamic sql to pass in a different SP
Let's say I need ID column value and pass it to another sp named GetAnotherData #Ids. How can I do that?
well you can go with Alexander Fedorenko example, but if you don't want to create any temp tables, you can use output xml parameter to pass your ids:
declare #stmt nvarchar(max), #Data xml, #searchstring nvarchar(max)
select #stmt = '
select #Data = (
select id
from Table1
where ' + #searchstring + '
for xml raw(''Data'')
)
'
exec sp_executesql
#stmt = #stmt,
#params = N'#Data xml output',
#Data = #Data output
select
T.C.value('#id', 'int') as id
from #Data.nodes('Data') as T(C)
sql fiddle demo
The following example creates a user-defined table type that has one Id column. Further the INSERT #RetIds EXEC(#STR) statement fills the parameter list, and then passes the values to a stored procedure
CREATE TYPE RetIds AS TABLE
(
Id int
)
DECLARE #searchstring varchar(500) = 'AND SearchCol = 1'
DECLARE #str varchar(max)
SELECT #str ='SELECT Id FROM dbo.test6 WHERE 1 = 1 ' + #searchstring
DECLARE #RetIds AS RetIds
INSERT #RetIds
EXEC(#str)
EXEC dbo.ExecIds #RetIds
See demo on SQLFiddle

Dynamically Create Update SQL In Stored Procedure

I try to create a stored procedure to update a table record whose sql statement is dynamically created. I wrote some codes but am stoped in to run this query dynamically, How can i run this query or is there a better solution for this problem.
How this SP work?=> I send the columns names,values and datatype of the record that need update to SP like below
<e columnName=''PaymentStatus'' value=''99'' type=''nvarchar''/>
<e columnName=''HotelProvider'' value=''GAT2'' type=''nvarchar''/>
Then travel the nodes and create an Update statement, but can't execute it :))
I am giving a part of SP to understand the question better.
DECLARE #UpdateXml xml = '
<xml>
<e columnName=''PaymentStatus'' value=''99'' type=''nvarchar''/>
<e columnName=''HotelProvider'' value=''GAT2'' type=''nvarchar''/>
</xml>';
DROP TABLE ##UpdateFields
SELECT
t.c.value('#columnName', 'varchar(max)') AS ColumnName,
t.c.value('#value', 'varchar(max)') AS Value,
t.c.value('#property', 'varchar(max)') AS PropertyOf,
t.c.value('#type', 'varchar(max)') AS ColumnType
INTO ##UpdateFields
from #UpdateXml.nodes('/xml/e') as t(c)
DECLARE #SQL nvarchar(MAX) = 'UPDATE HotelBooking ';
DECLARE #SQLUpdatePart nvarchar(MAX);
SET #SQLUpdatePart = 'SET ';
SELECT #SQLUpdatePart= #SQLUpdatePart+ColumnName +'='+'#QP_'+ColumnName+',' FROM ##UpdateFields WHERE PropertyOf IS NULL;
DECLARE #SQLWherePart nvarchar(MAX);
SET #SQLWherePart = ' WHERE Id=2';
DECLARE #ParmDefinition nvarchar(MAX)='';
SELECT #ParmDefinition = #ParmDefinition+'#QP_'+ColumnName+' '+ColumnType+',' FROM ##UpdateFields;
SELECT #ParmDefinition
SELECT #SQL + #SQLUpdatePart + #SQLWHerePart;
Last two select statements results are:
#QP_PaymentStatus nvarchar,#QP_HotelProvider nvarchar,#QP_TransactionId uniqueidentifier,#QP_UpdatedDate datetime
and
UPDATE HotelBooking SET PaymentStatus=#QP_PaymentStatus,HotelProvider=#QP_HotelProvider,UpdatedDate=#QP_UpdatedDate,TransactionId=#QP_TransactionId WHERE Id=2
Now How can I give the #QP parameters to sp_executesql() method dynamically?
You can do it by wrapping sp_executesql call in another exec:
declare #updateStr nvarchar(1000)
-- #updateStr = N'select * from ATable where ID = #p1'
set #updateStr = N'N''select * from ATable where ID = #p1'''
declare #paramStr nvarchar(100)
-- #paramStr = N'#p1 int'
set #paramStr = N'N''#p1 int'''
declare #actualParameters nvarchar(100)
set #actualParameters = N'#p1 = 10'
-- Concatenate parts of query into a variable
declare #sql nvarchar(max)
set #sql = N'sp_executesql ' + #updateStr + ',' + #paramStr + ', ' + #actualParameters
-- And voila!
exec (#sql)