Use dynamic column name in where clause without executing a variable - sql

I use SQL Server and have the following query:
declare #variable nvarchar(max)
set #variable = 'Fixed_Assets'
declare #sql nvarchar(max)
set #sql = 'Select ' + #variable + ' from table where ' + #variable + '= 1 '
But how could I still use #variable as a value and not a column name?
I want to add a column (Name) and then with the constant value of Fixed Assets

You can't directly insert a variable as a column name into a command, but you can create a command as a nvarchar, concat another variable into it (in your case the column name), then use Exec() to run it.
DECLARE #variable varchar(10)
SET #variable = 'YourColumn'
DECLARE #sqlCommandText nvarchar(1000);
SET #sqlCommandText = N'select * from table where ' + #variable + ' = ''1'''
Exec (#sqlCommandText)
Don't forget if you have a single quote inside a string in sql you need to escape them by doubling them up.

Related

how to add custom column in SQL string query with variable

I am using string query in sql and executing it with Execute method. I have to add an additional column with default value. that default value is contained in a variable. When i add that default valued column in the query string and execute it I get an error "Invalid column name 'dafaultValue' ".
Is there any other solution to do this ?
Here is my code:
Declare #variable Varchar(Max);
Declare #variableQuery Varchar(Max);
set #variable = 'Test';
set #variableQuery = 'select '+#variable+' as dest ,* from myTable ';
execute (#variableQuery);
Your issue is that you need to contain the variable in single quotes:
set #variableQuery = 'select '+ ''''+#variable+'''' +' as dest ,* from myTable';
Otherwise it thinks it is a column name in the table, which it isn't, hence the error.
I would strongly encourage you to learn to use sp_executesql and pass in parameters. This is much safer than munging query strings:
Declare #variable Varchar(Max);
Declare #variableQuery Varchar(Max);
set #variable = 'Test';
set #variableQuery = 'select #variable as dest, t.* from myTable t';
exec sp_executesql #variableQuery,
N'#variable varchar(max)',
#variable = #variable;
This method also allows you to pass values back from the query, so for processing queries, it is more powerful than exec.
The query variable would often be declared to be nvarchar(), just to be as general as possible.

Adding a table variable in Dynamic SQL

I am a beginner in Dynamic SQL and trying to write a dynamic sql code in which I need to include a table variable .When I try to include the table variable I am getting an error saying that I need to include the Static variable.
Below is just part of the code
DECLARE #NAMES TABLE (name varchar)
DECLARE #fields varchar(max);
.
.
.
Select #fields=FROM sys.columns
WHERE object_id=object_id('dbo.employees')
order by name
SET #SQL=''
SET #SQL='Select '+ #fields
SET #SQL=#SQL + ' from dbo.test()'
SET #SQL = #SQL + ' WHERE name IN'
SET #SQL= #SQL + '(Select name from '
SET #SQL=#SQL + #NAMES +')'
To start with, your SELECT to get the column names won't work at all. You need something like this:
DECLARE #fields nvarchar(max);
SET #fields = N'';
SELECT #fields += CASE WHEN LEN(#fields) = 0 THEN N'' ELSE N', ' END + name
FROM sys.columns
WHERE object_id=object_id('dbo.employees')
ORDER BY column_id
PRINT #fields;
I'm honestly not sure what the rest of your SQL is trying to do... it's trying to select the fields from the employee table from the return of a table-valued function called test()? Where the 'name' column from that test() result set is in ... what? You'll need to be a lot more clear before I can give you a complete answer. One major problem is that you've never actually filled your table variable with anything, so ... I have no idea what you're going for. Knowing the definition of the Test() function would also be helpful.
But at least the above will give you the #fields variable set correctly to the list of columns in the table dbo.employee.
When doing Dynamic SQL, it really helps to write out the end resulting SQL you want, and then identify what parts of that SQL should be filled in by variable data, and work backwards. It's then a lot easier to construct your SQL to build your dynamic SQL.
You need to include the tablevariable logic to dynamic sql
--You need to load #names inside dynamic sql
DECLARE #fields varchar(max);
.
.
.
Select #fields=FROM sys.columns
WHERE object_id=object_id('dbo.employees')
order by name
SET #SQL='DECLARE #NAMES TABLE (name varchar); '
SET #SQL +=' Select '+ #fields
SET #SQL=#SQL + ' from dbo.test()'
SET #SQL = #SQL + ' WHERE name IN'
SET #SQL= #SQL + '(Select name from '
SET #SQL=#SQL + ' #NAMES )'
Or you can load into temp table and access the temptable inside dynamic sql. This means you will be loading temptable like #names and then use that in dynamic sql...

sql how to write this as a script

I have the following sql query
Select * from Name
where surname in ('test1', 'test2')
which works
But I wanted to do the following
DECLARE #Surname as VARCHAR(100)
set #Surname = 'test1' + ',' + 'test2'
Select * from Name
where surname in #Surname
this is the actual query used
DECLARE #COESNo as VARCHAR(100)
set #COESNo = '121108883' + ',' + '121108890'
declare #sql varchar(max)
set #sql = 'select [LEI_ACCEPT] , [PREFERED_LEI] , [INSPECTION_COMPANY], [INSP_ACCEPT] from [CERTIFICATE_DETAILS] where [Certificate_no] in ('
set #sql = #sql + #COESNo + ')'
exec #sql
get the error
The name 'select [LEI_ACCEPT] , [PREFERED_LEI] , [INSPECTION_COMPANY], [INSP_ACCEPT] from [CERTIFICATE_DETAILS] where [Certificate_no] in (121108883,121108890)' is not a valid identifier.
doesn't seem to work
any ideas
There are two popular solutions.
First one is to build string with query and use sp_executesql to run it.
Second one is to write (or find) function (something like SplitText2Table()) which converts comma separated string to table and write query which use this function -- something like:
select *
from name
where surname in (select item from SplitText2Table(#surnames))
This is not a solution for the exact problem in the question. But maybe (?) you could instead use this workaround:
declare #SurName1 nvarchar(20)
declare #SurName2 nvarchar(20)
set #SurName1='test1'
set #SurName2='test2'
select * from [Name] where [surname] in (#SurName1, #SurName2)
you will need to create your statement and execute - like
declare #sql varchar(max)
set #sql = 'Select * from [Name] where surname in ('
set #sql = #sql + #surname + ')'
After creating the statement just say
exec #sql
You can also check the formed query is correct or not using print
print #sql
Please use print before execution of the command (this will help you in correcting the query is there is any error.).
EDIT:
As per the comment - Since Name is a keyword for SQL - we will need to use square bracket against it. I have modified the statement in my answer.
Edit 2: Based on further comments -
Firstly I would like to know the datatype of Certificate_no column in your database.
If it is a varchar field you will need to have single quotes around each value.
The name SELECT [LEI_ACCEPT] , [PREFERED_LEI] , [INSPECTION_COMPANY], [INSP_ACCEPT] FROM[CERTIFICATE_DETAILS] WHERE [Certificate_no] IN ('121108883','121108890')
You will need to create -
DECLARE #COESNo as VARCHAR(100)
set #COESNo = '''121108883''' + ',' + '''121108890'''
Since Certificate number is varchar the string build will need a single quote in formed query which will appear with three single quotes.
I have created Working DEMO for you on SQL FIDDLE - CLICK HERE

Using table columns in prepared statement parameter

My page has a dropdown list that let a user choose any search category like title, description and so forth. So I have this SQL statement:
select * from table where "selected value from dropdown list" = "searchform"
I would like to pass it to the prepared statement like this:
select * from table where ? = ?
Since my select statements have the same form, only the columns in the where clause are different, is there a way to do this without manually creating select statements for every column?
Yes, it is called dynamic sql.
DECLARE #sql AS VARCHAR(MAX)
SET #sql = 'select * from table where ' + #column + ' = ''' + #value + ''''
EXEC(#sql)
You must check if the column is of numeric type.
You should also be careful for sql injection. My example is a very simplistic one, so you have to do your own checks.
For instance use of QUOTENAME would be useful:
DECLARE #sql AS VARCHAR(MAX)
SET #sql = 'select * from table where ' + QUOTENAME(#column) + ' = ''' + #value + ''''
EXEC(#sql)
The above examples are simply TSQL. In your prepared statement i think you could have the following:
PreparedStatement pstmt = con.prepareStatement("
DECLARE #sql AS VARCHAR(MAX)
SET #sql = 'select * from table where ' + QUOTENAME(?) + ' = ? '
EXEC(#sql)
");
pstm.setString(1,columnName);
pstm.setString(2,filterValue);
Unfortunately i am not familiar with JAVA, so i have not tested this. I think it worths a try though.
The above #sql variable will produce a statement like :
select * from table where [columnname] = filtervalue
columnname wrapped with brackets will help against SQL injection.

Creating SQL table using dynamic variable name

I want to create backup SQL tables using variable names.
something along the lines of
DECLARE #SQLTable Varchar(20)
SET #SQLTable = 'SomeTableName' + ' ' + '20100526'
SELECT * INTO quotename(#SQLTable)
FROM SomeTableName
but i'm getting
Incorrect syntax near '#SQLTable'.
It's just part of a small script for maintence so i don't have to worry about injections.
DECLARE #MyTableName sysname;
DECLARE #DynamicSQL nvarchar(max);
SET #MyTableName = 'FooTable';
SET #DynamicSQL = N'SELECT * INTO ' + QUOTENAME(#MyTableName) + ' FROM BarTable';
EXEC sp_executesql #DynamicSQL;
Unfortunately, you can't use bind variables for table names, column names, etc. IN this case you must generate dynamic SQL and use exec.
DECLARE #Script NVARCHAR(MAX);
SET #Script = N'SELECT * INTO SomeTableName_' + N'20100526' + N' FROM SomeTableName';
EXEC sp_executesql #Script
I've left the date separate as I assume you want to calculate it for every run.
You should look into using synonyms:
-- Create a synonym for the Product table in AdventureWorks2008R2.
CREATE SYNONYM MyProduct
FOR AdventureWorks2008R2.Production.Product;
GO
-- Query the Product table by using the synonym.
USE tempdb;
GO
SELECT ProductID, Name
FROM MyProduct
WHERE ProductID < 5;
GO
http://msdn.microsoft.com/en-us/library/ms177544.aspx
DECLARE #MyTableName nvarchar(20);
DECLARE #DynamicSQL nvarchar(1000);
SET #MyTableName = "FooTable";
SET #DynamicSQL = N'SELECT * INTO ' + #MyTableName + ' FROM BarTable';
exec #DynamicSQL;
this query is correct but just use single quote at the ("FooTable")='FooTable'