Sql server SQL Server:检查约束是否存在关系,否则插入

Sql server SQL Server:检查约束是否存在关系,否则插入,sql-server,Sql Server,我试图创建一个约束来验证关系是否存在 我尝试创建一个过程,然后在检查约束中使用它。显然,这似乎不起作用 这些是我的桌子: STOCKITEMS表格: StockItemId INT StockItemName VARCHAR ColorId INT ColorId INT ColorName VARCHAR 颜色表格: StockItemId INT StockItemName VARCHAR ColorId

我试图创建一个约束来验证关系是否存在

我尝试创建一个过程,然后在检查约束中使用它。显然,这似乎不起作用

这些是我的桌子:

STOCKITEMS
表格:

StockItemId      INT
StockItemName    VARCHAR
ColorId          INT
ColorId          INT
ColorName        VARCHAR
颜色
表格:

StockItemId      INT
StockItemName    VARCHAR
ColorId          INT
ColorId          INT
ColorName        VARCHAR
这是我的存储过程:

CREATE PROCEDURE USP_ValidateColor
    (@Color NVARCHAR(50))
AS
    IF NOT EXISTS(SELECT ColorName FROM WareHouse.Colors WHERE ColorName = @Color) 
    BEGIN
        DECLARE @Id INT
        SET @Id = (SELECT TOP(1) ColorId + 1 FROM Warehouse.Colors 
                    ORDER BY ColorId DESC)

        INSERT INTO Warehouse.Colors 
        VALUES (@Id, @Color)

        PRINT 'Does not exist'; 
    END;
    ELSE 
        PRINT 'Exists'; 
因此,如果用户在表stock items中插入,我需要检查
colorId
是否已经存在于color表中


如果没有,则将该
colorname
插入到颜色和中。我曾考虑在我的过程中使用约束检查,但无法修复查询

不要使用SP检查约束,请使用外键:

CREATE TABLE Colour (ColourID int PRIMARY KEY, --This should really have a name
                     ColourName varchar(20));

CREATE TABLE StockItem (StockItemID int PRIMARY KEY, --This should really have a name too
                        StockItemName varchar(20),
                        ColourID int);

ALTER TABLE dbo.StockItem ADD CONSTRAINT Colour_FK FOREIGN KEY (ColourID) REFERENCES dbo.Colour(ColourID);
然后,如果您试图在
StockItem
表中插入某些内容,则除非颜色存在,否则将失败:

INSERT INTO dbo.Colour (ColourID,
                        ColourName)
VALUES (1,'Green'),(2,'Blue');
GO

INSERT INTO dbo.StockItem (StockItemID,
                           StockItemName,
                           ColourID)
VALUES(1,'Paint',1); --works
GO
INSERT INTO dbo.StockItem (StockItemID,
                           StockItemName,
                           ColourID)
VALUES (1,'Wood Panels',3); --fails

GO

--clean up
DROP TABLE dbo.StockItem;
DROP TABLE dbo.Colour;
对于检查,请使用唯一的检查约束。如果只想在颜色不存在时插入颜色,请使用
insert。。从…起其中
检查是否存在并插入同一查询

唯一的“窍门”是来自的
需要一个表。可以使用创建表的方法来修复此问题,该方法使用要插入的值来创建表。如果存储过程接受表值参数,则没有问题

此示例使用左连接插入不匹配的值:

declare @colors table (Color nvarchar(10) UNIQUE)

insert into @colors VALUES ('green')

select * from @colors;

insert into @Colors (Color)
select new.Color
from (VALUES ('red'),
             ('green')) new(Color)
    left outer join @Colors old on old.Color=new.Color
where old.Color is NULL

-- (1 row affected)

insert into @Colors (Color)
select new.Color
from (VALUES ('red'),
             ('green')) new(Color)
    left outer join @Colors old on old.Color=new.Color
where old.Color is NULL

-- (0 rows affected)

select * from @colors;
-- green
-- red
使用子查询执行相同的操作:

insert into @Colors (Color)
select new.Color
from 
    (VALUES ('red'),
            ('green')) new(Color)
where not exists (select 1 
                  from @colors 
                  where color=new.Color);

通过使用
UNIQUE
约束,我们确保不能插入重复条目

这不是约束,而是查询。INSERT可以包含FROM和WHERE子句。您可以在不存在(…)的地方编写
INSERT
不应该是Warehouse.Color。另外,请检查是否可以设置ColorId和Identity字段。@PanagiotisKanavos-不幸的是,SQL Server不支持在不存在的位置插入[…]。这是一个MySQL-ism。在插入之前,可以使用触发器检查表中是否存在该值。如果它确实存在,请插入您的首选值或默认值。@ChrisJ是否存在?我从来没有使用过MySQL,只有SQL Server。您可以使用带有INSERT的查询来确保某些内容不存在。无论是内部联接还是子查询,它都可以工作