循环多数据库时DB_NAME()返回master库名问题求助
解决动态SQL中DB_NAME()返回master库名的问题
问题核心在于DB_NAME()的执行上下文:当你通过EXEC (@sql)执行动态SQL时,代码的运行环境是当前连接的数据库(也就是你执行脚本所在的master库),所以DB_NAME()只会返回master,而非目标业务数据库。
直接的解决方法是:不要依赖DB_NAME()函数,而是将遍历到的数据库名称直接作为字符串常量嵌入SELECT语句中。修改后的脚本如下:
DECLARE @sql NVARCHAR(MAX); SET @sql = N''; SELECT @sql = @sql + N' UNION ALL SELECT top 1 Account as Account, ''' + REPLACE(name, '''', '''''') + ''' as DatabaseName, -- 直接嵌入数据库名称字符串 (Select CompnyName from ' + QUOTENAME(name) + '.dbo.OADM)as Entity, GL.TransId as TransactionId, isnull(Debit,0) as Debit, isnull(Credit,0) as Credit, isnull(Debit,0)- isnull(Credit,0) as Balance, year(GL.refdate)*10000+month(GL.refdate)*100+day(GL.refdate) as TimePeriod FROM ' + QUOTENAME(name) + '.dbo.JDT1 GL' FROM master.sys.databases WHERE state = 0 and database_id > 8 and name not like '%template%' and name not like '%staging%' and name not like '%test%' SET @sql = STUFF(@sql, 1, 11, ''); EXEC (@sql); --Print @sql
修改说明
- 使用
''' + REPLACE(name, '''', '''''') + '''替代DB_NAME():- 外层三个单引号用于生成字符串常量的首尾单引号
REPLACE(name, '''', '''''')是为了处理数据库名称含单引号的特殊情况,避免动态SQL语法报错
- 也可以用
QUOTENAME(name, '''')替代上述写法,效果完全一致:QUOTENAME(name, '''') as DatabaseName
修改后,每条SELECT语句都会直接返回对应的业务数据库名称,不再受执行上下文的影响。
内容的提问来源于stack exchange,提问作者Wynand Cilliers
相关产品推荐
相关产品推荐

