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);