简体   繁体   English

Memory 优化表上的条件唯一约束

[英]Conditional Unique Constraint on Memory Optimized Tables

I am trying to keep integrity in a MEMORY OPTIMIZED table I have.我试图在我拥有的 MEMORY OPTIMIZED 表中保持完整性。 In that table is a foreign key (uniqueidentifier) that points to another table and an Active flag (bit) denoting whether the record is active or not.该表中有一个指向另一个表的外键(唯一标识符)和一个表示记录是否处于活动状态的活动标志(位)。

I want to stop inserts from happening if the incoming record has the same foreign key as an existing record, only if the existing record is active (Active = 1).如果传入记录与现有记录具有相同的外键,我想阻止插入发生,前提是现有记录处于活动状态(Active = 1)。

Because this is a memory optimized table, I am limited in how I can go about this.因为这是一个 memory 优化表,所以我对 go 的了解有限。 I have tried creating a unique index and discovered they are not allowed in memory optimized tables.我尝试创建一个唯一索引,发现它们在 memory 优化表中是不允许的。

UPDATE: I ended up using a stored procedure to solve my problem.更新:我最终使用存储过程来解决我的问题。 The stored procedure will do the check for me prior to the insert or update of a record.存储过程将在插入或更新记录之前为我进行检查。

Most folks get around the limitations of In-Memory table constraints using triggers.大多数人使用触发器绕过内存表约束的限制。 There are a number of examples listed here:这里列出了许多示例:

https://www.mssqltips.com/sqlservertip/3080/workaround-for-lack-of-support-for-constraints-on-sql-server-memoryoptimized-tables/ https://www.mssqltips.com/sqlservertip/3080/workaround-for-lack-of-support-for-constraints-on-sql-server-memoryoptimized-tables/

Specifically for your case this will mimic a unique constraint for insert statements but the poster has examples for update and delete triggers as well in the link above.特别是对于您的情况,这将模拟插入语句的唯一约束,但海报在上面的链接中也有更新和删除触发器的示例。

-- note the use of checksum to make a single unique value from the combination of two columns

CREATE TRIGGER InMemory.TR_Customers_Insert ON InMemory.Customers
 WITH EXECUTE AS 'InMemoryUsr'
  INSTEAD OF INSERT  
AS
 SET NOCOUNT ON
 --CONSTRAINT U_OnDisk_Customersg_1 UNIQUE NONCLUSTERED (CustomerName, CustomerAddress)
  IF EXISTS (
    -- Check if rows to be inserted are consistent with CHECK constraint by themselves
    SELECT 0
        FROM  INSERTED I
    GROUP BY CHECKSUM(I.CustomerName, I.CustomerAddress) 
    HAVING COUNT(0) > 1
    UNION ALL

       -- Check if rows to be inserted are consistent with UNIQUE constraint with existing data
    SELECT 0
        FROM  INSERTED I
    INNER JOIN InMemory.tblCustomers C WITH (SNAPSHOT)
      ON  C.ChkSum = CHECKSUM(I.CustomerName, I.CustomerAddress)
    ) 
    BEGIN
      ;THROW 50001, 'Violation of UNIQUE Constraint! (CustomerName, CustomerAddress)', 1
    END
  INSERT INTO InMemory.tblCustomers WITH (SNAPSHOT)
      ( CustomerID ,
       CustomerName ,
       CustomerAddress,
    chksum
      )
  SELECT  NEXT VALUE FOR InMemory.SO_Customers_CustomerID ,
      CustomerName ,
      CustomerAddress,
   CHECKSUM(CustomerName, CustomerAddress)
 FROM INSERTED
 GO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM