如何从未知数量的数据库中进行选择?

时间:2014-06-20 10:01:57

标签: sql sql-server

我想向客户展示他们在多个'供应商'中的总订单的历史记录。每个供应商在SQL Server中都有一个单独的数据库来存储他们自己的订单。

在我的数据库中,我只知道用户注册了哪些供应商。所以我的序列需要像这样:

  1. 获取用户注册的所有VendorID。
  2. 转到供应商表并获取其服务器+数据库名称
  3. 执行select语句,该语句从用户注册的每个供应商数据库中的每个Order表中获取所有订单。
  4. DECLARE @UserID int = 999
    
    SELECT Count(OrderNumber) AS 'Orders'
    
    FROM
    --- Need some kind of loop here?
    [VendorServer].[VendorDB].[OrderTable] o1
    
    WHERE 
    o1.UserID = @UserID
    

    如果订单分布在多个数据库中,我如何获得该客户订单总数的总和?

    用户最多可以注册100多家供应商。所以它必须查询100个数据库。这是一个极端的例子,但它可能。

2 个答案:

答案 0 :(得分:1)

这可以使用动态查询来解决:查询本身是动态生成然后执行的。

如果没有表格架构,就无法编写可在您的环境中运行的内容,但这个想法将是

DECLARE @query NVARCHAR(MAX) = ''

SELECT @query += 'UNION ALL 
                  SELECT whatever 
                  FROM   ' + VendorServer + '.' + VendorDB + '.OrdeTable
                  WHERE  condition'
FROM   Vendor
WHERE  VendorID IN (all the VendorIDs that the user is signed up with) 

SET @query = SUBSTRING(@query, 10, LEN(@query))

EXEC sp_executesql(@query)

评论中的OP描述了此架构

CREATE TABLE User_Vendor (
  UserID int
, VendorID int
)

CREATE TABLE Vendors (
  VendorID int
, Name varchar(50)
, DatabaseName varchar(50)
, Servername varchar(50)
)

在这种情况下,查询/存储过程体将是

DECLARE @UserID int = '999'
DECLARE @query NVARCHAR(MAX) = ''

DECLARE @vUserID nvarchar(10) = CAST(UserID as nvarchar(10))

SELECT @query += 'UNION ALL 
                  SELECT Count(OrderNumber) AS [Orders]
                  FROM   ' + v.Servername + '.' + v.DatabaseName + '.OrdeTable
                  WHERE  o1.UserID = ' + @UserID + ' '
FROM   User_Vendor uv
       INNER JOIN Vendors v ON uv.VendorID = v.VendorID
WHERE  uv.UserID = @UserID

SET @query = SUBSTRING(@query, 10, LEN(@query))

EXEC sp_executesql(@query)

SQLFiddle demo SELECT @query而不是EXEC sp_executesql(@query)

添加的变量@vUserID是为了避免查询中出现多个CAST,查询中不需要User表。

要获取订单的总数,而不是每个供应商的计数,行

SET @query = SUBSTRING(@query, 10, LEN(@query))

应改为

SET @query = 'SELECT SUM([Orders]) [Orders]
              FROM (' + SUBSTRING(@query, 10, LEN(@query)) + ') a'

答案 1 :(得分:1)

虽然与Serpiton的答案相似,但只是张贴供您参考 -

    DECLARE @userId INT;
    DECLARE @sql VARCHAR(MAX) = '';

    SELECT  @sql += ' SELECT COUNT(*) Cnt FROM ' + 
                    ServerName + '.' + DbName + '.' + tblNameWithSchema + 
                    ' WHERE UserId = ' + CAST(@userId AS VARCHAR(50)) + ' UNION ALL '
    FROM    yourTbl
    WHERE   UserId = @userId;

    -- Remove excessive 'Union All'
    SET @sql = SUBSTRING(@sql, LEN(@sql) - LEN(' UNION ALL '), LEN(' UNION ALL '));

    SET @sql = 'SELECT SUM(Cnt) FROM (' + @sql + ') tmp'

    EXECUTE sp_executesql(@sql);