【问题标题】:Oracle dotnet DBMS output queryOracle dotnet DBMS 输出查询
【发布时间】:2013-04-19 13:45:51
【问题描述】:

我正在.net 中运行一些代码,使用.net 中的oracleclient。 SQL 代码可以使用 DBMS_PUT_LINE 函数输出许多响应,然后我通过调用 DBMS_GET_LINE 来检索这些响应。如果输出只是特定的文本行,即 'DBMS_OUTPUT.PUT_LINE('USER IS NOT AVAILABLE : PLEASE CONTACT SYSTEM ADMINISTRATOR');'然后对 get_line 的调用工作正常,我得到了那个文本。但是,如果调用是输出 SQL 错误消息,'DBMS_OUTPUT.PUT_LINE(SQLERRM);'然后我得到以下错误返回,'ORA-06502: PL/SQL: numeric or value error: hex to raw conversion error'

真正奇怪的是,如果我第二次运行完全相同的代码(包括关闭并重新连接到数据库),那么对 get_line 的调用会返回正在输出的实际错误消息。

我的代码基本上做了以下事情:

打开数据库连接 使用 executeNonQuery 运行 SQL 查询 创建输出参数,如:

Dim anonymous_block = "begin dbms_output.get_line(:1, :2); end;"

aCmd.CommandText = anonymous_block
aCmd.Parameters.Add("1", OracleType.VarChar, 32000)
aCmd.Parameters("1").Direction = ParameterDirection.Output
aCmd.Parameters.Add("2", OracleType.Int32)
aCmd.Parameters("2").Direction = ParameterDirection.Output

然后运行另一个 executeNonQuery 以获取输出。

然后用 .close() 关闭数据库

但在第二次运行时,它得到了正确的输出。我可能有一些东西我第一次没有正确设置?

有什么想法吗?我总是可以只运行两次代码,但这似乎非常低效。

【问题讨论】:

    标签: .net oracle dbms-output


    【解决方案1】:

    首先,使用dbms_output 设计应用程序以在客户端和服务器之间进行有意义的交互是一种糟糕的方法。如果您的存储过程需要向调用者发送信息,则应通过OUT 参数或异常来完成。让存储过程捕获异常,尝试将其写入dbms_output 缓冲区,然后让应用程序尝试从dbms_output 缓冲区读取以确定是否存在异常,这不是编写应用程序的可扩展方法。

    也就是说,如果您要从dbms_output 缓冲区中获取数据,则需要循环执行。在您的特定情况下,错误堆栈包含多行数据(可能只有一次调用 dbms_output.put_line 但文本包含内部换行符。您需要循环直到 status (第二个参数)返回 1 .

    【讨论】:

    • 很遗憾,我必须照原样使用ASG提供的sql,所以我没有机会找到更好的方法。鉴于此,如果我使用 get_line 进行检索,并且它包含上面显示的错误消息,如果我随后对 get_line 进行第二次调用,它将返回一个空字符串,并且状态参数为 1。但我仍然没有得到实际的正在发送消息,只有 oracle hex/raw 转换错误。
    • @KevinAppleyard - 抱歉,ASG 在这里代表什么?哪些 SQL 语句不能更改?
    • 抱歉,ASG 是应用程序支持小组,他们为我提供了 SQL 函数来针对他们的数据库运行。可扩展性在这里并不是真正的问题,因为它每月只会运行几百次。他们为我提供了一段执行特定功能的 SQL。出于多种原因(主要是政治原因),这正是我必须解决的问题。
    • 原来问题出在数据库方面,Oracle 人员已经确定并对其进行了修复,现在第一次尝试就得到了正确的响应。将此答案标记为所有好的建议,谢谢@Justin Cave。
    猜你喜欢
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 2021-08-09
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多