Sql server select查询中嵌入的动态sql
我有一个表Sql server select查询中嵌入的动态sql,sql-server,tsql,dynamic-sql,Sql Server,Tsql,Dynamic Sql,我有一个表用户 ╔════╦═══════╦══════╗ ║ Id ║ Name ║ Db ║ ╠════╬═══════╬══════╣ ║ 1 ║ Peter ║ DB1 ║ ║ 2 ║ John ║ DB16 ║ ║ 3 ║ Alex ║ DB23 ║ ╚════╩═══════╩══════╝ 因此,当我查询数据库时: SELECT count(distinct([Request])) as nbrRequests FROM [SRV02].[DB1].[dbo]
用户
╔════╦═══════╦══════╗
║ Id ║ Name ║ Db ║
╠════╬═══════╬══════╣
║ 1 ║ Peter ║ DB1 ║
║ 2 ║ John ║ DB16 ║
║ 3 ║ Alex ║ DB23 ║
╚════╩═══════╩══════╝
因此,当我查询数据库时:
SELECT count(distinct([Request])) as nbrRequests
FROM [SRV02].[DB1].[dbo].[Project]
我得到这个结果:
╔═════════════╗
║ NbrRequests ║
╠═════════════╣
║ 2 ║
╚═════════════╝
我正在尝试使用动态SQL,但运气不好
NB:每个用户只有一个数据库,并且一个数据库只属于一个用户,这是一对一的关系您可以通过一个联合来计算每个特定的数据库表,并为其提供数据库标识,如下所示:
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可能非常棘手 此示例从users表生成select查询。对于用户表返回的每一行,变量@Query都会递增。每行返回一个查询,该查询将本地用户表连接到远程数据库中的项目表。每个查询的结果都在一起 示例
-- 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);
此示例用于帮助避免将这两个答案组合在一起,我得到了以下解决方案:
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);
请求表和用户表之间是否存在特定数据库上的链接?如果没有,每个数据库是否有一个以上的用户,如果有,结果会是什么?请指定表关系以及您如何期望这些请求,因为2,3,6Db是唯一的链接,每个用户只有一个数据库,并且一个数据库只属于一个用户。为什么使用动态sql会“不走运”?您尝试的查询是什么,出现了什么错误?@TabAlleman,运气不好,因为我找不到如何将Users表连接到DBxx。Project table,我找到了一个解决方案,您可以看到我的答案。我不认为此请求是动态的,每次添加user@Hamza_L它不是动态的。每次添加数据库时都必须对其进行更改,因为这不是一项简单的任务,所以在查询中添加两行不会太多。但这只是一种方法。请随意选择最佳答案:)为什么有u.Id=p.Id?u、 Id是用户的Id,p.Id是项目的Id
-- 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);
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);