检查sql约束

检查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都是主键和外键,所以当我尝试添加与数据库中现有值不对应的

我对SQL中的约束有一个问题,确切地说是transact-SQL中的约束。我有一个旅行数据库。我创建了一个添加新旅行参与者的过程。我使用的是ms sql server,因此在创建表时添加了外键和主键约束。现在在我为旅行添加新参与者的过程中

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…那么您的问题是否可能表明存在更大的应用程序设计问题?这些值会传递到我的添加新旅行参与者的过程中,因为现在我没有任何大型应用程序,我刚刚开始编写过程,这是我的第一个数据库,所以我对所有这些新事物都有点迷茫,这就是为什么我询问约束中的错误。这会导致
更新失败。如果是预先存在的行,我想他们只想“故障转移”
插入
,并允许
更新
@某天如果我不这么认为,我想他们只想在主题是新的情况下更新航程价格。否则,主题价格将包含在航次价格中。