How to use local variable in 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
Best Answer
You can't pass a variable to
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):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.