如果不满足条件,则在SQL中阻止删除语句

时间:2013-08-26 19:05:09

标签: sql-server tsql

我的场景是:我在SQL中有两个表,一个是Header,一个是Detail。当在标题中删除记录时,我也想删除记录的详细信息。在我真正删除详细信息之前,我正在做一些检查。

我的问题是我在检查时根据删除的记录加入Header表,不幸的是,当我这样做时,Header已经被用户的声明删除了。

如果标题不符合必要条件,如何阻止删除标题。标题表的示例:

 Key      |  Status
 -------------------
 001      |  00
 002      |  00
 003      |  40

我的删除声明:

 DELETE FROM HEADER WHERE KEY = '003'

在删除详细信息之前,在删除详细信息之前,我正在检查以确保状态< 40.如果不是这种情况我会抛出一个错误,我怎样才能为Header做同样的事情?

我的代码如下:

 ALTER TRIGGER [dbo].[trg_PO_DELETE]

 ON PO

 AFTER DELETE

 AS

DECLARE
    @Date                   DATETIME
    , @Who                  VARCHAR(20)
    , @ProcessedStatus      CHAR(2)
    , @ProcessingStatus     CHAR(2)
    , @ShmtType             INT
    , @POType               INT
    , @MsgNo                INT
    , @Msg                  VARCHAR(MAX)
    , @Continue             INT

SET @Date                   = CURRENT_TIMESTAMP
SET @Who                    = SYSTEM_USER
SET @ProcessedStatus        = '90'
SET @ProcessingStatus       = '40'
SET @ShmtType               = 3
SET @POType                 = 1
SET @MsgNo                  = 0
SET @Msg                    = ''
SET @Continue               = 0



IF EXISTS(SELECT 1 FROM PO(NOLOCK)
                JOIN DELETED ON PO.po_asn_number = DELETED.po_asn_number
                            AND PO.po_customer_id = DELETED.po_customer_id
                            AND PO.po_number = DELETED.po_number
                            AND PO.po_type = DELETED.po_type
                            AND PO.po_status = DELETED.po_status
            WHERE PO.po_status < @ProcessingStatus)
    BEGIN
        /*  REMOVE SHIPMENT DETAIL WHEN SHIPMENT HEADER IS DELETED  */
        DELETE PO_DETAIL
        FROM PO_DETAIL 
        JOIN DELETED ON PO_DETAIL.pd_asn_number = DELETED.po_asn_number
                    AND PO_DETAIL.pd_customer_id = DELETED.po_customer_id
                    AND PO_DETAIL.pd_po_number = DELETED.po_number
                    AND PO_DETAIL.pd_type = DELETED.po_type

        /*  REMOVE UCC FOR SHIPMENT WHEN SHIPMENT IS DELETED*/ 
        DELETE UCC
        FROM UCC
        JOIN DELETED ON UCC.cs_shipment_number = DELETED.po_asn_number
                    AND UCC.cs_po_number = DELETED.po_number
                    AND DELETED.po_type = @ShmtType

        /*  UPDATE PO LEVEL INFORMATION */
        UPDATE PO 
                SET PO.po_shipped_qty = PO.po_shipped_qty - DELETED.po_shipped_qty
                , PO.po_received_qty = PO.po_received_qty - DELETED.po_received_qty
        FROM PO
        JOIN DELETED ON PO.po_asn_number = DELETED.po_number
                    AND PO.po_number = DELETED.po_number
                    AND PO.po_customer_id = DELETED.po_customer_id
                    AND DELETED.po_type = @POType
    END
ELSE
    BEGIN
        SET @Continue = 1
        SET @MsgNo = 50000
        SET @Msg = dbo.fnc_GetMessage(@MsgNo)
    END
 IF @Continue=1  -- Error Occured
    BEGIN
      RAISERROR @MsgNo @Msg
      RETURN
    END

我认为我的问题是因为在我可以进行加入之前,Header记录已经消失。您提供的任何帮助都会非常有用。

1 个答案:

答案 0 :(得分:0)

尝试使用INSTEAD OF DELETE触发器,如下所示:

CREATE TRIGGER TEST1 
ON DBO.HEADER 
INSTEAD OF DELETE 
AS 
  BEGIN 
      DELETE H 
      FROM   HEADER H 
             INNER JOIN DELETED d 
                     ON H.[KEY] = d.[KEY] 
                        AND H.STATUS < 40 
  END 

GO