Sql 无法将用户定义的记录插入表中
场景 我已经创建了一个存储过程,其中我将用户定义的表作为参数,然后首先检查Sql 无法将用户定义的记录插入表中,sql,sql-server,tsql,stored-procedures,Sql,Sql Server,Tsql,Stored Procedures,场景 我已经创建了一个存储过程,其中我将用户定义的表作为参数,然后首先检查角色ID和表单ID是否存在,然后更新现有表。否则,我将插入到现有表中 问题 在我的存储过程中写入insert查询后,我在更改存储过程时遇到以下错误 Msg 137,16级,状态1,程序SP\u设置\u角色\u权限\u保存\u和更新,第17行 必须声明标量变量“@Temp”。 Msg 137,16级,状态1,程序SP\u设置\u角色\u权限\u保存\u和更新,第17行 必须声明标量变量“@Temp” 下面是我的SP代码: C
角色ID
和表单ID
是否存在,然后更新现有表。否则,我将插入到现有表中
问题
在我的存储过程中写入insert查询后,我在更改存储过程时遇到以下错误
Msg 137,16级,状态1,程序SP\u设置\u角色\u权限\u保存\u和更新,第17行
必须声明标量变量“@Temp”。
Msg 137,16级,状态1,程序SP\u设置\u角色\u权限\u保存\u和更新,第17行
必须声明标量变量“@Temp”
下面是我的SP代码:
CREATE TYPE _ROLERIGHTSSCHEMA as Table (
_Role_ID int,
_Form_ID int,
_Form_Name varchar(100),
_Can_View bit,
_Can_Edit bit,
_Can_Prepare_By bit,
_Can_Change_Status_By bit,
_Prepared_By_ID int,
_Prepared_Date datetime
)
ALTER PROCEDURE SP_SETUP_ROLES_RIGHTS_SAVE_AND_UPDATE
(@Temp _ROLERIGHTSSCHEMA ReadOnly)
AS
BEGIN
IF EXISTS(SELECT * FROM ROLE_RIGHTS WHERE Role_ID = @Temp.Role_ID AND Form_ID = @Temp.Form_ID)
BEGIN
Update Role_Rights
set Can_View = t._Can_View,
Can_Edit = t._Can_Edit,
Can_Prepare_By = t._Can_Prepare_By,
Can_Change_Status_By = _Can_Change_Status_By,
Modified_By_ID = 0,
Modified_Date = GETDATE()
From @Temp t
WHERE Role_Rights.Role_ID = t._Role_ID and Role_Rights.Form_ID = t._Form_ID
END
ELSE
BEGIN
INSERT INTO Role_Rights (
Role_ID,
Form_ID,
Can_View,
Can_Edit,
Can_Prepare_By,
Can_Change_Status_By,
Prepared_By_ID,
Prepared_Date
) SELECT _Role_ID, _Form_ID, _Can_View, _Can_Edit, _Can_Prepare_By, _Can_Change_Status_By, 0, GETDATE() FROM @Temp
END
END
要一次更新/插入多条记录,请使用: 编辑:
CREATE TYPE _ROLERIGHTSSCHEMA as Table (
_Role_ID int,
_Form_ID int,
_Form_Name varchar(100),
_Can_View bit,
_Can_Edit bit,
_Can_Prepare_By bit,
_Can_Change_Status_By bit,
_Prepared_By_ID int,
_Prepared_Date datetime
)
ALTER PROCEDURE SP_SETUP_ROLES_RIGHTS_SAVE_AND_UPDATE
(@Temp _ROLERIGHTSSCHEMA ReadOnly)
AS
BEGIN
IF EXISTS(SELECT * FROM ROLE_RIGHTS WHERE Role_ID = @Temp.Role_ID AND Form_ID = @Temp.Form_ID)
BEGIN
Update Role_Rights
set Can_View = t._Can_View,
Can_Edit = t._Can_Edit,
Can_Prepare_By = t._Can_Prepare_By,
Can_Change_Status_By = _Can_Change_Status_By,
Modified_By_ID = 0,
Modified_Date = GETDATE()
From @Temp t
WHERE Role_Rights.Role_ID = t._Role_ID and Role_Rights.Form_ID = t._Form_ID
END
ELSE
BEGIN
INSERT INTO Role_Rights (
Role_ID,
Form_ID,
Can_View,
Can_Edit,
Can_Prepare_By,
Can_Change_Status_By,
Prepared_By_ID,
Prepared_Date
) SELECT _Role_ID, _Form_ID, _Can_View, _Can_Edit, _Can_Prepare_By, _Can_Change_Status_By, 0, GETDATE() FROM @Temp
END
END
合并
超过如果存在/更新/插入基于集的
:
Single insert -- no difference
Single update -- no difference
Multiple insert -- no difference
Multiple update -- no difference
Multiple insert/update: MERGE -- will handle it correctly
IF EXISTS -- you will lose records to insert
更新/插入不带IF部件:
Update Role_Rights
set Can_View = t._Can_View,
Can_Edit = t._Can_Edit,
Can_Prepare_By = t._Can_Prepare_By,
Can_Change_Status_By = _Can_Change_Status_By,
Modified_By_ID = 0,
Modified_Date = GETDATE()
From @Temp t
WHERE Role_Rights.Role_ID = t._Role_ID and Role_Rights.Form_ID = t._Form_ID;
INSERT INTO Role_Rights (
Role_ID,
Form_ID,
Can_View,
Can_Edit,
Can_Prepare_By,
Can_Change_Status_By,
Prepared_By_ID,
Prepared_Date
)
SELECT _Role_ID, _Form_ID, _Can_View, _Can_Edit,
_Can_Prepare_By, _Can_Change_Status_By, 0, GETDATE()
FROM @Temp t
WHERE NOT EXISTS (SELECT 1
FROM Role_Rights rr
WHERE rr.Role_ID = t._Role_ID
and rr.Form_ID = t._Form_ID);
exists子句中的语句格式不正确-这会引发错误。你有:
IF EXISTS(SELECT * FROM ROLE_RIGHTS WHERE Role_ID = @Temp.Role_ID AND Form_ID = @Temp.Form_ID)
但它应该是:
if exists (select * from ROLE_RIGHTS as rr inner join @Temp as tp on rr.Role_ID = tp._Role_ID and rr.Form_ID = tp._Form_ID)
正如@lad2025已经提到的那样,这种修正是毫无意义的 在ELSE之后的语句中尝试使用多个IF子句,检查这是否有效
CREATE TYPE _ROLERIGHTSSCHEMA as Table (
_Role_ID int,
_Form_ID int,
_Form_Name varchar(100),
_Can_View bit,
_Can_Edit bit,
_Can_Prepare_By bit,
_Can_Change_Status_By bit,
_Prepared_By_ID int,
_Prepared_Date datetime
)
ALTER PROCEDURE SP_SETUP_ROLES_RIGHTS_SAVE_AND_UPDATE
(@Temp _ROLERIGHTSSCHEMA ReadOnly)
AS
BEGIN
IF EXISTS(SELECT * FROM ROLE_RIGHTS WHERE Role_ID = @Temp.Role_ID AND Form_ID = @Temp.Form_ID)
BEGIN
Update Role_Rights
set Can_View = t._Can_View,
Can_Edit = t._Can_Edit,
Can_Prepare_By = t._Can_Prepare_By,
Can_Change_Status_By = _Can_Change_Status_By,
Modified_By_ID = 0,
Modified_Date = GETDATE()
From @Temp t
WHERE Role_Rights.Role_ID = t._Role_ID and Role_Rights.Form_ID = t._Form_ID
END
ELSE
BEGIN
IF NOT EXISTS(SELECT * FROM ROLE_RIGHTS WHERE Role_ID = @Temp.Role_ID AND Form_ID = @Temp.Form_ID)
BEGIN
INSERT INTO Role_Rights (
Role_ID,
Form_ID,
Can_View,
Can_Edit,
Can_Prepare_By,
Can_Change_Status_By,
Prepared_By_ID,
Prepared_Date
) SELECT _Role_ID, _Form_ID, _Can_View, _Can_Edit, _Can_Prepare_By, _Can_Change_Status_By, 0, GETDATE() FROM @Temp
END
END
END
你应该考虑不要使用SPY前缀。它可能会导致性能问题和其他一些有趣的挑战。选择不同的前缀,或者甚至更好,完全不选择前缀。之前,我写了上面的if条件更新查询工作正常。我更新了一条记录,但在写入
IF
条件后,我的插入代码不起作用。@Ahmeralahsan使用IF/update/insert对多条记录不起作用。首先,我检查了你的答案,结果很好。但是在@smor-answer之后,我只是编辑了我的IF
条件,它的效果非常好。你的答案和@smor-answer之间的主要区别是什么,因为我发现这两个答案都很有用,但我不清楚我选择了哪一个作为我的代码。使用这种方法有很大的缺点(当@Temp table有两条记录要更新/插入时——根本就没有插入部分)。当然,OP可以使用游标并分别处理每一行,但这比基于集合的方法慢得多。