2013-04-25 84 views
2

我在.net中使用oracleclient in,net运行一些代码。 SQL代码可以使用DBMS_PUT_LINE函数输出大量响应,然后通过调用DBMS_GET_LINE来检索该函数。如果输出只是特定的文本行,即'DBMS_OUTPUT.PUT_LINE('用户不可用:请联系系统管理员');'然后,对get_line的调用工作正常,并且我得到了该文本。但是,如果调用要输出SQL错误消息'DBMS_OUTPUT.PUT_LINE(SQLERRM);'那么我得到以下错误返回,'ORA-06502:PL/SQL:数字或值错误:十六进制原始转换错误'Oracle dotnet DBMS输出查询

真的很奇怪的事情,是如果我然后运行完全相同的代码第二次包括关闭并重新连接到数据库),那么对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分贝()

但在第二次运行,它得到正确的输出。我有没有第一次正确设置?

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

回答

1

首先,设计一个应用程序做客户端,并使用dbms_output服务器之间有意义的交流是一种可怕的方式。如果您的存储过程需要将信息发送给调用者,则应通过OUT参数或例外来完成。让存储过程捕获异常,尝试将其写入dbms_output缓冲区,然后让应用程序尝试从dbms_output缓冲区中读取以确定是否存在异常不是编写应用程序的可伸缩方法。

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

+0

不幸的是,我不得不使用由ASG提供的sql,所以我没有机会去找更好的方法。因此,如果我使用get_line进行检索,并且它包含上面显示的错误消息,那么如果我再创建第二个来电get_line,它返回一个空字符串,并且状态参数是1,但我仍然没有得到实际的邮件被发送,只有Oracle六角/ RAW转换错误 – 2013-04-25 16:58:02

+0

@KevinAppleyard - 对不起,什么是'ASG'站在这里?哪个SQL语句不能改? – 2013-04-25 17:01:35

+0

对不起,ASG是应用程序支持组,提供给我的SQL函数来运行它们的数据库。可扩展性在这里并不是真正的问题,因为每月只能运行几百次。他们为我提供了一大块执行特定功能的SQL。出于多种原因(主要是政治因素),这正是我必须与之合作的原因。 – 2013-04-25 17:11:52