我正在尝试创建一个触发器,当主记录插入主表时,该触发器会在多个表上初始化记录。下面的代码给出错误“对象引用未设置为对象的实例。”
评估是触发器所存在的表,并且每个相关表都有一个AppraisalID外键。
BEGIN TRANSACTION
DECLARE @appraisalid int
SET @appraisalid = (SELECT AppraisalID FROM inserted)
INSERT INTO dbo.AppraisalCPD (AppraisalID)
VALUES (@appraisalid)
COMMIT;
下面的代码可行,但我宁愿使用变量来分配值,因为我需要将行添加到公平的几个表中。
BEGIN
INSERT INTO dbo.AppraisalCPD
(AppraisalID)
SELECT AppraisalID
FROM inserted;
END;
如果有人可以建议使用Appraisal表中的插入行来设置appraisalid变量,以便将行插入到我需要的每个其他表中,那将非常有帮助。
答案 0 :(得分:1)
我假设你在谈论家庭评估。
[评估]表是父母,[所有者] / [位置]是孩子。
这是tempdb中的播放架构。
-- just playing
use tempdb;
go
-- drop table
if object_id('appraisal') > 0
drop table appraisal
go
-- create table - home appraisal
create table appraisal
(
app_id int identity (1,1),
app_request datetime,
app_employee_id int
);
-- drop table
if object_id('owners') > 0
drop table owners
go
-- create table - the owners
create table owners
(
own_id int identity (1,1) primary key,
own_first_nm varchar(64),
own_last_nm varchar(64),
app_id int
);
-- drop table
if object_id('location') > 0
drop table location
go
-- the location
create table location
(
loc_id int identity (1,1) primary key,
loc_street varchar(64),
loc_city varchar(64),
loc_state varchar(2),
loc_zip varchar(9),
app_id int
);
go
通过触发器创建空子记录时,您必须定义默认值或在触发器中提供它们。
另外,我留下设置外键供你处理。
触发器的代码如下所示。
-- The trigger
CREATE TRIGGER DBO.make_empty_children on dbo.appraisal
for insert, update, delete
as
BEGIN
-- nothing to do?
IF (@@rowcount = 0) RETURN;
-- do not count rows
SET NOCOUNT ON;
-- delete
IF NOT EXISTS (SELECT * FROM inserted)
BEGIN
RETURN;
END
-- insert
ELSE IF NOT EXISTS (SELECT * FROM deleted)
BEGIN
-- dummy record for owners
insert into owners
(
own_first_nm,
own_last_nm,
app_id
)
select
'enter first name',
'enter last name',
app_id
from
inserted;
-- dummy record for location
insert into location
(
loc_street,
loc_city,
loc_state,
loc_zip,
app_id
)
select
'enter street',
'enter city',
'ri',
'00000',
app_id
from
inserted;
RETURN;
END
-- update
ELSE
BEGIN
RETURN;
END
END
GO
我将占位符留给DELETE和UPDATE操作。
1 - 您是否要拒绝评估表中id(密钥)的更新。可能不是。这也可以通过外键(FK)来处理(防止)。
2 - 你想级联删除吗?这也可以由FK或触发器中的代码处理。
让我们看不到表格中的记录。
select * from appraisal;
select * from owners;
select * from location;
像Marc / Aaron所说,插入/删除的表是记录集。不是一排。
订单无法保证。如果您希望按app id订单插入记录,请使用订单。
-- Insert 2 records
insert into appraisal
(
app_request,
app_employee_id
)
values
(getdate(), 7),
(dateadd(d, 1, getdate()), 7);
-- Lets see the data
select * from appraisal;
select * from owners;
select * from location;