0

オンボードのトリガーを使用して単純な t-sql スクリプトの問題を解決するのを手伝ってくれる人はいますか? 非常に単純なトリガーを使用して、あるテーブルから別のテーブルにデータをコピーします (これらのテーブル間に関係はありません)。(同じスクリプトから) トリガーを作成した直後に最初にデータを挿入しようとすると、望ましい結果が得られますが、次のすべての試みは失敗し、次のプロンプトが表示The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.されます。以下のトリガーを見てください。

CREATE TRIGGER AuthorInsert ON Author
INSTEAD OF INSERT
AS
BEGIN -- //- 1 -//
--***************** if insert was correct ********************
    IF (SELECT COUNT(*) FROM INSERTED) > 0
    BEGIN --//- 2 -//
        DECLARE @id int, @roleId int;
        DECLARE @nameId int, @reestrCodeId int, @passportDataId int, @addressId int, @phoneId int;
        SET @nameId = (SELECT INSERTED.NameID FROM INSERTED);
        SET @reestrCodeId = (SELECT INSERTED.ReestrCodeID FROM INSERTED);
        SET @passportDataId = (SELECT INSERTED.PassportDataID FROM INSERTED);
        SET @addressId = (SELECT INSERTED.AddressID FROM INSERTED);
        SET @phoneId = (SELECT INSERTED.PhoneID FROM INSERTED);
        BEGIN TRY
            INSERT INTO Role(RoleName) VALUES('Author');
        END TRY
        BEGIN CATCH
        END CATCH
        SET @roleId = (SELECT Role.RoleID FROM Role WHERE Role.RoleName = 'Author');
        INSERT INTO Employee(NameID, ReestrCodeID, RoleID, PassportDataID, AddressID, PhoneID)VALUES
                            (@nameId, @reestrCodeId, @roleId, @passportDataId, @addressId, @phoneId);
        SET @id = (SELECT Employee.EmployeID FROM Employee WHERE Employee.EmployeID = @@IDENTITY) + 1;
        INSERT INTO Author VALUES(@id, @nameId, @reestrCodeId, @passportDataId, @addressId, @phoneId);
    END -- //- 2 -//
END -- //- 1 -//

テーブルの図は非常に原始的であるため、投稿する理由はありません(上記のように、これらのテーブル間に直接的な関係はありません)。私のスクリプトのどこが間違っていて、実際にその奇妙なエラーが何を意味するのでしょうか?

4

1 に答える 1

3

BEGIN TRYブロックのポイントがわかりません。Role名前付きがあることを確認したいのは明らかですがAuthor、毎回トリガーでこれをチェックする必要がありますか? 今すぐ入力して、もう一度確認する必要はありませんか?

CREATE TRIGGER dbo.AuthorInsert ON dbo.Author INSTEAD OF INSERT
AS
BEGIN
  SET NOCOUNT ON;
  IF EXISTS (SELECT 1 FROM inserted)
  BEGIN
    DECLARE @emps TABLE(id INT, NameID INT);
    DECLARE @RoleID INT;    
    SELECT @RoleID = RoleID FROM dbo.Roles WHERE RoleName = 'Author';
  
    IF @RoleID IS NULL
    BEGIN
      -- probably not necessary to do this over and over again
      -- unless someone is sabotaging your Roles table.
      INSERT dbo.Roles(RoleName) SELECT 'Author';
      SELECT @RoleID = SCOPE_IDENTITY();
    END
  
    INSERT dbo.Employee(NameID, ReestrCodeID, RoleID, PassportDataID, 
      AddressID, PhoneID) OUTPUT inserted.EmployeeID, inserted.NameID 
      INTO @emps SELECT NameID, ReestrCodeID, @RoleID, PassportDataID, 
       AddressID, PhoneID FROM inserted;
  
    -- this seems redundant. If an author is linked to an employee, 
    -- why do we need to store all of this information again?
    INSERT dbo.Author(EmployeeID, NameID, ReestrCodeID, RoleID, 
      PassportDataID, AddressID, PhoneID)
      SELECT e.id, i.NameID, i.ReestrCodeID, @RoleID, 
        i.PassportDataID, i.AddressID, i.PhoneID FROM @emps AS e
        INNER JOIN inserted AS i ON e.NameID = i.NameID;
  END
END
GO
于 2013-03-12T22:40:18.227 に答える