动态 SQL 中表名存在语法错误

问题描述 投票:0回答:1

我在sql server中编写了一个SP来检查数据是否存在于几个表中,如果不存在则查询将失败,但如果数据存在则它将在表3中插入一些数据。但我发现我传递 tru 变量的数据库名称出现错误。以下是错误消息。

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

这是我的SP:

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

请帮我解决这个问题,我做了太多事情后一片空白:(

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

sql sql-server t-sql dynamic-sql
1个回答
0
投票

您引用的内容有误。

QUOTENAME
需要单个对象或数据库名称,而不是由三部分组成的名称。

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

DECLARE @Full_Table_name NVARCHAR(1000) = QUOTENAME(@DB_Name) + '.dbo.Variable_Table_Name';

然后删除下方的引用。您还应该正确传递参数。并且切勿使用没有长度的

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;

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

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;
© www.soinside.com 2019 - 2024. All rights reserved.