【问题标题】:Having weird exception using MAX(CASE WHEN) in query: DB2.iSeries.iDB2DCFunctionErrorException: 'An unexpected exception occurred在查询中使用 MAX(CASE WHEN) 出现奇怪的异常:DB2.iSeries.iDB2DCFunctionErrorException: '发生意外异常
【发布时间】:2021-10-25 19:20:24
【问题描述】:

我有以下查询将行中的一些数据放在列中:

string qry3 =
            "SELECT TABLENAME1.SLONO AS ORDER, TABLENAME1.SLLNNO AS LINE " +
            ",  MAX(CASE WHEN TABLENAME2.CZVRNM in ('SLEEVEDEPTH', 'LENGTH') THEN CAST(RTRIM(TABLENAME2.CZREFD) AS FLOAT(53)) END) AS SLEEVE " +
            ",  MAX(CASE WHEN TABLENAME2.CZVRNM in ('INSTALLATION') THEN CAST(RTRIM(TABLENAME2.CZREFD) AS FLOAT(53)) END) AS DAMPER_AI " +
            "FROM LOCATION.LOCATION2.TABLENAME1 TABLENAME1 LEFT JOIN LOCATION.LOCATION2.TABLENAME2 TABLENAME2 " +
            "     ON (TABLENAME1.SLONO = TABLENAME2.SPONO AND TABLENAME1.SLLNNO = TABLENAME2.SPLNNO)  " +
            "GROUP BY TABLENAME1.SLONO, TABLENAME1.SLLNNO ";

但是当我尝试在以下代码中运行它时:

        try
        {
            conAS400.Open();

            iDB2Command command = conAS400.CreateCommand();
            command.CommandText = qry3;

            command.CommandTimeout = 0;

            iDB2DataReader reader = command.ExecuteReader();
            dtAS400 = new DataTable();
            dtAS400.Load(reader); //<-- The exception occurs here. I can't even catch it

            conAS400.Close();

            retrieved = true;
        }

        catch (Exception ex)
        {
            MessageBox.Show("Could not retrive the information. Exception: " + ex.Message);

            retrieved = false;
        }
        finally
        {
            conAS400.Close();
        }

我得到了这个例外:

"IBM.Data.DB2.iSeries.iDB2DCFunctionErrorException: '意外 发生异常。类型:System.AccessViolationException,消息: 尝试读取或写入受保护的内存。这通常是一个 指示其他内存已损坏..'"

我还有其他可以正常工作的查询,但这个不行。我什至尝试了如下 SQL 查询(感谢 Gordon Linoff 提供此代码):

SELECT 
    A.IDA, A.SomeInfo,
    MAX(CASE WHEN VarName in ('Depth', 'Depth2') THEN VarValue END) AS Depth,
    MAX(CASE WHEN VarName in ('Length') THEN VarValue END) AS Length
FROM 
    A
LEFT JOIN 
    B ON A.IDA = B.IDA
GROUP BY 
    A.IDA, A.SomeInfo

而且它有效。我能做什么?

司机:

客户端访问 ODBC 驱动程序(32 位)12.00.00.00

iSeries Access ODBC 驱动程序 12.00.00.00

编辑:这是没有字符串的 sql 查询。

SELECT TABLENAME1.SLONO AS ORDER, TABLENAME1.SLLNNO AS LINE, 
    MAX(CASE WHEN TABLENAME2.CZVRNM in ('SLEEVEDEPTH', 'LENGTH') THEN CAST(RTRIM(TABLENAME2.CZREFD) AS FLOAT(53)) END) AS SLEEVE, 
    MAX(CASE WHEN TABLENAME2.CZVRNM in ('INSTALLATION') THEN CAST(RTRIM(TABLENAME2.CZREFD) AS FLOAT(53)) END) AS DAMPER_AI 
FROM LOCATION.LOCATION2.TABLENAME1 TABLENAME1 LEFT JOIN LOCATION.LOCATION2.TABLENAME2 TABLENAME2 
    ON (TABLENAME1.SLONO = TABLENAME2.SPONO AND TABLENAME1.SLLNNO = TABLENAME2.SPLNNO)  
GROUP BY TABLENAME1.SLONO, TABLENAME1.SLLNNO 

【问题讨论】:

  • 请编辑您的问题(不要使用 cmets)以添加您正在使用的 Db2 驱动程序的版本,以及它是哪种类型的驱动程序。通常有必要确保您拥有 IBM 提供的驱动程序的最新修订包(如果驱动程序的供应商是 IBM)。
  • 这个问题似乎与管理/配置相关,可以在 dba.stackexchange.com 找到更好的答案。
  • 感谢您的 cmets。我已经编辑了我的问题并将其发布在 dba.stackexchange.com 上。
  • 我有版本 12.00.02.00 的 ODBC 驱动程序,并且在旋转时一直在做这种事情。作为实验,您可以更改与 OLE DB 驱动程序的连接,甚至更好的是 IBM.Data.DB2.iSeries.dll 驱动程序。
  • @Mike 我想我有 IBM.Data.DB2.iSeries.dll 驱动程序?我直接在visual studio中添加了该dll作为参考。这是我第一次处理 as400(也是作为开发人员的第一份工作),我在处理这个问题时遇到了很多麻烦。你如何看待这种东西?

标签: c# sql db2 ibm-midrange db2-400


【解决方案1】:

好的,所以我终于发现了问题所在。出于某种原因,我无法 CASTMAX 内浮动。如果我从查询中删除两个CAST,异常就消失了,一切正常。我不确定为什么会发生这种情况,如果有人可以解释这一点,那将非常有帮助,因为我需要将这些值转换为浮动。另外,如果我SELECT 更多列,则有必要将所述列添加到GROUP BY 语句中。无论如何,这是修改后的代码:

编辑:找到施放它们的方法。事实证明,我得到了一些空值、一些空白字段,并且我试图将一个数字分配给一个字符串。这是现在的代码:

SELECT TABLENAME1.SLONO AS ORDER, TABLENAME1.SLLNNO AS LINE, TABLENAME1.PROMISEDT,
    CAST(MAX(CASE WHEN RTRIM(TABLENAME2.CZREFD) IS NULL OR RTRIM(TABLENAME2.CZREFD) = '' THEN '0.000' WHEN TABLENAME2.CZVRNM = 'SLEEVEDEPTH' OR TABLENAME2.CZVRNM = 'LENGTH' THEN RTRIM(TABLENAME2.CZREFD) END) AS FLOAT(53)) AS SLEEVE,  
    MAX(CASE WHEN TABLENAME2.CZVRNM in ('INSTALLATION') THEN RTRIM(TABLENAME2.CZREFD) END) AS DAMPER_AI 
FROM LOCATION.LOCATION2.TABLENAME1 TABLENAME1 LEFT JOIN LOCATION.LOCATION2.TABLENAME2 TABLENAME2 
    ON (TABLENAME1.SLONO = TABLENAME2.SPONO AND TABLENAME1.SLLNNO = TABLENAME2.SPLNNO)  
GROUP BY TABLENAME1.SLONO, TABLENAME1.SLLNNO, TABLENAME1.PROMISEDT --remember to add every column from the SELECT here 

【讨论】:

  • 为什么不直接使用 MAX(CASE WHEN TABLENAME2.CZVRNM in ('SLEEVEDEPTH', 'LENGTH') THEN CAST(RTRIM(TABLENAME2.CZREFD) AS FLOAT(53)) ELSE 0 END) AS SLEEVE, 之类的东西。这将摆脱空值,并且 max 函数应该返回一个浮点数。
  • @jmarkmurphy 我刚刚尝试过,得到了完全相同的异常。出于某种原因,我无法在 MAX 内投射。
  • 嗯,它对我有用。也许您的系统在 PTF 上落后了?与您的管理员交谈,看看他们是否会安装最新的磁带,或者至少安装最新的数据库组 ptf's。
猜你喜欢
  • 1970-01-01
  • 2014-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多