Sql server 2005 使用RAISERROR在t-SQL中引发特定错误

Sql server 2005 使用RAISERROR在t-SQL中引发特定错误,sql-server-2005,tsql,raiserror,Sql Server 2005,Tsql,Raiserror,我有一个视图具有而不是INSERT触发器(在SQLServer2005中)。当用户插入视图时,他们实际上是在插入和更新许多表。该视图非常复杂,不能有索引,因此很遗憾没有约束 视图被插入到from C#中,使用的代码很难更改。此代码使用以下命令捕获主键和唯一键冲突: try { ... // Insert into view } catch (SqlException ex) { if (ex.Number == 2627 || ex.Number == 2601) // Prim

我有一个视图具有
而不是INSERT
触发器(在SQLServer2005中)。当用户插入视图时,他们实际上是在插入和更新许多表。该视图非常复杂,不能有索引,因此很遗憾没有约束

视图被插入到from C#中,使用的代码很难更改。此代码使用以下命令捕获主键和唯一键冲突:

try
{
    ... // Insert into view
}
catch (SqlException ex)
{
    if (ex.Number == 2627 || ex.Number == 2601) // Primary key exception, unique constraint violation
    {
        ... // Report the duplicate entry to the user
    }
    else
    {
        throw;
    }
}

所以我的问题是:我可以在触发器中使用
RAISERROR
创建一个编号为2627或2601的异常吗?

否。您必须等待(可能)

您只能抛出放入sys.messages(50000+)中的错误,或者抛出包含50000的文本的错误。或者将其嵌入文本并更改您的c#。您不能抛出小于50000的错误


如果视图太复杂以至于不能使用DRI,那么它就太复杂了。此外,您还会遇到并发性问题:重叠调用会在您启动自己的调用时打破您的“唯一性”。

否。您必须等待(可能)

您只能抛出放入sys.messages(50000+)中的错误,或者抛出包含50000的文本的错误。或者将其嵌入文本并更改您的c#。您不能抛出小于50000的错误


如果视图太复杂以至于不能使用DRI,那么它就太复杂了。此外,您还会遇到并发性问题:重叠调用会在您启动自己的调用时,在某个时候破坏您的“唯一性”。

我不确定您是否真的可以
引发真正的主键冲突。尽管你可以用你自己的信息提出你自己的错误,然后抓住它。这还允许您区分真正的主键冲突和您自己的自定义冲突

也许实现这一点最粗糙的方法是

SQL代码(可能在触发器定义中)

C#


我不确定你是否真的能提出真正的主键违规。尽管你可以用你自己的信息提出你自己的错误,然后抓住它。这还允许您区分真正的主键冲突和您自己的自定义冲突

也许实现这一点最粗糙的方法是

SQL代码(可能在触发器定义中)

C#


谢谢,很公平。我的理解是,模式绑定视图只有在SQL Server 2005中没有左连接、联合和子查询时才能编制索引。在我看来,这些并不一定会使视图变得太复杂。@Paul:因为维护索引视图需要对这些结构进行大量处理。请参阅“为什么我不能在索引视图中使用外部联接?”中的“对不起,我的意思是太复杂,无法用作视图,而不是太复杂,SQL Server无法在其上维护索引。在我的例子中,视图没有外部联接,但有一个子查询,因此我可以根据ROW_NUMBER()函数的结果进行限制。@Paul:ROW_NUMBER()将要求重新计算整个索引视图(按顺序更改位置/删除、更改分区等)。有很好的理由限制索引视图。谢谢,这很公平。我的理解是,模式绑定视图只有在SQL Server 2005中没有左连接、联合和子查询时才能编制索引。在我看来,这些并不一定会使视图变得太复杂。@Paul:因为维护索引视图需要对这些结构进行大量处理。请参阅“为什么我不能在索引视图中使用外部联接?”中的“对不起,我的意思是太复杂,无法用作视图,而不是太复杂,SQL Server无法在其上维护索引。在我的例子中,视图没有外部联接,但有一个子查询,因此我可以根据ROW_NUMBER()函数的结果进行限制。@Paul:ROW_NUMBER()将要求重新计算整个索引视图(按顺序更改位置/删除、更改分区等)。对索引视图的限制有很好的理由。谢谢……如果无法引发主键错误,这可能就是我需要做的。或者,我可以通过将两个相同的值插入到带有主键的临时表中,从而导致真正的主键冲突……但这两个值似乎都有点老套:-S@Paul是的,他们有点不成熟——尽管我想说我帖子中的方法比你建议的double
INSERT
更不成熟。我还确信有一种更好的方法可以
RAISERROR
消除错误并捕获您的特定异常,因此最好阅读
RAISERROR
的细节。是的,同意。[还有更多字符]谢谢……如果无法引发主键错误,我可能需要这样做。或者,我可以通过将两个相同的值插入到带有主键的临时表中,从而导致真正的主键冲突……但这两个值似乎都有点老套:-S@Paul是的,他们有点不成熟——尽管我想说我帖子中的方法比你建议的double
INSERT
更不成熟。我还确信有一种更好的方法可以
RAISERROR
消除错误并捕获您的特定异常,因此最好阅读
RAISERROR
的细节。是的,同意。[还有更多的字符]
RAISERROR('Custom View Violation',16,1);
try 
{
    //execute SP / Insert etc...
}
catch (SqlException ex)
{
    if (ex.Message.Split('\r')[0] == "Custom View Violation")
    {
        //deal with your exception
    }
}