在触发器上更新插入的记录
Update inserted record on a trigger
当通过外部应用程序将记录插入数据库时,我在尝试更新记录时遇到了问题。
我需要从应用程序中的用户插入的记录从 table AERO_LOCATIONSTOCKMIN
中获取值 MinimumStock
,其中包含父位置和资产类型
LOCATIONSTOCKMINID ASSETTYPEID LOCATIONID MINIMUMSTOCK
54000000001 54000000043 43200000357 12.00
54000000002 54000000043 43200000883 6.00
目的是:当用户尝试在 Asset
table 上插入记录(通过外部应用程序)时,触发器必须检查用户是否已为该 [=选择了位置 Asset
。如果是这样,触发器必须检索所选位置的父位置,并检查是否为此 AssetType
和此父位置定义了最低库存。
如果全部满足,触发器必须将字段UDFText01
设置为上述table中定义的最小库存。
这是我到目前为止所尝试过的方法。触发器正在检查要求,但在尝试更新时失败并引发以下错误:
The transaction ended in the trigger. The batch has been aborted
.
我尝试以多种方式修改 UPDATE 语句,但所有方式都引发相同的错误消息。
编辑
按照@Sean Lannge 的建议,我编辑了我的触发器以管理多个插入。触发器不再显示错误消息,但更改(插入)未保存到数据库中。
ALTER TRIGGER [spectwosuite].[TRI_ASSET_STOCKMIN] ON [spectwosuite].[ASSET]
FOR INSERT AS
BEGIN
IF (UPPER(USER) != 'SPECTWOREPLENG')
DECLARE @assettypeid numeric(15);
DECLARE @assetid numeric(15);
DECLARE @locationid numeric(15);
DECLARE @parentlocationid numeric(15);
DECLARE @stockmin numeric(9,2);
DECLARE @mistock varchar(100);
DECLARE crs_ROWS CURSOR FOR
SELECT ASSETID, ASSETTYPEID, LOCATIONID
FROM inserted;
OPEN crs_ROWS;
FETCH NEXT FROM crs_ROWS INTO @assetid, @assettypeid, @locationid
WHILE (@@FETCH_STATUS = 0)
BEGIN
SELECT @parentlocationID = ParentLocationID FROM Location
LEFT JOIN Asset ON Asset.LocationID = Location.LocationID
WHERE Asset.LocationID = @locationid;
IF NOT EXISTS
(SELECT * FROM Location LEFT JOIN INSERTED AS i ON Location.LocationID = i.LocationID
WHERE Location.LocationID = i.LocationID)
BEGIN
RAISERROR ('Please fill the Location for the Asset.',16,1);
ROLLBACK;
END
ELSE
IF EXISTS (SELECT MinimumStock FROM AERO_LOCATIONSTOCKMIN
WHERE AssetTypeID = @assettypeid AND LocationID = (SELECT ParentLocationID FROM Location WHERE LocationID = @locationID))
BEGIN
SELECT @stockmin = MinimumStock FROM AERO_LOCATIONSTOCKMIN
WHERE AssetTypeID = @assetTypeID AND LocationID =
(SELECT ParentLocationID FROM Location WHERE LocationID = @locationID);
SELECT @mistock= CONVERT(varchar(100),@stockmin);
--RAISERROR (@mistock,16,1);
UPDATE spectwosuite.ASSET
SET UDFText01 = @mistock
FROM
INSERTED I
INNER JOIN spectwosuite.ASSET T ON
T.AssetID = I.AssetID
--UPDATE spectwosuite.ASSET SET UDFText01 = @mistock
-- FROM spectwosuite.ASSET AS A INNER JOIN inserted AS I
-- ON A.AssetID = I.AssetID;
END
ELSE
RAISERROR ('The parent Location for the Asset Type doesn't have minimum stock defined',16,1);
ROLLBACK;
FETCH NEXT FROM crs_ROWS INTO @assetid, @assettypeid, @locationid;
END;
CLOSE crs_ROWS;
DEALLOCATE crs_ROWS;
END;
根据此处的扩展讨论,看看这样的事情是否更接近您正在尝试做的事情。
ALTER TRIGGER [spectwosuite].[TRI_ASSET_STOCKMIN] ON [spectwosuite].[ASSET] FOR INSERT AS
IF (UPPER(USER) != 'SPECTWOREPLENG')
BEGIN
create table #MyInsertedCopy
(
--whatever columns go here that you want to display for error rows
ErrorMessage varchar(50)
)
insert #MyInsertedCopy
select i.* --use your real columns, not *
, 'Please fill the Location for the Asset' as ErrorMessage
from inserted i
left join Location l on l.LocationID = i.LocationID
where l.LocationID IS NULL
insert #MyInsertedCopy
select i.* --use your real columns, not *
, 'The parent location for that Asset doesn''t have minimum stock defined' as ErrorMessage
from inserted i
left join AERO_LOCATIONSTOCKMIN a on a.AssetTypeID = i.AssetID
left join Location l on l.ParentLocationID = i.LocationID
where a.AssetTypeID is NULL
update a
set UDFText01 = MinimumStock
FROM INSERTED I
INNER JOIN spectwosuite.ASSET T ON T.AssetID = I.AssetID
INNER JOIN AERO_LOCATIONSTOCKMIN a on a.AssetTypeID = i.AssetID
INNER JOIN Location l on l.ParentLocationID = i.LocationID
IF EXISTS(select * from #MyInsertedCopy)
--do something to report that there are rows that failed
select * from #MyInsertedCopy
END
当通过外部应用程序将记录插入数据库时,我在尝试更新记录时遇到了问题。
我需要从应用程序中的用户插入的记录从 table AERO_LOCATIONSTOCKMIN
中获取值 MinimumStock
,其中包含父位置和资产类型
LOCATIONSTOCKMINID ASSETTYPEID LOCATIONID MINIMUMSTOCK
54000000001 54000000043 43200000357 12.00
54000000002 54000000043 43200000883 6.00
目的是:当用户尝试在 Asset
table 上插入记录(通过外部应用程序)时,触发器必须检查用户是否已为该 [=选择了位置 Asset
。如果是这样,触发器必须检索所选位置的父位置,并检查是否为此 AssetType
和此父位置定义了最低库存。
如果全部满足,触发器必须将字段UDFText01
设置为上述table中定义的最小库存。
这是我到目前为止所尝试过的方法。触发器正在检查要求,但在尝试更新时失败并引发以下错误:
The transaction ended in the trigger. The batch has been aborted
.
我尝试以多种方式修改 UPDATE 语句,但所有方式都引发相同的错误消息。
编辑
按照@Sean Lannge 的建议,我编辑了我的触发器以管理多个插入。触发器不再显示错误消息,但更改(插入)未保存到数据库中。
ALTER TRIGGER [spectwosuite].[TRI_ASSET_STOCKMIN] ON [spectwosuite].[ASSET]
FOR INSERT AS
BEGIN
IF (UPPER(USER) != 'SPECTWOREPLENG')
DECLARE @assettypeid numeric(15);
DECLARE @assetid numeric(15);
DECLARE @locationid numeric(15);
DECLARE @parentlocationid numeric(15);
DECLARE @stockmin numeric(9,2);
DECLARE @mistock varchar(100);
DECLARE crs_ROWS CURSOR FOR
SELECT ASSETID, ASSETTYPEID, LOCATIONID
FROM inserted;
OPEN crs_ROWS;
FETCH NEXT FROM crs_ROWS INTO @assetid, @assettypeid, @locationid
WHILE (@@FETCH_STATUS = 0)
BEGIN
SELECT @parentlocationID = ParentLocationID FROM Location
LEFT JOIN Asset ON Asset.LocationID = Location.LocationID
WHERE Asset.LocationID = @locationid;
IF NOT EXISTS
(SELECT * FROM Location LEFT JOIN INSERTED AS i ON Location.LocationID = i.LocationID
WHERE Location.LocationID = i.LocationID)
BEGIN
RAISERROR ('Please fill the Location for the Asset.',16,1);
ROLLBACK;
END
ELSE
IF EXISTS (SELECT MinimumStock FROM AERO_LOCATIONSTOCKMIN
WHERE AssetTypeID = @assettypeid AND LocationID = (SELECT ParentLocationID FROM Location WHERE LocationID = @locationID))
BEGIN
SELECT @stockmin = MinimumStock FROM AERO_LOCATIONSTOCKMIN
WHERE AssetTypeID = @assetTypeID AND LocationID =
(SELECT ParentLocationID FROM Location WHERE LocationID = @locationID);
SELECT @mistock= CONVERT(varchar(100),@stockmin);
--RAISERROR (@mistock,16,1);
UPDATE spectwosuite.ASSET
SET UDFText01 = @mistock
FROM
INSERTED I
INNER JOIN spectwosuite.ASSET T ON
T.AssetID = I.AssetID
--UPDATE spectwosuite.ASSET SET UDFText01 = @mistock
-- FROM spectwosuite.ASSET AS A INNER JOIN inserted AS I
-- ON A.AssetID = I.AssetID;
END
ELSE
RAISERROR ('The parent Location for the Asset Type doesn't have minimum stock defined',16,1);
ROLLBACK;
FETCH NEXT FROM crs_ROWS INTO @assetid, @assettypeid, @locationid;
END;
CLOSE crs_ROWS;
DEALLOCATE crs_ROWS;
END;
根据此处的扩展讨论,看看这样的事情是否更接近您正在尝试做的事情。
ALTER TRIGGER [spectwosuite].[TRI_ASSET_STOCKMIN] ON [spectwosuite].[ASSET] FOR INSERT AS
IF (UPPER(USER) != 'SPECTWOREPLENG')
BEGIN
create table #MyInsertedCopy
(
--whatever columns go here that you want to display for error rows
ErrorMessage varchar(50)
)
insert #MyInsertedCopy
select i.* --use your real columns, not *
, 'Please fill the Location for the Asset' as ErrorMessage
from inserted i
left join Location l on l.LocationID = i.LocationID
where l.LocationID IS NULL
insert #MyInsertedCopy
select i.* --use your real columns, not *
, 'The parent location for that Asset doesn''t have minimum stock defined' as ErrorMessage
from inserted i
left join AERO_LOCATIONSTOCKMIN a on a.AssetTypeID = i.AssetID
left join Location l on l.ParentLocationID = i.LocationID
where a.AssetTypeID is NULL
update a
set UDFText01 = MinimumStock
FROM INSERTED I
INNER JOIN spectwosuite.ASSET T ON T.AssetID = I.AssetID
INNER JOIN AERO_LOCATIONSTOCKMIN a on a.AssetTypeID = i.AssetID
INNER JOIN Location l on l.ParentLocationID = i.LocationID
IF EXISTS(select * from #MyInsertedCopy)
--do something to report that there are rows that failed
select * from #MyInsertedCopy
END