[英]dynamic sql embedded in select query
我有一个表Users
,
╔════╦═══════╦══════╗ ║ Id ║ Name ║ Db ║ ╠════╬═══════╬══════╣ ║ 1 ║ Peter ║ DB1 ║ ║ 2 ║ John ║ DB16 ║ ║ 3 ║ Alex ║ DB23 ║ ╚════╩═══════╩══════╝
并且许多数据库具有相同的结构(相同的表,相同的过程等),因此每个数据库都有一个名为Project
的表,这就是Project
表的结构,
╔════╦═════════╦═════════════╗ ║ Id ║ Request ║ Information ║ ╠════╬═════════╬═════════════╣ ║ 1 ║ 126 ║ XB1 ║ ║ 2 ║ 126 ║ D6 ║ ║ 3 ║ 202 ║ BM-23 ║ ╚════╩═════════╩═════════════╝
因此,当我查询数据库时:
SELECT count(distinct([Request])) as nbrRequests
FROM [SRV02].[DB1].[dbo].[Project]
我得到这个结果:
╔═════════════╗ ║ NbrRequests ║ ╠═════════════╣ ║ 2 ║ ╚═════════════╝
现在,我想要的是将表Users
结果“链接” /“加入”到该查询,其中Users
表中的Db
列是我的数据库的名称,因此我可以得到如下结果:
╔════╦═══════╦══════╦═════════════╗ ║ Id ║ Name ║ Db ║ NbrRequests ║ ╠════╬═══════╬══════╬═════════════╣ ║ 1 ║ Peter ║ DB1 ║ 2 ║ ║ 2 ║ John ║ DB16 ║ 3 ║ ║ 3 ║ Alex ║ DB23 ║ 6 ║ ╚════╩═══════╩══════╩═════════════╝
我正在尝试使用动态SQL,但是没有运气。
注意:每个用户只有一个数据库,并且一个数据库仅属于一个用户,这是一对一关系
您可以通过UNION对每个特定的数据库表进行计数并为其提供数据库标识,例如:
SELECT u.Id, u.Name, u.Db, dbCts.nbrRequests
FROM [Users] u INNER JOIN
(SELECT 'DB1' as db, count(distinct([Request])) as nbrRequests
FROM [SRV02].[DB1].[dbo].[Project]
UNION
SELECT 'DB16', count(distinct([Request])) as nbrRequests
FROM [SRV02].[DB16].[dbo].[Project]
UNION
SELECT 'DB23', count(distinct([Request])) as nbrRequests
FROM [SRV02].[DB23].[dbo].[Project]
) dbCts ON u.Db = dbCts.db
不要忘记将服务器和架构添加到Users
表中,因为您的问题中没有这样的信息。
同样,为了做到这一点,您所连接的用户必须对所有数据库都具有特权。
动态SQL可能非常棘手。
本示例从用户表构建选择查询。 对于用户表返回的每一行,变量@Query递增。 每行返回一个查询,该查询将本地用户表连接到远程数据库中的项目表。 每个查询的结果都是UNIONED在一起。
例
-- Wil holds our dynamic query.
DECLARE @Query NVARCHAR(MAX) = '';
-- Builds our dynamic statement.
SELECT
@Query =
@Query
+ CASE WHEN LEN(@Query) > 0 THEN ' UNION ALL ' ELSE '' END
+ 'SELECT u.Id, u.Name, u.Db, COUNT(DISTINCT p.Request) AS NbrRequest '
+ 'FROM [SVR02].' + QUOTENAME(DB) + 'dbo.Project AS p INNER JOIN Users u ON u.Db= p.Db '
+ 'GROUP BY u.Id, u.Name, u.Db'
FROM
Users
;
-- Executes the dynamic statement.
EXECUTE (@Query);
结合这两个答案https://stackoverflow.com/a/35795690/1460399和https://stackoverflow.com/a/35795189/1460399 ,我得到了以下解决方案:
DECLARE @Query NVARCHAR(MAX)= 'SELECT u.Id, u.Name, u.Db, dbCts.nbrRequests FROM [Users] u INNER JOIN (';
DECLARE @QueryLength INT= LEN(@Query);
SELECT @Query = @Query
+CASE WHEN LEN(@Query) > @QueryLength THEN ' UNION ' ELSE '' END
+'SELECT '''+Db+''' as db, count(distinct(Request)) as nbrRequests FROM [SRV02].'+Db+'[Project]'
FROM Users;
SET @Query = @Query+') dbCts ON u.Db = dbCts.db';
EXECUTE (@Query);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.