【问题标题】:Can not catch error in merge statement无法在合并语句中捕获错误
【发布时间】:2015-11-13 00:00:11
【问题描述】:

您好,我无法在合并语句中捕获错误。
在 SQL Plus 中运行 merge 语句会出现以下错误:
ORA-00932: inconsistent datatypes: expected DATE got NUMBER

当我在 Vb.net 中使用 ExecuteNonQuery 执行语句时不会出现任何异常。
有没有办法在 Vb.net 中捕获该错误而不在合并语句中使用日志错误?

编辑:

Try
    Dim count as Interger=0
    Dim cmd As New OleDb.OleDbCommand(strSQL)
    count = cmd .ExecuteNonQuery()
Catch ex as Exception
    ... Respond ...
End Try

有错误的示例合并语句:

MERGE INTO TABLE_A a USING
(
    SELECT ID,SUM(AMOUNT) AMOUNT
    FROM TABLE_B b
    GROUP BY ID
) b
ON ( b.ID=a.ID )
WHEN MATCHED THEN 
    UPDATE SET a.AMOUNT=a.AMOUNT+b.AMOUNT 
WHEN NOT MATCHED THEN 
    INSERT (ID, DT, AMOUNT) VALUES (b.ID, 0, b.AMOUNT);

SQL Plus 在插入时会出错,但 Vb.net 无法捕获。
字段 DT 的数据类型是 DATE。

【问题讨论】:

  • 如果您向我们展示您的代码会很好。
  • @Lalit Kumar B 示例代码已添加。
  • @Lalit Kumar B 添加了示例合并语句。
  • DATE需要插入一个零长度字符串吗?只需从 insert 中删除 dt ,对于新插入的行,它无论如何都是 NULL 。我正在考虑如何获得ORA-00932。您能否发布您的 SQL*Plus 会话。发布一个有效的测试用例,以便我们重现您声称的内容。
  • @Lalit Kumar B 认为 Vb,net 无法捕获但 SQL Plus 的合并语句示例会出错。

标签: vb.net oracle error-handling oledb oledbcommand


【解决方案1】:

编辑 3: 我的错 - 在这种情况下,我认为您必须订阅 oleDbConnection.InfoMessage 事件并在 MERGE 命令之后检查适用的 SQL-00932 消息。我在 OLE-DB 中看不到任何与 FireInfoMessageEventOnUserErrors 等效的属性(这似乎完全倒退了......)。

编辑 2:
似乎有一个默认阈值会导致 vb.net 忽略某些 SQL 异常(无法理解这种决定背后的基本原理)。无论如何,我认为如果您执行以下操作,您应该会看到引发的异常。

cmd.FireInfoMessageEventOnUserErrors = true;

结束 EDIT2

编辑:我只是更仔细地阅读了这个问题。如果 vb.net 执行根本没有抛出任何异常,则表明您没有在两者中运行完全相同的语句。我最初的猜测是,您传递的日期参数错误地将 SQL Plus 字符串变量传递为01/01/2015(1 除以 1 除以 2015)和 vb.net 变量正确传递为 '01/01/2015'(即带引号的字符串)。
结束编辑

我不知道您所说的“在合并语句中使用日志错误”是什么意思,但听起来您只需要使用 vb.net try-catch 语法来捕获并处理 Oracle 错误的语法。

从这里:http://www.tek-tips.com/viewthread.cfm?qid=467119

相关代码sn-p:

Try  
... Sql here ...
Catch ex as OleDbException
... Respond to error here ...
End Try

【讨论】:

  • 我使用相同的语句是 SQL Plus 和 Vb.net。我已经尝试过 OleDbException 它没有抛出任何异常。
  • 尝试强制一个 SQL 错误,例如将 WHERE 1=1/0 添加到 SQL,并在 vb.net 中运行 - 这应该告诉 vb.net 执行是否实际上隐藏了 SQL 异常。如果不是这样,我们需要查看 MERGE 语句以了解在 SQL Plus 中可能触发它失败的原因。第一个健全性检查应该是您将两个会话连接到同一个数据库/帐户。下一个检查是所有与日期相关的转换都是显式的(即 TO_DATE(arg1,'DD-MON-YYYY') 而不是 TO_DATE(arg1))。除此之外,你会发现。需要发布实际的 MERGE 以获得更多洞察力。
  • 从头开始;认为我找到了解释 - 更新答案
  • 我使用的是 OleDb 而不是 SqlClient。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
相关资源
最近更新 更多