snippetsqlMinor
How to use local variable in USE statement
Viewed 0 times
localstatementhowusevariable
Problem
How to use local variable in
Msg 911, Level 16, State 1, Line 6
Database 'DWSource_@Country' does not exist. Make sure that the name is entered correctly.
Code:
Thanks in advance!
Br,
Anja
USE statement? I get error:Msg 911, Level 16, State 1, Line 6
Database 'DWSource_@Country' does not exist. Make sure that the name is entered correctly.
Code:
DECLARE @Country varchar(3)
SET @Country='UKR'
USE DWSource_@Country
SELECT @Country as country,
count(*) as n_ALL,
sum(case when LEN(EPOSTA)>0 then 1 else 0 end) as EMAIL1,
sum(case when LEN(EPOSTA_2)>0 then 1 else 0 end) as EMAIL2
FROM [dbo].[_data_CRM_S_PARTNER]
WHERE VIR = 'SM'
AND PRAVNA_OSEBA = 0
AND PROBLEMATICEN = 0
AND ISNULL([STATUS],0) IN (0,1)
AND ID_DBCLUSTER IN ('112','122','132','212','222','232','312','322','332','311','321','331')Thanks in advance!
Br,
Anja
Solution
You can't pass a variable to
A cleaner dynamic SQL approach than the latter approach, IMHO, since it doesn't require you to inject the database name in front of every object in the dynamic SQL (and also, in this case, allows you to pass
Both of those things at least somewhat reduce your risk for SQL injection, IMHO. Not that a malicious user could do much with a
That all said, I do agree with Thomas that if you have the same query you want to run in multiple databases, you are better off creating the same stored procedure in each database, and having the app just connect to the desired database in the first place. Since the app has to know which country you're after, it shouldn't be that hard to just generate a connection string based off of that, and call a clean, no-dynamic-SQL stored procedure in that database.
USE. You can do this inside the dynamic SQL, or you can build a string that prepends each object name with the database prefix.A cleaner dynamic SQL approach than the latter approach, IMHO, since it doesn't require you to inject the database name in front of every object in the dynamic SQL (and also, in this case, allows you to pass
@Country as a parameter):DECLARE @country CHAR(3) = 'UKR';
-- assume above is incoming parameter
DECLARE
@db SYSNAME = N'DWSource_' + @Country,
@exec NVARCHAR(300),
@sql NVARCHAR(MAX);
SET @sql = N'SELECT @Country as country,
count(*) as n_ALL,
sum(case when LEN(EPOSTA)>0 then 1 else 0 end) as EMAIL1,
sum(case when LEN(EPOSTA_2)>0 then 1 else 0 end) as EMAIL2
FROM [dbo].[_data_CRM_S_PARTNER]
WHERE VIR = ''SM''
AND PRAVNA_OSEBA = 0
AND PROBLEMATICEN = 0
AND ISNULL([STATUS],0) IN (0,1)
AND ID_DBCLUSTER IN (''112'',''122'',''132'',''212'',''222'',
''232'',''312'',''322'',''332'',''311'',''321'',''331'')';
SELECT @exec = QUOTENAME(@db) + '.sys.sp_executesql'
EXEC @exec @sql, N'@Country CHAR(3)', @Country;Both of those things at least somewhat reduce your risk for SQL injection, IMHO. Not that a malicious user could do much with a
CHAR(3) but if you use that pattern in other ways with bigger variables, someone could easily pass @Country = '1''; DROP TABLE dbo._data_CRM_S_PARTNER; SELECT '''... and in the other solution this would be a problem (again, if the variable were bigger).EXEC @exec method quasi-stolen from Erland Sommarskog's great article on dynamic SQL.That all said, I do agree with Thomas that if you have the same query you want to run in multiple databases, you are better off creating the same stored procedure in each database, and having the app just connect to the desired database in the first place. Since the app has to know which country you're after, it shouldn't be that hard to just generate a connection string based off of that, and call a clean, no-dynamic-SQL stored procedure in that database.
Code Snippets
DECLARE @country CHAR(3) = 'UKR';
-- assume above is incoming parameter
DECLARE
@db SYSNAME = N'DWSource_' + @Country,
@exec NVARCHAR(300),
@sql NVARCHAR(MAX);
SET @sql = N'SELECT @Country as country,
count(*) as n_ALL,
sum(case when LEN(EPOSTA)>0 then 1 else 0 end) as EMAIL1,
sum(case when LEN(EPOSTA_2)>0 then 1 else 0 end) as EMAIL2
FROM [dbo].[_data_CRM_S_PARTNER]
WHERE VIR = ''SM''
AND PRAVNA_OSEBA = 0
AND PROBLEMATICEN = 0
AND ISNULL([STATUS],0) IN (0,1)
AND ID_DBCLUSTER IN (''112'',''122'',''132'',''212'',''222'',
''232'',''312'',''322'',''332'',''311'',''321'',''331'')';
SELECT @exec = QUOTENAME(@db) + '.sys.sp_executesql'
EXEC @exec @sql, N'@Country CHAR(3)', @Country;Context
StackExchange Database Administrators Q#80231, answer score: 8
Revisions (0)
No revisions yet.