0

Ich versuche, einen DELETE-Trigger für eine Speicher Optimierte Tabelle in SQL Server 2016 RC 2löschen Auslöser für Speicher Optimierte Tabelle

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 

zu schreiben, wenn ich diese Abfrage leite ich folgende Fehler. Unterabfragen (Abfragen, die in einer anderen Abfrage verschachtelt sind) werden nur in SELECT-Anweisungen mit nativ kompilierten Modulen unterstützt.

+0

DELETE FROM [dbo] [Tabelle 2] FROM dbo.Table2 AS t2 d ON t2.Id = d.id' – lad2025

+0

@ lad2025 gelöscht werde ich Mitglied Ich habe das schon einmal ausprobiert und probiert es auch wieder, aber FROM Clause ist auch in Native Compiled Modules nicht erlaubt. Hier ist der neue Fehler 'Die Verwendung der FROM-Klausel in einer UPDATE-Anweisung und Angabe einer Tabellenquelle in einer DELETE-Anweisung wird von nativ kompilierten Modulen nicht unterstützt.' –

Antwort

0

Die Problemumgehung besteht darin, eine Tabellenvariable zu verwenden und über die Zeilen mit einer WHILE-Schleife zu iterieren. Hier ist ein Beispiel für ein Update mit FROM Abhilfe:

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 [email protected] 

     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 
0

ich heute einen einfachen Trick tat für um diese Arbeit, da ich nicht Unterabfragen in einem nativ kompilierten gespeicherten Prozedur verwenden kann.

Szenario ist von Master-Child-Tabellen löschen.

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;