8

期日が設定された日付と等しい場合、SQL トリガーを解決してユーザーをブロックするように自動的に設定し、別のテーブルに日付を含むブロック レコードを作成しようとすると、いくつかの問題が発生します。

問題は、トリガーが挿入によってオフに設定されると、印刷ステートメントが実行され、挿入が発生しますが、テーブルへの挿入は行われないか、更新ステートメントですか? 誰でも理由を説明できますか?

注: 単独で実行する場合、insert ステートメントと Update ステートメントはどちらも問題ありません。

アカウントテーブル

CREATE TABLE [dbo].[Account](
[AccountNo] [int] IDENTITY(1,1) NOT NULL,
[CustomerNo] [int] NOT NULL,
[PaymentNo] [int] NULL,
[CreditNo] [int] NULL,
[BlockID] [dbo].[number] NULL,
[Balence] [dbo].[currency] NOT NULL,
[AmountDue] [dbo].[currency] NOT NULL,
[DueDate] [dbo].[dates] NULL,
[AutherisedBy] [nvarchar](50) NOT NULL,
[DateCreated] [date] NOT NULL,

ブロックされたユーザー テーブル

CREATE TABLE [dbo].[BlockedUsers](
[BlockID] [int] IDENTITY(1,1) NOT NULL,
[DateEnforced] [dbo].[dates] NOT NULL,
[Blocked] [dbo].[switch] NOT NULL,

引き金

ALTER TRIGGER [dbo].[Add_Blocked_User]
ON [dbo].[Account]
FOR INSERT
AS  
BEGIN
SET NOCOUNT ON;

Declare @ID int
Select @ID = [AccountNo] from inserted  
If(Select [DueDate] from inserted) = '2011-01-01'

INSERT INTO dbo.BlockedUsers(DateEnforced,Blocked)
VALUES (GETDATE(),1)
PRINT 'New Block Date Added'

UPDATE Account 
Set BlockID = IDENT_CURRENT('BlockID')
where @ID = @ID
PRINT 'Account Blocked'

END

GO

完全に機能する例: 以下のヘルプを使用して完了。

ALTER TRIGGER [dbo].[Add_Blocked_User]
ON [dbo].[Account]
AFTER INSERT
AS 
BEGIN

SET NOCOUNT ON;

Declare @ID int
Select @ID = [AccountNo] from inserted  
 If(Select [DueDate] from inserted)Not Between (select CONVERT(date, getdate() - 30)) And (select CONVERT(date, getdate()))
Begin
    INSERT INTO dbo.BlockedUsers(DateEnforced,Blocked)
    VALUES (GETDATE(),1)
    PRINT 'New Block Date Added'

    UPDATE Account 
    Set BlockID = (Select Max(BlockID) From BlockedUsers)
    where [AccountNo] = (Select [AccountNo] from inserted)  
    PRINT 'Account Blocked'
 End

 END

GO
4

2 に答える 2

6

IFTransact-SQLのステートメントでは、条件の後に次の 1 つのステートメントが必要です。

IF condition
  statement;

BEGIN同じブランチで複数のステートメントを実行する場合は、それらを/ END"大括弧"で囲む必要があります。

IF condition
BEGIN
  statement;
  statement;
  ...
END;

トリガーでは、条件の結果に応じて INSERT ステートメントのみが実行され(Select [DueDate] from inserted) = '2011-01-01'ます。PRINT と UPDATE はどちらも無条件に実行されますAccount。したがって、おそらくINSERT、UPDATE、および両方の PRINTBEGINを追加する必要があります。END

...
If(Select [DueDate] from inserted) = '2011-01-01'
BEGIN
INSERT INTO dbo.BlockedUsers(DateEnforced,Blocked)
VALUES (GETDATE(),1);
PRINT 'New Block Date Added';

UPDATE Account 
Set BlockID = IDENT_CURRENT('BlockID')
where @ID = @ID;
PRINT 'Account Blocked';
END;
...
于 2012-12-16T02:12:44.470 に答える
-2

あなたがした

FOR INSERT

使いたい

AFTER INSERT, UPDATE

FOR INSERT は、トリガーが通常の挿入操作を完全に置き換えることを Sql Server に伝えます。AFTER INSERT は、先に進んで行を挿入し、後処理ステップとしてこのコードを実行するように Sql Server に指示します。

于 2012-12-16T00:28:07.143 に答える