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)
请在这件事上给予我帮助。
我尝试删除并添加单个代码来获取正确的数据库名称,但它不起作用。
您在错误的地方引用了。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)