I want to accomplish this:
update #sourceDatabase.dbo.PredictedPrices
and then set #sourceDatabase as a variable.
But I'm not allowed?
Incorrect syntax near '.'.
Is there another way?
DECLARE #Dynsql NVARCHAR(MAX)
DECLARE #sourceDatabase sysname
DECLARE #MinPrice MONEY
SET #sourceDatabase = 'foo'
SET #MinPrice = 1.00
SET #Dynsql = N'update ' + QUOTENAME(#sourceDatabase) + '.dbo.PredictedPrices
set MinPrice = #MinPrice'
EXECUTE sp_executesql #Dynsql,
N'#MinPrice money',
#MinPrice = #MinPrice;
For this to be done you need to use SP_ExecuteSQL . i.e dynamic query execution
Example:
EXECUTE sp_executesql
N'SELECT * FROM AdventureWorks2008R2.HumanResources.Employee
WHERE BusinessEntityID = #level',
N'#level tinyint',
#level = 109;
If you're running this script in SSMS, you can use SQLCMD Mode (found under the Query menu) to script a variable for your database name:
:setvar sourceDatabase YourDatabaseName
update $(sourceDatabase).dbo.PredictedPrices
set ...
Related
I know I am overthinking this, but I've been banging against this for too long so I'm reaching out for help.
This is the statement I'm trying to run: SELECT #cntMax = MAX(id) FROM [Raw_Item-FieldReport]
BUT, the table name is a variable #reportTable
This doesn't work:
SET #sql = 'SELECT #cntMax = MAX(id) FROM #reportTable'
EXEC sp_executesql #sql
I even tried having the actual table name in the SET #sql and that doesn't work either.
I didn't think it would be this difficult, please tell me I'm missing something easy/obvious.
Here's the full bit of code for those who want it:
DECLARE
#inTable nvarchar(255) = 'Raw_Item',
#reportTable nvarchar(255),
#fieldName nvarchar(255),
#cnt int,
#cntMax int,
#sql nvarchar(max)
SET #reportTable = #inTable + '-FieldReport'
SET #cnt = 1
SELECT #cntMax = MAX(id) FROM [Raw_Item-FieldReport]
PRINT #cntMax
SET #cntMax = 0
SET #sql = 'SELECT #cntMax = MAX(id) FROM [Raw_Item-FieldReport]'
EXEC sp_executesql #sql
PRINT #cntMax
SQL Server 12.0.2008.8 (on Azure)
You need to use an output parameter, otherwise SQL Server has no idea how to connect #cntMax in the dynamic SQL to #cntMax not in the dynamic SQL, since they are different scopes. And to protect yourself from SQL injection (some tips here and here), always check that your object exists, and use QUOTENAME() as opposed to manually adding square brackets (and you should always use QUOTENAME() when building object names from user input or variables, even when they don't have bad characters like dashes):
DECLARE #sql nvarchar(max),
#inTable nvarchar(255) = N'Raw_Item',
#reportTable nvarchar(255);
SET #reportTable = N'dbo.' + QUOTENAME(#inTable + '-FieldReport');
IF OBJECT_ID(#reportTable) IS NOT NULL
BEGIN
SET #sql = N'SELECT #cntMax = MAX(id) FROM ' + #reportTable + N';';
EXEC sys.sp_executesql #sql,
N'#cntMax int output',
#cntMax = #cntMax OUTPUT;
PRINT #cntMax;
END
ELSE
BEGIN
PRINT 'Nice try, h#xx0rs!';
END
Always use schema reference (dbo), always use statement terminators, and please try to avoid naming things with invalid identifier characters like dash (-). And one additional tip: always use N prefix on N'nvarchar string literals'.
I am writing an SP in SQL SERVER, and I need one of the steps to execute a query that comes with data from another variable and save that result in another variable for later use in SP. The code I am using displays the following error:
Procedure expects parameter '#handle' of type 'int'.
DECLARE #retorno INT, #sql NVARCHAR(4000), #parametro NVARCHAR(4000), #caminho NVARCHAR(4000)
SET #caminho = '\\arquivos\CÉLULA DE INOVAÇÃO\SQL\19072019.CSV'
SET #parametro = N'#retornoOut INT OUTPUT'
SET #sql = 'SELECT TOP 1 SUBSTRING(RIGHT('''+#caminho+''',12),1,8)'
PRINT #SQL
EXEC sp_execute #sql, #parametro, #retornoOut=#retorno OUTPUT;
The purpose of the code is from a file passed by the user, I can get the name from the given path. I don't know what could be wrong with id.
The problem is that youre using sp_execute , when you should use sp_executesql
this works fine
DECLARE #retorno INT, #sql NVARCHAR(4000), #parametro NVARCHAR(4000), #caminho NVARCHAR(4000)
SET #caminho = '\\arquivos\CÉLULA DE INOVAÇÃO\SQL\19072019.CSV'
SET #parametro = N'#retornoOut INT OUTPUT'
SET #sql = 'SELECT TOP 1 SUBSTRING(RIGHT('''+#caminho+''',12),1,8)'
PRINT #SQL
EXEC sp_executesql #sql, #parametro, #retornoOut=#retorno OUTPUT;
You don't need to use dynamic SQL for this. You can just use set or a simple select:
Using set:
SET #retorno = SUBSTRING(RIGHT(#caminho,12),1,8)
Using select:
SELECT #retorno = SUBSTRING(RIGHT(#caminho,12),1,8)
I have a script and its works well:
DECLARE #RunSPSQL VARCHAR(60);
SET #RunSPSQL = 'EXEC master.dbo.sp_test';
EXEC (#RunSPSQL) AT LNK_SERVER_NAME;
Now I would like to change linked server name to variable, something like this:
DECLARE #RunSPSQL VARCHAR(60);
DECLARE #LNK_Name NVARCHAR(60);
SET #RunSPSQL = 'EXEC master.dbo.sp_test';
SET #LNK_Name = 'LNK_SERVER_NAME';
EXEC (#RunSPSQL) AT #LNK_Name;
But it doesn't work:
Incorrect syntax near '#LNK_Name'
I was looking for a solution, but no success for now.
If anyone, please help.
You can't use a variable to replace the name of an object. Instead you need to use some dynamic SQL to achieve this:
DECLARE #RunSPSQL varchar(60);
DECLARE #LNK_Name nvarchar(60);
DECLARE #SQL nvarchar(MAX);
SET #RunSPSQL = 'EXEC master.dbo.sp_test';
SET #LNK_Name = N'LNK_SERVER_NAME';
SET #SQL = N'EXEC (#RunSPSQL) AT ' + QUOTENAME(#LNK_Name) + N';';
EXEC sp_executesql #SQL, N'#RunSPSQL varchar(60)', #RunSPSQL = #RunSPSQL;
Just ensure you quote the linked server's name to avoid any injection.
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'
I have the below SQL..What I am trying to do is use the Parameter defined at the stored procedure level inside dynamic SQL:
CREATE PROCEDURE [dbo].[Test]
(#DealID NVARCHAR(500),
#OUTPUT NVARCHAR(MAX) OUTPUT,
#FeeType CHAR(1)
) -- I want to use this parameter inside dynamic SQL query
AS
DECLARE #exec_str NVARCHAR(MAX)
DECLARE #ParmDefinition NVARCHAR(MAX)
BEGIN
SET #exec_str = N'DECLARE #ParmDefinition NVARCHAR(500)
SELECT * FROM #FeeType' --This is where I want to use the variable
DECLARE #ParamDefinition nvarchar(max)
SET #ParamDefinition = N'#OUTPUT NVARCHAR(MAX) OUTPUT'
EXEC sp_executesql #exec_str, #ParamDefinition
Can someone please tell me how to do it?
Thanks
In SQL Server Identifiers can't be parameterized.
Since you are using dynamic SQL anyway, you can do something like this:
SET #exec_str= N'Select * from '+ #FeeType
EXEC(#exec_str)
However, this is vulnerable to SQL injection attacks. To reduce the risk to minimum you should check first that such a table name exists, and I would also use quotename just to be on the safe side:
IF EXISTS
(
SELECT 1
FROM Information_Schema.Tables
WHERE TABLE_NAME = #FeeType
)
BEGIN
SET #exec_str= N'Select * from '+ QUOTENAME(#FeeType)
EXEC(#exec_str)
END