通过过程中的参数动态切换数据库

Switching database dynamically by a parameter in procedure

我正在使用 Microsoft SQL Server 2012。

我有一个实例,它有三个数据库 - A、B、C。

A 和 B 有一个同名的 table,我想用 C 编写一个程序,使用 A 和 B 中的 table。

TEMP_INSTANCE
  - A
    - table TEMP_TABLE
  - B
    - table TEMP_TABLE
  - C
    - stored procedure TEMP_PROCEDURE

TEMP_PROCEDURE接受一个参数@P。如果@P1,这个returns数据来自A.TEMP_TABLE,如果@P2,那么returns那些来自B.TEMP_TABLE。我认为最简单的方法是使用 IF 并在每个短语中进行查询,如下所示。

CREATE PROCEDURE C.dbo.TEMP_PROCEDURE
    @P tinyint
AS
BEGIN
    SET NOCOUNT ON

    IF @P = 1
    BEGIN
        SELECT * FROM A.dbo.TEMP_TABLE
    END
    ELSE IF @P = 2
    BEGIN
        SELECT * FROM B.dbo.TEMP_TABLE
    END
END

但这种方式效率低下,因为我应该在每个 IF 短语中编写相同的查询。如果实例数大于2,每当有修改的时候,效率就会很低

我的问题:是否有更清洁的解决方案?我不想在一个存储过程中重复相同的查询。

这不是很 well-known 语法,但您可以在相关数据库中调用 sp_executesql,可能更难阅读,但您不必将整个查询重复两次。

CREATE PROCEDURE C.dbo.TEMP_PROCEDURE
    @P tinyint
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @sql     nvarchar(max) = N'SELECT * FROM dbo.TEMP_TABLE;',
            @context nvarchar(max) = CASE @P 
                     WHEN 1 THEN N'A' ELSE N'B' END + N'.sys.sp_executesql';

    EXEC @context @sql;
END

其他人可能会建议 SET @sql = N'SELECT * FROM ' + @db + '.dbo.TEMP_TABLE';,但我认为我在此处提出的方法更清洁且不易受到 SQL 注入的影响。