【问题标题】:Delete Trigger for Memory Optimized Table内存优化表的删除触发器
【发布时间】:2016-04-09 22:45:25
【问题描述】:

我正在尝试为 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 语句中受支持。

【问题讨论】:

  • DELETE FROM [dbo].[Table2] FROM dbo.Table2 AS t2 JOIN deleted d ON t2.Id = d.id
  • @lad2025 我曾尝试过,也曾多次尝试过,但本机编译模块中也不允许使用 FROM 子句。这是新的错误Using the FROM clause in an UPDATE statement and specifying a table source in a DELETE statement is not supported with natively compiled modules.

标签: in-memory database-trigger sql-server-2016 memory-optimized-tables


【解决方案1】:

我今天做了一个简单的技巧来解决这个问题,因为我不能在本机编译的存储过程中使用子查询。

场景是从主子表中删除:

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;

【讨论】:

    【解决方案2】:

    解决方法是使用表变量并使用 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
    

    【讨论】:

      猜你喜欢
      • 2018-10-09
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-02
      相关资源
      最近更新 更多