动态 sql 嵌入在 select 查询中
dynamic sql embedded in select query
我有一个tableUsers
,
╔════╦═══════╦══════╗
║ Id ║ Name ║ Db ║
╠════╬═══════╬══════╣
║ 1 ║ Peter ║ DB1 ║
║ 2 ║ John ║ DB16 ║
║ 3 ║ Alex ║ DB23 ║
╚════╩═══════╩══════╝
和许多具有相同结构的数据库(相同的 tables,相同的过程,......),所以每个数据库都有一个名为 Project
的 table,这是Project
table,
的结构
╔════╦═════════╦═════════════╗
║ 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 ║
╚═════════════╝
现在,我想要的是 "link"/"join" ... table Users
的结果到此查询,其中列 Db
在 Users
table 是我的数据库的名称,所以我可以得到这样的结果:
╔════╦═══════╦══════╦═════════════╗
║ Id ║ Name ║ Db ║ NbrRequests ║
╠════╬═══════╬══════╬═════════════╣
║ 1 ║ Peter ║ DB1 ║ 2 ║
║ 2 ║ John ║ DB16 ║ 3 ║
║ 3 ║ Alex ║ DB23 ║ 6 ║
╚════╩═══════╩══════╩═════════════╝
我正在尝试使用动态 SQL,但没有成功。
注意:每个用户只有一个数据库,一个数据库只属于一个用户,是一对一的关系
您可以使用 UNION 计算每个特定数据库 table 并为其提供数据库标识,如下所示:
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
table 我没有,因为没有关于你的问题的此类信息。
此外,为了执行此操作,您的连接用户必须拥有所有数据库的权限。
动态 SQL 可能非常棘手。
此示例构建来自用户 table 的 select 查询。对于用户 table 返回的每一行,变量 @Query 递增。每行 returns 一个将本地用户 table 加入远程数据库中的项目 table 的查询。每次查询的结果一共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);
本例使用QUOTENAME to help avoid SQL injection attacks.
结合这 2 个答案 and ,我得到了这个解决方案:
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);
我有一个tableUsers
,
╔════╦═══════╦══════╗ ║ Id ║ Name ║ Db ║ ╠════╬═══════╬══════╣ ║ 1 ║ Peter ║ DB1 ║ ║ 2 ║ John ║ DB16 ║ ║ 3 ║ Alex ║ DB23 ║ ╚════╩═══════╩══════╝
和许多具有相同结构的数据库(相同的 tables,相同的过程,......),所以每个数据库都有一个名为 Project
的 table,这是Project
table,
╔════╦═════════╦═════════════╗ ║ 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 ║ ╚═════════════╝
现在,我想要的是 "link"/"join" ... table Users
的结果到此查询,其中列 Db
在 Users
table 是我的数据库的名称,所以我可以得到这样的结果:
╔════╦═══════╦══════╦═════════════╗ ║ Id ║ Name ║ Db ║ NbrRequests ║ ╠════╬═══════╬══════╬═════════════╣ ║ 1 ║ Peter ║ DB1 ║ 2 ║ ║ 2 ║ John ║ DB16 ║ 3 ║ ║ 3 ║ Alex ║ DB23 ║ 6 ║ ╚════╩═══════╩══════╩═════════════╝
我正在尝试使用动态 SQL,但没有成功。
注意:每个用户只有一个数据库,一个数据库只属于一个用户,是一对一的关系
您可以使用 UNION 计算每个特定数据库 table 并为其提供数据库标识,如下所示:
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
table 我没有,因为没有关于你的问题的此类信息。
此外,为了执行此操作,您的连接用户必须拥有所有数据库的权限。
动态 SQL 可能非常棘手。
此示例构建来自用户 table 的 select 查询。对于用户 table 返回的每一行,变量 @Query 递增。每行 returns 一个将本地用户 table 加入远程数据库中的项目 table 的查询。每次查询的结果一共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);
本例使用QUOTENAME to help avoid SQL injection attacks.
结合这 2 个答案
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);