我对SQL中的约束有疑问,确切地说就是在transact-sql中。我有一个旅行数据库。我创建了一个添加新旅行参与者的程序。我正在使用ms-sql server,因此在创建表时添加了外键和主键约束。现在我的程序中为我的旅行添加新参与者
insert VoyageThemes(VoyageId,ThemeId) values (@voyageId,@themeId)
现在,在VoyageThemes表中,VoyageId和ThemeId都是主键和外键,所以当我尝试添加与数据库约束中已存在的值不对应的新值时,它就会抬头。
我的问题是,我可以以某种方式检查约束是否“说”我无法向表中添加值,因此我可以停止该过程,或者如果VoyageId和ThemeId存在,我需要手动检入我的数据库。
由于这行代码,我需要知道这些值是否存在:
update Voyages
set Voyages.Price=Voyages.Price+@costOfTheme*@numOfParticipants
我正在更新旅行的价格,所以这行代码只有在有相应的VoyageId和ThemeId时才能执行
答案 0 :(得分:2)
我想你可以使用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
答案 1 :(得分:1)
而不是INSERT
,使用MERGE
仅在尚未存在的情况下创建行,例如
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);