检查sql约束
我对SQL中的约束有一个问题,确切地说是transact-SQL中的约束。我有一个旅行数据库。我创建了一个添加新旅行参与者的过程。我使用的是ms sql server,因此在创建表时添加了外键和主键约束。现在在我为旅行添加新参与者的过程中检查sql约束,sql,sql-server-2008,constraints,Sql,Sql Server 2008,Constraints,我对SQL中的约束有一个问题,确切地说是transact-SQL中的约束。我有一个旅行数据库。我创建了一个添加新旅行参与者的过程。我使用的是ms sql server,因此在创建表时添加了外键和主键约束。现在在我为旅行添加新参与者的过程中 insert VoyageThemes(VoyageId,ThemeId) values (@voyageId,@themeId) 现在,在VoyageThemes表中,VoyageId和ThemeId都是主键和外键,所以当我尝试添加与数据库中现有值不对应的
insert VoyageThemes(VoyageId,ThemeId) values (@voyageId,@themeId)
现在,在VoyageThemes表中,VoyageId和ThemeId都是主键和外键,所以当我尝试添加与数据库中现有值不对应的新值时,constraint会引起注意
我的问题是,我是否可以检查约束是否“表示”无法向表中添加值,以便停止该过程,或者我需要手动检查数据库中是否存在VoyageId和ThemeId
我需要知道这些值是否因为这行代码而存在:
update Voyages
set Voyages.Price=Voyages.Price+@costOfTheme*@numOfParticipants
我正在更新一次旅行的价格,因此只有当有相应的VoyageId和ThemeId时,这一行代码才能生效。我想您可以使用try/catch?:
...
BEGIN TRY
insert VoyageThemes(VoyageId,ThemeId) values (@voyageId,@themeId)
-- If we are here, then the insert succeeded, proceed with the update
update Voyages
set Voyages.Price=Voyages.Price+@costOfTheme*@numOfParticipants
...
END TRY
BEGIN CATCH
-- insert failed, check error
SELECT @error_number = ERROR_NUMBER(),
@error_severity = ERROR_SEVERITY(),
@error_state = ERROR_STATE()
IF @error_number = 547
-- constraint violation
BEGIN
PRINT '...'
END
ELSE
-- propagate error
BEGIN
RAISERROR(@error_number, @error_severity, @error_state) WITH LOG
END
END CATCH
使用
MERGE
仅当行不存在时才创建行,而不是INSERT
MERGE INTO VoyageThemes
USING (
VALUES (@voyageId, @themeId)
) AS S (VoyageId, ThemeId)
ON VoyageThemes.VoyageId = S.VoyageId
AND VoyageThemes.ThemeId = S.ThemeId
WHEN NOT MATCHED THEN
INSERT (VoyageId, ThemeId)
VALUES (VoyageId, ThemeId);
我相信您可以在插入后检查@行数,看看是否成功。看一看。它包含您所需的所有信息(您可能还希望添加
参考\u约束。更新\u规则,参考\u约束。删除\u规则
到原始查询)您从何处获取要插入到此表中的值?看起来您有一个带有PK themeId的主题表和一个带有PK voyageId和VoyageThemes的Voyage表,VoyageThemes是一个联接或多对多表。在大多数应用程序中,当您添加一个或另一个主题或将二者链接在一起时,您会在某种屏幕上从现有主题和/或航行列表中进行选择,在这种情况下,您的中间应用层至少会知道要提交到数据库的正确PK ID…那么您的问题是否可能表明存在更大的应用程序设计问题?这些值会传递到我的添加新旅行参与者的过程中,因为现在我没有任何大型应用程序,我刚刚开始编写过程,这是我的第一个数据库,所以我对所有这些新事物都有点迷茫,这就是为什么我询问约束中的错误。这会导致更新失败。如果是预先存在的行,我想他们只想“故障转移”插入
,并允许更新
@某天如果我不这么认为,我想他们只想在主题是新的情况下更新航程价格。否则,主题价格将包含在航次价格中。