TSQL变量对象引用未设置为对象的实例

时间:2014-02-01 20:11:23

标签: sql-server tsql variables triggers nullreferenceexception

我正在尝试创建一个触发器,当主记录插入主表时,该触发器会在多个表上初始化记录。下面的代码给出错误“对象引用未设置为对象的实例。”

评估是触发器所存在的表,并且每个相关表都有一个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变量,以便将行插入到我需要的每个其他表中,那将非常有帮助。

1 个答案:

答案 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;

enter image description here

像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;

enter image description here