How can I use a parameter instead of a field name like:
Declare #Thecode varchar(10)
Set #Thecode= ‘code’ --'code' is field name.
Select #Thecode from sqltable
Here is the correction in your query:
SET #Thecode= ‘code’ --'code' is field name.
SET #query='Select '+#Thecode+' from sqltable'
EXECUTE(#query)
There are two ways to execute dynamic SQL in SQL Server: use the sp_executesql system stored procedure or the EXECUTE() operator.
And for more details about the dynamic SQL execution Follow the below link:
https://www.mssqltips.com/sqlservertip/1160/execute-dynamic-sql-commands-in-sql-server/
I think you are looking for the Dynamic SQL.
If it is so then please check the following solution:
Note: Tested in SQL Server 2008 R2
Declare #Thecode varchar(10)
DECLARE #query VARCHAR(MAX)
Set #Thecode= 'code' --'code' is field name.
SET #query = 'SELECT '+ #Thecode +' from sqltable';
EXEC(#query)
Always mention the DBMS in the tags while posting the question. And take care of SQL Injection
For more details about Dynamic SQL.
Related
I want to know if there is a possibility to inject sql query into procedure argument. I have particular case:
ALTER PROCEDURE [Test].[Injection]
#Query varchar(250) = null
AS
SET NOCOUNT ON
SET #Query = REPLACE(#Query,'','') COLLATE Latin1_General_CI_AI
... more sql code
SELECT * FROM Customers
WHERE (#Query IS NULL OR (Name COLLATE Latin1_General_CI_AI like '%'+#Query+'%'))
ORDER BY ExternalCode ASC
I want to inject sql query using #Query variable and possibly comment the rest of the code. Procedure is called via Web Service using JDBCConnector. I tried passing (and many others combinations):
'''abc'','''','''');SELECT * FROM [DummyTable][Dummy];--'
as #Query argument but it didn't work out.
No worries, SQL injection is impossible like this.
The way SQL injection works is by sneaking in (injecting) SQL code into the target query.
That is not possible to do with parameters, since SQL parameters are treated as data, not as code. You can pass any SQL code you want inside the parameter, but it will not pose an SQL injection threat.
However - please note that if you are using dynamic SQL inside your stored procedure, and concatenate the parameters into the SQL string, then your query is vulnerable to SQL injection attacks.
This code is not safe!
DECLARE #Sql nvarchar(max) = N'SELECT * FROM Customers
WHERE ('+ #Query +' IS NULL '....
EXEC(#SQL)
To safely run dynamic SQL in SQL Server you can use sp_executeSql and pass the parameters as parameters:
DECLARE #Sql nvarchar(max) = N'SELECT * FROM Customers
WHERE (#TheQuery IS NULL '....
EXEC sp_ExecuteSql
#Sql,
N'#TheQuery varchar(250)',
#TheQuery = #Query
sorry I am uploading a pic of my query as I dont know to format my text...as a newbie its confusing.
So you want to execute:
select * from File_20170703 -- where your table name is a variable.
It is not possible to use variables for table or column names, what you need to do is to build a dynamic sql and execute it using sp_executesql.
here is an example:
DECLARE #sql nvarchar(4000)
SELECT #sql = 'SELECT * FROM File_20170703'
EXEC sp_executesql #sql
More info about dynamic sql
A simple TSQL "dynamic sql" looks like this:
DECLARE #file_name AS VARCHAR(100)
DECLARE #query AS VARCHAR(MAX)
SET #file_name = 'file_20170101'
SET #query = 'SELECT * FROM ' + #file_name
execute(#query)
Basically you need to create a valid sql query by concatenating various parts of the query together, then you can execute that whole big string as your query.
You can use SQL Cursor along with while loop. Examples are given here:
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/while-transact-sql
I need to TRIM databases as per requirement. So, I'm using below script and giving database names manually. All I need is to automate the script to get database names automatically. Can anyone please suggest how to get the database name automatically.
Use [Sales_backup_2015_05_31_230001_7137975]
Exec [spMaint_TrimTestDB] 1
Go
for Eg:
instead of giving manually Sales_backup_2015_05_31_230001_7137975 I need to get db name automatically
Thanks.
There is a function DB_NAME() that would return the name of the current database if no parameters are passed. Check this.
I guess dynamic SQL might help you to run SP in different databases:
DECLARE #sql nvarchar(max)
SELECT #sql = (
SELECT N'Use '+QUOTENAME([name]) +' Exec [spMaint_TrimTestDB] 1;'
FROM sys.databases
WHERE database_id >= 5 AND [name] like 'Sales_backup%'
FOR XML PATH('')
)
EXEC sp_executesql #sql
This script will create and execute dynamic statement like:
Use [sales_backup_2015] Exec [spMaint_TrimTestDB] 1;
Use [sales_backup_2016] Exec [spMaint_TrimTestDB] 1;
etc...
I have a query in sql as following
select PricingXML.query('/Fields/Field1,/Fields/Field2') from T_SMPricingData
PricingXML is a xml column in the table T_SMPricingData.
I need to pass the xquery from a variable to the query like the following
declare #var nvarchar(100)
set #var='/Fields/Field1,/Fields/Field2'
select PricingXML.query('sql:variable("#var")') from T_SMPricingData
How can I use the variable correctly. It is not working in the intended manner
Edit
My output for the original correct query is
<Field1>10</Field1><Field2>11</Field2>
<Field1>20</Field1>
The data in the column looks like
<Fields>
<Field1>20</Field1>
<Field3>22</Field3>
<Field4>23</Field4>
</Fields>
Link for sql fiddle
http://www.sqlfiddle.com/#!3/12d7c/6/0
I achieved the above by
DECLARE #var nvarchar(100)
SET #var='/Fields/Field1,/Fields/Field2'
DECLARE #sqlCommand varchar(1000)
SET #sqlCommand = 'SELECT PricingXml.query('''+#var+''') from MyTable'
EXEC (#sqlCommand)
I have used sp_addlinkedserver to access the remote machines db now i am writing queries explicitly on database like,
select * from [server\instance].database.owner.tablename
Now with this,
[Server\instance] : this has to be provided explicitly
[database] : can we find databases on specified instance using query like ms_ForEachDB ?
[owner] : Can we find the database owner name using query ?
If these values are found using queries do we need to use EXEC() to execute this or we can still achieve it using nice queries ?
Thanks all,
The "nice" format you mention is simply a 4 part object reference.
select * from [server\instance].database.owner.tablename
3 part
select * from database.owner.tablename
2 part
select * from owner.tablename
If you want to dynamically change any of the server, db or schema values then you have one option:
EXEC (#sqlstring)
However, if you only access stored procs remotely...
DECLARE #RemoteSP varchar(500)
SET #RemoteSP = '[server\instance].database2.schema.proc2'
EXEC #RemoteSP #p1, #p2, #p3 OUTPUT
SET #RemoteSP = '[server\instance].database1.schema.proc1'
EXEC #RemoteSP #p4, #p5, #p6 OUTPUT
However, changing the components of the object reference makes no sense arguably: if you know you're going to query a table then just call that table in that database...
you should make a query string and then run it by exec() function.
getting server name :
SELECT ##SERVERNAME
getting current db name :
SELECT DB_NAME() AS DataBaseName
You do not have to use EXEC you could use something like select * from openquery(MyLinkedServer,#sql) THough i prefer EXEC(#sql) AT MyLinkedServer
But all work
If it happens that you need to use some sort of variable in your arguments(e.g. collect remote's server updates since yesterday):
DECLARE #yesterday NVARCHAR(20) = '2016-09-23 08:16:20';
DECLARE #sql NVARCHAR(MAX) = N'SELECT * FROM database.targetTable AS origin
WHERE origin.columnWithDateTime >'''+#yesterday+''';';
PRINT #sql;
EXEC(#sql) AT linkedServer
______
Where:
database.targetTable : For some reason SSMS 2008 R2 returns error if you describe it as [database].[targetTable], and i don't know why that happens.
#yesterday: Is the variable you want to insert (this case, a string containing datetime-like element)
PRINT #sql: Just to verify if the quotes are correctly placed.
columnWithDateTime: Should be a column with datetime format (e.g. "timestamp", or similar to the #yesterday variable format.
"OPENQUERY does not accept variables for its arguments.": See Here (MSDN: OPENQUERY (Transact-SQL)).