【问题标题】:How to make a trigger(insert,update) to check if rows are equal如何制作触发器(插入,更新)以检查行是否相等
【发布时间】:2023-01-30 10:55:16
【问题描述】:

使用触发器(更新和插入)来防止将两个不兼容的组件插入到同一装配体中,而不管它们的添加顺序如何。

我有一个包含 OrderID 和 ProductID 列的表 Order,以及另一个包含 3 列 nvarchar 类型的表 Compactibility 以检查可压缩性。

如何触发以比较具有相同 OrderID 的产品并检查字符串 (编辑:这不是完整的数据库,只是重要的数据)

CREATE TABLE Compactibility(
  IDProduct int NOT NULL FOREIGN KEY REFERENCES
  Produto(IDProduto),
  Caixa nvarchar(50) NOT NULL CHECK (Caixa IN  ('ATX', 'Micro-ATX', 'ALL')), 
  Socket nvarchar(50) NOT NULL CHECK (Socket IN ('LGA2066','LGA1700', 'A76M', 'NONE')),
  TipoRAM nvarchar(7) NOT NULL CHECK (TipoRAM IN ('NONE','DDR4','DDR5')),
)
GO

CREATE TABLE Order(
  IDOrder int NOT NULL PRIMARY KEY identity(1,1),
  IDProduct int FOREIGN KEY REFERENCES Product(IDProduct)
)
GO

【问题讨论】:

  • 我建议您应该使用表来处理 Sockets、RamType、CaseType 等内容。然后你会为这个表创建外键。考虑一下一旦发布了一种新型 RAM,这种设计将是多么痛苦。如果你已经正确规范化了所有你需要做的就是在 RamType 表中添加一行,一切都会正常工作。
  • 你能触发 Compactibility 的插入吗?在触发器代码中,检查产品 ID 是否也出现在订单表中的任何订单中。
  • 我为每个组件都有一个表,但我没有时间,这是我的第一个 sql 项目,所以我做的有点简单
  • 使用触发器来强制执行参照完整性是一个非常明显的标志,表明某些地方在设计中走错了方向。触发器可能有用,但不能确保数据正确。这就是约束的作用。
  • “检查字符串”不够清楚。以什么方式检查它们?

标签: sql sql-server database


【解决方案1】:
USE db_TI1;
GO

CREATE TRIGGER tr_c
ON ProdutoVenda
AFTER INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @IDProduto1 INT, @IDEncomenda INT, @IDProduto2 INT, 
            @Caixa1 NVARCHAR(50), @Caixa2 NVARCHAR(50), 
            @Socket1 NVARCHAR(50), @Socket2 NVARCHAR(50), 
            @TipoRam1 NVARCHAR(50), @TipoRam2 NVARCHAR(50);

    SET @IDProduto1 = (SELECT TOP 1 IDProduto FROM inserted);
    SET @IDEncomenda = (SELECT TOP 1 IDEncomenda FROM inserted);
    SET @IDProduto2 = (SELECT TOP 1 IDProduto FROM ProdutoVenda WHERE IDEncomenda = @IDEncomenda AND Montagem >= 1 AND IDProduto <> @IDProduto1);

    IF @IDEncomenda IS NOT NULL
    BEGIN
        SET @Caixa1 = (SELECT Caixa FROM Compactibilidade WHERE IDProduto = @IDProduto1);
        SET @Socket1 = (SELECT Socket FROM Compactibilidade WHERE IDProduto = @IDProduto1);
        SET @TipoRam1 = (SELECT TipoRAM FROM Compactibilidade WHERE IDProduto = @IDProduto1);

        SET @Caixa2 = (SELECT Caixa FROM Compactibilidade WHERE IDProduto = @IDProduto2);
        SET @Socket2 = (SELECT Socket FROM Compactibilidade WHERE IDProduto = @IDProduto2);
        SET @TipoRam2 = (SELECT TipoRAM FROM Compactibilidade WHERE IDProduto = @IDProduto2);

        IF NOT EXISTS (
            SELECT 1 
            FROM Compactibilidade 
            WHERE (Caixa = @Caixa1 AND Caixa = @Caixa2) 
              AND (Socket = @Socket1 AND Socket = @Socket2) 
              AND (TipoRAM = @TipoRam1 AND TipoRAM = @TipoRam2)
        ) 
        
        AND @IDProduto1 = @IDProduto2 
        AND @Caixa1 = @Caixa2  OR @Caixa1 NOT IN ('ALL') OR @Caixa1 NOT IN ('ALL')
        AND @Socket1 = @Socket2  OR @Socket1 NOT IN ('NONE') OR @Socket2 NOT IN ('NONE')
        AND @TipoRam1 = @TipoRam2 OR @TipoRam1 NOT IN ('NONE') OR @TipoRam2 NOT IN ('NONE')
        
        BEGIN
            RAISERROR('Componente Incompatível!', 16, 1);
            ROLLBACK TRANSACTION;
        END
    END
END;
GO

UPDATE ProdutoVenda SET IDEncomenda = 1766 WHERE IDProduto = 1
SELECT *
FROM ProdutoVenda

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    相关资源
    最近更新 更多