如何在USE
语句中使用局部变量?我得到错误:
消息 911,级别 16,状态 1,第 6 行
数据库“DWSource_@Country”不存在。确保正确输入名称。
代码:
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')
Run Code Online (Sandbox Code Playgroud)
提前致谢!
Br, 安雅
您不能将变量传递给USE
. 您可以在动态 SQL 中执行此操作,也可以构建一个字符串,在每个对象名称前加上数据库前缀。
一种比后一种方法更简洁的动态 SQL 方法,恕我直言,因为它不需要您在动态 SQL 中的每个对象前面注入数据库名称(并且,在这种情况下,还允许您@Country
作为参数传递):
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;
Run Code Online (Sandbox Code Playgroud)
恕我直言,这两件事至少在某种程度上降低了 SQL 注入的风险。并不是说恶意用户可以用 a 做很多事情,CHAR(3)
但是如果您以其他方式使用该模式并使用更大的变量,那么有人可以轻松通过@Country = '1''; DROP TABLE dbo._data_CRM_S_PARTNER; SELECT '''
……而在另一个解决方案中,这将是一个问题(同样,如果变量更大)。
EXEC @exec
从Erland Sommarskog 关于动态 SQL 的精彩文章中准窃取的方法。
话虽如此,我确实同意 Thomas 的观点,如果您想在多个数据库中运行相同的查询,最好在每个数据库中创建相同的存储过程,然后让应用程序首先连接到所需的数据库地方。由于应用程序必须知道您在哪个国家/地区,因此仅基于此生成连接字符串并在该数据库中调用干净的、无动态 SQL 的存储过程应该不难。
你不能。看看BOL 中语句的引用/语法USE
,这不接受表达式:
USE { database }
Run Code Online (Sandbox Code Playgroud)
看起来好像您正在执行某种形式的数据库分片,并且您希望能够以编程方式处于特定数据库的上下文中。您在这里有两个选择:动态 SQL 或某种形式的数据库和连接字符串细节的应用程序级切换。
归档时间: |
|
查看次数: |
18799 次 |
最近记录: |