2

SQL Server 2016 RC 2 でメモリ最適化テーブルの削除トリガーを作成しようとしています。

CREATE TRIGGER  [dbo].[TestCascadeDelete]
ON [CAMSII].[dbo].[Table1]  
WITH NATIVE_COMPILATION, SCHEMABINDING
FOR DELETE

AS BEGIN ATOMIC WITH
(
 TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english'
)

DELETE [dbo].[Table2] 
WHERE [dbo].[Table2].Id IN(SELECT Id from DELETED)

END
GO

このクエリを実行すると、次のエラーが発生します。サブクエリ (別のクエリ内にネストされたクエリ) は、ネイティブにコンパイルされたモジュールを含む SELECT ステートメントでのみサポートされます。

4

2 に答える 2

2

ネイティブにコンパイルされたストアド プロシージャではサブクエリを使用できないため、今日、これを回避するために簡単なトリックを行いました。

シナリオは、Master Child テーブルからの削除です。

row exist in parent -> capture id;

while (rowcount <> 0)
begin
      delete from child where id = idcaptured;
      delete from master where id = idcaptured;

      row exist in parent -> capture id;
end;
于 2016-12-06T19:34:58.657 に答える
0

回避策は、テーブル変数を使用し、WHILE ループで行を反復処理することです。FROM 回避策を使用した UPDATE の例を次に示します。

DROP TABLE IF EXISTS dbo.table1
GO
DROP TYPE IF EXISTS dbo.type1
GO


CREATE TABLE dbo.table1
(Id INT NOT NULL PRIMARY KEY NONCLUSTERED,
c2 INT NOT NULL,
LastUpdated DATETIME2 NOT NULL DEFAULT (SYSDATETIME())) 
WITH (MEMORY_OPTIMIZED=ON)
GO
CREATE TYPE dbo.type1 AS TABLE
(Id INT NOT NULL,
c2 INT NOT NULL,
RowID INT IDENTITY,
  INDEX ix_RowID (RowID DESC)) 
WITH (MEMORY_OPTIMIZED=ON)
GO
CREATE TRIGGER dbo.tr_table1
     ON dbo.table1
     WITH NATIVE_COMPILATION, SCHEMABINDING
     AFTER UPDATE
AS BEGIN ATOMIC WITH
(
TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english'
)
     -- original UPDATE with FROM statement:
     --UPDATE dbo.table1
     --SET LastUpdated = SYSDATETIME()
     --FROM dbo.table1 t JOIN Inserted i ON t.Id=i.Id

     DECLARE @tv dbo.type1
     INSERT @tv (Id, c2) 
     SELECT Id, c2 FROM Inserted


     -- workaround that iterates over the rows in the table variable, simulating a cursor:
     DECLARE @max INT = SCOPE_IDENTITY()

     DECLARE @i INT = 1
     DECLARE @Id INT

     WHILE @i <= @max
     BEGIN
         SELECT @Id = Id
         FROM @tv
         WHERE RowID=@i

         UPDATE dbo.table1
         SET LastUpdated = SYSDATETIME()
         WHERE Id = @Id

         SET @i += 1
     END

END
GO

INSERT dbo.table1 (Id, c2) VALUES (1,2)
INSERT dbo.table1 (Id, c2) VALUES (2,2)
GO
SELECT * FROM dbo.table1
GO
UPDATE dbo.table1
SET c2 = 3
GO
SELECT * FROM dbo.table1
GO
于 2016-04-27T00:35:37.277 に答える