防止插入没有触发器的列

时间:2018-01-14 08:30:24

标签: sql-server tsql

我在表格中有两个字段,Column1和Column2

Column1 | Column2
-------------------
 F      |   B
 A      |   C
--------------
 B           F    needs prevention
 C           A    needs prevention

如何在没有触发器的情况下阻止(B,F)和(C,A)插入?

3 个答案:

答案 0 :(得分:1)

所以基本上你想要防止插入与你已经拥有的行完全相反。

一种方法是添加一个检查约束和一个唯一索引:

CREATE TABLE dbo.MyTable
(
    Column1 char(1) NOT NULL,
    Column2 char(1) NOT NULL,
    CONSTRAINT chk_Col1AndCol2 CHECK(Column1 <= Column2)
);
GO

CREATE UNIQUE INDEX UX_MyTable 
    ON dbo.MyTable (Column1, Column2);
GO

此检查约束阻止Column1保存大于Column2中值的值。

如果您不想将column1限制为小于或等于column2, 另一种选择是使用具有用户定义功能的检查约束:

CREATE TABLE dbo.MyTable
(
    Column1 char(1) NOT NULL,
    Column2 char(1) NOT NULL
);
GO

CREATE UNIQUE INDEX UX_MyTable  -- Again, same unique index
    ON dbo.MyTable (Column1, Column2);
GO

CREATE FUNCTION fn_CheckMyTable
(
    @Column1 char(1),
    @Column2 char(1)
)
RETURNS int
AS
BEGIN

    RETURN 
    (
        SELECT COUNT(*)
        FROM MyTable
        WHERE Column1 = @Column2
        AND Column2 = @Column1
    )

END;
GO

ALTER TABLE MyTable
    ADD CONSTRAINT chk_MyTable1 CHECK(dbo.fn_CheckMyTable(Column1, Column2) = 0);
GO

答案 1 :(得分:0)

您可以尝试使用以防止这种情况 check constraint

CREATE TABLE MY_TABLE (
    COLUMN1 varchar(255) NOT NULL,
    COLUMN2 varchar(255) NOT NULL,
    CONSTRAINT MY_CONSTRAINT CHECK ((COLUMN1, COLUMN2) NOT IN (('B','F'), ('C','A')))
);

当然语法可能因提供商而异。

答案 2 :(得分:0)

您可以使用TRIGGER_NESTLEVEL

CREATE TABLE t(col1 CHAR(5), col2 CHAR(5));
CREATE TABLE t_helper(i CHAR(5));

CREATE TRIGGER trg_t_helper ON t_helper
AFTER INSERT
AS
BEGIN
   INSERT INTO t(col1, col2)
   SELECT i, 'B'
   FROM inserted;
END;


CREATE TRIGGER trg_t ON t
AFTER INSERT
AS
BEGIN
  IF ((SELECT TRIGGER_NESTLEVEL( OBJECT_ID('trg_t_helper'),'AFTER', 'DML'))= 0)  
  RAISERROR('Direct data insert are disabled.',16,-1);
END;

检查:

INSERT INTO t_helper(i) VALUES ('Z');

SELECT * FROM t;
--col1  col2
--Z     B  

INSERT INTO t(col1, col2) VALUES ('A', 'B');
  

Msg 50000 Level 16 State 1 Line 6

     

禁用直接数据插入。

<强> DBFiddle Demo