动态SQL用于多个(通用表)数据库解决方案?

时间:2017-08-18 15:49:40

标签: sql tsql stored-procedures view dynamic-sql

我一直在使用动态SQL查询(在存储过程中),以便为具有公共表的许多类似结构的数据库运行单个语句。

例如:

解决方案1:

ALTER PROC [dbo].[Example]
    @vc_db VARCHAR(16)
    , @vc_example VARCHAR(32)

AS
BEGIN

-- Dummy query for SSRS to allow columns to be read in Visual Studio

IF 1 = 2
BEGIN
    SELECT 
        T1.C1
        , T1.C2
        , T2.C3
        , T2.C4
    FROM 
        DB1.dbo.T1
    LEFT JOIN
        DB1.dbo.T2
    ON
        T2.C1 = T1.C1
    WHERE
        T2.C4 = @vc_example
END

-- Dynamic query

DECLARE @vc_SQL VARCHAR(MAX) = '
    SELECT 
        T1.C1
        , T1.C2
        , T2.C3
        , T2.C4
    FROM 
        ' + @vc_db + '.dbo.T1
    LEFT JOIN
        ' + @vc_db + '.dbo.T2
    ON
        T2.C1 = T1.C1
    WHERE
        T2.C4 = ''' + @vc_example + '''
'

PRINT @vc_SQL
EXEC (@vc_SQL)

END

到目前为止,它一直运行良好,因为它允许我们在运行多个数据库的语句/报告时传递其他参数。

然而,随着查询变得越来越复杂,管理虚拟查询以及将标准SQL转换为动态格式变得很困难。

因此,我们已开始研究实现此目的的其他方法。

解决方案2

我们最新的解决方案是为每个公用表创建一个视图(添加数据库列),基本上采用以下格式:

ALTER VIEW [dbo].[v_T1]
AS

SELECT *, 'DB1' DB FROM DB1.T1

UNION ALL

SELECT *, 'DB2' DB FROM DB2.T1

UNION ALL

SELECT *, 'DB3' DB FROM DB3.T1

这使我们能够以更简单,更简单的方式编写查询(在存储过程中)(不转换为“动态查询”,不需要Visual Studio拾取虚拟查询),而是利用用于限制和加入数据的附加数据库列,如下所示:

SELECT 
    T1.C1
    , T1.C2
    , T2.C3
    , T2.C4
FROM 
    v_T1
LEFT JOIN
    v_T2
ON
    v_T2.C1 = v_T1.C1
    AND v_T2.DB = v_T1.DB   -- JOIN condition on database to limit data
WHERE
    v_T2.C4 = @vc_example
    AND v_T1.DB = @vc_db    -- WHERE on database to limit data

此外,我已经能够通过输入(公共)表名来编写存储过程来动态构建这些视图,并且只要添加任何新数据库就可以重建这些视图。

然而,我们仍然不确定上述两种解决方案的效率/性能,尽管在大多数情况下,解决方案1似乎稍微快一点,但解决方案2在奇怪的情况下更快。我们还要进一步研究这个问题。

我的问题是......我能以更好的方式实现这一目标吗?

  

道歉,我不希望这是一个讨论。我真的想要一些关于某人是否已经知道实现上述目标的更简单有效方法的输入。非常感谢。

0 个答案:

没有答案