2015-05-14 70 views
0

我在通过外部应用程序将数据插入数据库时​​尝试更新记录时遇到问题。在触发器上更新插入的记录

我需要记录从应用程序的用户被插入取值MinimumStock从表AERO_LOCATIONSTOCKMIN上它们是父位置和资产类型

LOCATIONSTOCKMINID ASSETTYPEID LOCATIONID MINIMUMSTOCK 
    54000000001  54000000043 43200000357  12.00 
    54000000002  54000000043 43200000883  6.00 

这是目的:当用户尝试要在Asset表中插入记录(通过外部应用程序),触发器必须检查用户是否已为该Asset选择位置。如果是这样,触发器必须检索所选位置的父级位置,并检查是否存在为此AssetType定义的库存最小值以及此父级位置。

如果全部满足,则触发器必须将字段UDFText01设置为上表中定义的最小库存。

这是我到目前为止尝试过的。触发器正在检查需求,但在尝试更新并引发以下错误时失败:

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; 
+0

是哪个领域的用户输入数据到表中的列UDFText01一个(使用外部应用程序吗?) –

+0

@ S.Krishna是的。 – equisde

+0

我认为在这种情况下,您将需要使用'而不是'触发器。看到这个SO http://stackoverflow.com/questions/5341584/sql-server-after-insert-trigger-update-another-column-in-the-same-table –

回答

1

基础上进一步讨论,在这里看到,如果这样的事情是不是有点接近你正在尝试做的。

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 
+0

非常感谢你@SeanLannge。由于我现在不在办公室,我会尽快尝试解决方案,然后回复我的评论。再次,非常感谢您的时间和奉献! – equisde

+0

经过对表格字段相关性的一些修改(例如:'a.AssetTypeID = i.AssetID'>'a.AssetTypeID = i.AssetTypeID'),您的解决方案工作正常。非常感谢! – equisde