存储过程 - 将消息传递回用户应用程序的最佳方式

发布于 2024-07-06 05:35:59 字数 177 浏览 3 评论 0原文

我想知道人们如何看待在存储过程中使用 RAISERROR 将用户消息(即业务相关消息,而不是错误消息)传回应用程序。

我公司的一些高级开发人员一直在使用这种方法,并在 C# 代码中捕获 SqlException 来获取消息并将其显示给用户。 我对这种方法不满意,想知道其他人如何处理来自存储过程的这些类型的用户消息。

I'd like know what people think about using RAISERROR in stored procedures to pass back user messages (i.e. business related messages, not error messages) to the application.

Some of the senior developers in my firm have been using this method and catching the SqlException in our C# code to pick up the messages and display them to the user. I am not happy with this method and would like to know how other people deal with these types of user messages from stored procs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

痴者 2024-07-13 05:35:59

像这样使用 RAISERROR 确实不是一个好主意。 这就像使用异常作为流程控制逻辑一样,通常不受欢迎。

为什么不使用 OUT 参数来代替呢? 这正是他们的目的。 我想不出不支持 OUT 参数的数据库或客户端 API。

Using RAISERROR like this is really not a good idea. It's just like using Exceptions as flow control logic, which is generally frowned upon.

Why not use an OUT parameter instead? That's exactly what they are for. I can't think of a database or a client API that doesn't support OUT parameters.

我们的影子 2024-07-13 05:35:59

我已经这样做了,但它通常是为了传递业务“错误”消息,本质上必须有一个数据配置,无论出于何种原因都无法使用标准 FK 约束来强制执行。

如果它们实际上是“错误”,我对此没有太大问题。 如果它插入一条记录并使用 RAISERROR 抛出(“您已成功注册 XYZ!”),那么您就会遇到问题。 如果是这样的话,我可能会提出一个使用 out 参数的团队/部门/公司开发标准。

I've done this, but it was usually to pass along business "error" messages, essentially a data configuration had to be in place that couldn't be enforced with standard FK constraints for whatever reason.

If they are actually "errors", I don't have much of a problem with it. If it's inserting a record and using RAISERROR to throw ("You have successfully registered for XYZ!"), then you've got a problem. If that was the case, I'd probably come up with a team/department/company development standard for using out parameters.

不再见 2024-07-13 05:35:59

我会尝试避免让我的存储过程返回业务相关消息,因为根据定义,这些类型的消息可能应该在业务逻辑层中处理/生成。

例外情况应该是例外的(罕见的)。 我只会在错误时使用 RAISEERROR (就像我尝试导入所有这些数据,但其中一行有愚蠢的数据,所以我回滚了事务)。 您还需要非常小心所引发的错误的严重性,这可能会对错误的传播方式以及连接发生的情况产生巨大影响。

如果这还不够,请尝试使用返回值或输出变量。

I would try to avoid getting my stored procs from returning Business Related messages because by definition these kind of messages probably ought to be handled/generated in a Business Logic tier.

Execeptions should be exceptional (infrequent). I would use RAISEERROR only for errors (like hey I tried to import all this data and one of the rows had goofy data so I rolled back the transaction). You also need to be very careful with the severity of the error raised this can have a huge affect on how the error propogates and what happens to your connection.

Try using a return value or an output variable if this isn't enough.

泪冰清 2024-07-13 05:35:59

仅当情况异常并且您没有处理逻辑时才应抛出异常。 引发和捕获异常的成本也很高。

避免使用异常,除非

  1. 情况非常特殊
  2. 您没有针对异常情况的处理逻辑

使用输出参数或返回多个结果集来传递来自存储过程的信息。

Exceptions should be thrown only when the situation is exceptional and you do not have a handling logic. Also raising and catching exception is expensive.

Avoid using exceptions unless

  1. The situation is exceptional
  2. You do not have handling logic for the exceptional situation

Use output parameters or return multiple resultsets to pass info from the stored procedures.

回眸一遍 2024-07-13 05:35:59

让你的存储过程返回2组数据。 第一个可以包含实际返回的数据,然后第二个可以返回文本消息。 然后,您的应用程序代码可以在需要的地方使用数据,然后显示返回的任何消息。

Make your stored procedure return 2 sets of data. The first can contain the actual returned data, then the second can return a text message. Your app code can then use the data where it needs to, then display whatever message comes back.

溺渁∝ 2024-07-13 05:35:59

回答这么老的问题是不是不太好? 任何人......

对于您的日常状态消息,这将是一件坏事,我几乎同意上面的每个答案。 然而,我发现它非常有效地用于显示长批次的进度。 请参阅 从批处理和存储过程获取反馈/进度(Jens K 的示例)。 你必须有一个非常核心的理由才能这样做,但是当你需要它时,你需要它,而且它非常棒。

Is it bad form to answer a question this old? Anywho...

For your everyday status messages, this would be a Bad Thing and I agree with pretty much every answer above. I have however seen this used quite effectively for showing progress during long batches. See Getting feedback / progress from batches and stored procedures by Jens K for an example. You've got to have a pretty hardcore reason for doing it, but when you need it, you need it and it is awesome.

百变从容 2024-07-13 05:35:59

当错误发生时,我们会引发错误,并在输出变量或返回值中返回状态信息。

We raise errors when errors occur, and we return status information in output variables or return values.

戒ㄋ 2024-07-13 05:35:59

您应该使用 SQL 存储过程输出参数。

来自 http://msdn.microsoft.com/en-us/library/ms378108 .aspx

CREATE PROCEDURE GetImmediateManager
   @employeeID INT,
   @msg varchar(50) OUTPUT
AS
BEGIN
   SELECT ManagerID 
   FROM HumanResources.Employee 
   WHERE EmployeeID = @employeeID

   SELECT @msg = 'here is my message'
END

You should be using SQL stored procedure output parameters.

From http://msdn.microsoft.com/en-us/library/ms378108.aspx:

CREATE PROCEDURE GetImmediateManager
   @employeeID INT,
   @msg varchar(50) OUTPUT
AS
BEGIN
   SELECT ManagerID 
   FROM HumanResources.Employee 
   WHERE EmployeeID = @employeeID

   SELECT @msg = 'here is my message'
END
匿名的好友 2024-07-13 05:35:59

如果不能及早检查/捕获它,可能很难做其他事情。

我必须在我编写的过程中编写一个 raiseerror 并将其用作插入/更新表的约束,因为它是数据的“最后一站”,我必须在那里检查它。

我认为一般来说,如果您从数据库返回错误..这是一个痛苦的事情,并且很难在不付出很大努力的情况下向用户提供“好的”反馈,但有时您只是不知道,直到您插入/更新:P

If it can't be checked/caught earlier it might be difficult to do anything else.

I've had to write a raiseerror in a procedure I wrote and used as a constraint on inserting/updating a table because it was the 'last stop' for the data and I had to check it there.

I think in general if you are getting errors back from the DB.. its a pain in the butt and harder to give 'nice' feedback to the user without a lot of effort, but sometimes you just don't know until you insert/update :P

得不到的就毁灭 2024-07-13 05:35:59

我亵渎的 2 美分:

基于文本的消息在网络上运行得非常好,例如 HTTP。 创建、发送和调试系统很容易,其中消息传递以人类可读的文本完成。

因此,SQL Server 层与其上层之间的消息传递可能也是同样的情况。 使用文本作为消息传递的一部分可能会让您的开发更加敏捷,调试也更加容易。 也许高级开发人员很务实,您也许应该愿意抛开先入为主的正确性观念。

根据设计选择本身的优点来争论,而不是基于正确性的概念。 (软件开发也有时尚)

My blasphemous 2 cents:

Text-based messages work really well on the web, like, HTTP for example. It's easy to create, send, debug systems where the messaging is done in human-readable text.

So, maybe the same thing with the messaging between your SQL Server layer and the layer above it. Using text as part of the messaging might be making your development more agile and your debugging easier. Maybe the senior developers are being pragmatic and you should maybe be open to setting aside pre-conceived notions of correctness.

Debate the design choice on its own merits, not based on notions of correctness. (There is fashion in software development too)

迟到的我 2024-07-13 05:35:59

我将使用存储过程中的 RETURN 值,如下所示:

CREATE PROCEDURE checkReturnValue
AS
BEGIN
    DECLARE @err AS INT
    SET @err = 0

    IF (rand() < 0.5)
    BEGIN
        SET @err = 1
    END

    SELECT * FROM table

    PRINT @err

    RETURN @err
END

检查调用存储过程的应用程序中的 RETURN 值。

I'd use the RETURN value from the stored procedure, like this:

CREATE PROCEDURE checkReturnValue
AS
BEGIN
    DECLARE @err AS INT
    SET @err = 0

    IF (rand() < 0.5)
    BEGIN
        SET @err = 1
    END

    SELECT * FROM table

    PRINT @err

    RETURN @err
END

Check the RETURN value in your application calling the stored procedure.

悸初 2024-07-13 05:35:59

仅当“业务”错误消息是数据库错误消息时,即违反了为满足数据库级别的基本低级业务需求而设置的数据库约束。

它不应该用于高级业务逻辑,这应该避免在数据库层中。 数据库层总是变化最慢的,因此只有非常缓慢变化和不变的业务逻辑才应该存在。

因此,对于不活跃/禁用客户的订单消息,可能是“是”,但对于 90 天内有余额的客户的订单则不然。 第一条规则可能是永久性的,第二条规则可能是可配置的,每月都会受到业务突发奇想的影响。

Only if the "business" error messages are database error messages in the sense that the database constraints which have been put in place to satisfy basic low-level business requirements at the database level are being violated.

It should not be used for high-level business logic, which should be avoided in the database layer. The database layer is always the slowest to change, so only very slowly changing and unchanging business logic should be there.

So maybe yes for message about order for an inactive/disabled customer, but not for an order for a customer who has a balance in 90 days. The first rule may be permanent, the second is likely to be configurable, subject to whims of the business on a monthly basis.

仙女 2024-07-13 05:35:59

我使用 raiseerror 从多个嵌套存储过程的深处返回,但存储过程的最后一层总是在引发到调用语言(在我们的例子中是通过 JDBC 的 Java)之前捕获异常。 最外层的存储过程 catch 被转换为 XML 消息以传输到 JDBC 调用,并且根据我们的约定,根元素必须包含反馈属性。 反馈属性的值始终具有 ok、alert 或 error 装饰器。 好的意味着继续,这里没什么可看的。 警报意味着继续,但向用户显示其余的反馈。 错误意味着弃踢,请致电服务台。

I've used raiseerror to return from the depths of multiple nested stored procedures, but the final layer of stored procedure always catches the exception prior to being raised to the calling language (in our case Java via JDBC). The stored procedure catch in the outer most layer is transformed into an XML message to be transported to the JDBC call and the root element, by our convention, must contain a feedback attribute. The value of the feedback attribute always has a decorator of either ok, alert, or error. Ok means go on, nothing to see here. Alert means go on, but show the rest of the feedback to the user. Error means punt, call the help desk.

极度宠爱 2024-07-13 05:35:59

我想如果您不介意弄乱检查列,那么您可以根据发生的情况返回不同的内容。

如果一切正常,则正常返回数据。
如果出现问题,请返回一个结果,其中包含一个名为 Error 的列,该列描述了问题所在。 在处理数据并采取相应措施之前,请检查此列的列名称。

如果你真的反对 RAISERROR 的话,我就无法理解了。

I guess if you don't mind messing with checking columns and such you could return something different based on what happened.

If everything is fine, return the data as normal.
If something isn't fine, return a result with a column named Error that describes what was bad. Check the column names for this column before you process data and act accordingly.

Off the top of my head if you really object to RAISERROR.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文