动态 SQL 中表名的语法错误

Dar*_*ter 0 sql t-sql sql-server dynamic-sql

我在 SQL Server 中编写了一个存储过程来检查数据是否存在于几个表中,如果不存在则查询将失败,但如果数据存在则它将在表 3 中插入​​一些数据。但我看到我得到了一个我通过变量传递的数据库名称错误。以下是错误消息。

消息 208,级别 16,状态 1,第 65 行
无效的对象名称“EMR-Integration-DEV.dbo.EMR_ADF_Variables_test”

这是我的存储过程:

CREATE PROCEDURE InsertData
    @Client_Id INT,
    @EMR_Id INT,
    @Client_Name NVARCHAR(255),
    @EMR_Name NVARCHAR(255),
    @DB_Name NVARCHAR(255)
AS
BEGIN
    DECLARE @Full_Table_name NVARCHAR(255);
    SET @Full_Table_name = @DB_Name + '.dbo.Variable_Table_Name'; 

    -- Check if values exist in tables in the Reference database
    IF NOT EXISTS (SELECT 1 FROM Dim.Client_table WHERE ClientId = @Client_Id AND StagedName = @Client_Name)
    BEGIN
        PRINT 'Error: Client does not exist.';
        RETURN;
    END

    IF NOT EXISTS (SELECT 1 FROM  [dbo].[EMR] WHERE EMR_Id = @EMR_Id AND EMR_Name = @EMR_Name)
    BEGIN
        PRINT 'Error: EMR does not exist.';
        RETURN;
    END
    
    DECLARE @SqlQuery NVARCHAR(MAX);

    SET @SqlQuery = 
        'IF NOT EXISTS (SELECT 1 FROM ' + QUOTENAME(@Full_Table_name) + ' WHERE Client_Id = ' + CAST(@Client_Id AS NVARCHAR) + ' AND EMR_Id = ' + CAST(@EMR_Id AS NVARCHAR) + ')
        BEGIN
            INSERT INTO ' + QUOTENAME(@Full_Table_name) + ' (Client_Id, EMR_Id, Client_Name, EMR_Name)
            VALUES (' + CAST(@Client_Id AS NVARCHAR) + ', ' + CAST(@EMR_Id AS NVARCHAR) + ', N''' + @Client_Name + ''', N''' + @EMR_Name + ''');
            INSERT INTO ' + QUOTENAME(@Full_Table_name) + ' (Client_Id, EMR_Id, Client_Name, EMR_Name)
            VALUES (' + CAST(@Client_Id AS NVARCHAR) + ', ' + CAST(@EMR_Id AS NVARCHAR) + ', N''' + @Client_Name + ''', N''' + @EMR_Name + ''');
        END';

    EXEC sp_executesql @SqlQuery;

    PRINT 'Data inserted successfully.';
END
Run Code Online (Sandbox Code Playgroud)

请在这件事上给予我帮助。

我尝试删除并添加单个代码来获取正确的数据库名称,但它不起作用。

Cha*_*ace 5

您在错误的地方引用了。QUOTENAME需要单个对象或数据库名称,而不是由三部分组成的名称。

相反,只需在过程顶部引用数据库名称(唯一的动态位)。

DECLARE @Full_Table_name NVARCHAR(1000) = QUOTENAME(@DB_Name) + '.dbo.Variable_Table_Name';
Run Code Online (Sandbox Code Playgroud)

然后删除下面的引用。您还应该正确传递参数。切勿n/varchar在没有长度的情况下使用。

DECLARE @SqlQuery NVARCHAR(MAX) = '
IF NOT EXISTS (SELECT 1
    FROM ' + @Full_Table_name + '
    WHERE Client_Id = @Client_Id
      AND EMR_Id = @EMR_Id
)
BEGIN
    INSERT INTO ' @Full_Table_name + '
        (Client_Id, EMR_Id, Client_Name, EMR_Name)
    VALUES
        (@Client_Id, @EMR_Id, @Client_Name, @EMR_Name),
        (@Client_Id, @EMR_Id, @Client_Name, @EMR_Name);
END;
';

EXEC sp_executesql @SqlQuery
  N'@Client_Id INT,
    @EMR_Id INT,
    @Client_Name NVARCHAR(255),
    @EMR_Name NVARCHAR(255)',
  @Client_Id = @Client_Id,
  @EMR_Id = @EMR_Id,
  @Client_Name = @Client_Name.
  @EMR_Name = @EMR_Name;
Run Code Online (Sandbox Code Playgroud)

考虑到只有数据库名称是动态的,另一个选择是使用动态过程名称。

DECLARE @proc nvarchar(1000) = QUOTENAME(@DB_Name) + '.sys.sp_executesql';

DECLARE @SqlQuery NVARCHAR(MAX) = '
IF NOT EXISTS (SELECT 1
    FROM dbo.Variable_Table_Name
    WHERE Client_Id = @Client_Id
      AND EMR_Id = @EMR_Id
)
BEGIN
    INSERT INTO dbo.Variable_Table_Name
        (Client_Id, EMR_Id, Client_Name, EMR_Name)
    VALUES
        (@Client_Id, @EMR_Id, @Client_Name, @EMR_Name),
        (@Client_Id, @EMR_Id, @Client_Name, @EMR_Name);
END;
';

EXEC @proc @SqlQuery
  N'@Client_Id INT,
    @EMR_Id INT,
    @Client_Name NVARCHAR(255),
    @EMR_Name NVARCHAR(255)',
  @Client_Id = @Client_Id,
  @EMR_Id = @EMR_Id,
  @Client_Name = @Client_Name.
  @EMR_Name = @EMR_Name;
Run Code Online (Sandbox Code Playgroud)