【问题标题】:querySetCell to NULL when copying data?复制数据时querySetCell为NULL?
【发布时间】:2013-05-30 19:22:43
【问题描述】:

这就是我的情况。

我必须使用一些遗留代码。这段代码给了我一个查询对象,我必须附加一些行。基本上,我需要复制1行N次(N不是常数),然后手动调整一些数据。

现在,至少 IMO 我正在做的事情确实不是正确的做事方式。我更愿意返回一个不需要在 CF 端进行修改并在数据库上生成正确数据集的查询对象。但是,唉,我无法访问原始查询:(

所以这是我的破解。我决定编写一个复制查询行的通用函数,然后我可以在添加副本后手动设置所需的任何单元格。

请看下面:

private function duplicateQueryRow(
    required query originalQuery,
    required numeric rowNum
) {
    queryAddRow(arguments.originalQuery, 1);
    for (local.i = 1; local.i LTE listLen(originalQuery.columnList); local.i += 1) {
        columnName = listGetAt(originalQuery.columnlist, i);
        querySetCell(originalQuery, columnName, originalQuery[columnName][rowNum], originalQuery.recordcount);
    }
}

问题:

假设某些列是 NULL。 例如,假设 ACOLUMN 列在第 5 行的值为 NULL。 当我这样做时,最后一行的 ACOLUMN 值将是“”,因为 CF 不处理 NULL。现在,如果我执行select distinct ACOLUMN from QUERY_NAME,我将得到第 5 行和自 NULL <> [empty string] 以来的最新行。

我确实有一个解决方案,它在下面:

private function duplicateQueryRow(
    required query originalQuery,
    required numeric rowNum
) {
    queryAddRow(arguments.originalQuery, 1);
    for (local.i = 1; local.i LTE listLen(originalQuery.columnList); local.i += 1) {
        columnName = listGetAt(originalQuery.columnlist, i);           
        if (originalQuery[columnName][rowNum] NEQ "") {
            querySetCell(originalQuery, columnName, originalQuery[columnName][rowNum], originalQuery.recordcount);
        }
    }
}

这行得通,因为现在不会复制 NULL,但我只是不相信这是正确的....

想知道是否有人有更好的解决方案?或者至少看看这个功能是否有问题。我想的要求是对于一个给定查询和要复制的 rowNumber 的函数将返回查询,并在末尾带有查询的 rowNumber 行的副本。

提前致谢!

【问题讨论】:

    标签: coldfusion coldfusion-9


    【解决方案1】:

    或者至少看看这是否有问题 功能。

    想到的明显问题是它不区分实际的空字符串和空值。因此,根据该逻辑,包含实际空字符串的列将被视为null

    我环顾四周,不幸的是找不到任何适用于这种情况的内置函数。我认为IsNull 可能会这样做,但它似乎并没有像您期望的那样处理查询列。如果传入查询列:

            isNull( queryName["columnName"][ rowNumber ] ) 
    

    .. 它总是返回“NO”。很可能是因为查询引用的计算结果为空字符串,而不是实际值,即null

    不过,您也许可以使用一些未记录的功能。 (我通常不会推荐它,但在这种情况下我看不到任何替代方案)。 CF 查询对象有一个名为getField(rowIndex, columnIndex) 的内部方法,它返回基础查询值。如果您使用该值,而不是使用关联数组表示法获得的值,它应该保留空值。

       targetRow = queryAddRow(originalQuery, 1);
       columnNames = originalQuery.getColumnList();
    
       // note: colIndex refers to the position within the original SQL
       for (colIndex = 1; colIndex <= arrayLen(columnNames); colIndex++) {
          realValue = originalQuery.getField( sourceRow, columnIndex );
          originalQuery[ columnNames[colIndex] ][ targetRow ] = realValue;
       }
    

    【讨论】:

    • 现在我倾向于接受这个建议。因为该功能没有记录,我可能会稍等片刻,看看是否有其他人加入。如果没有,我会将其标记为答案。好的,现在就试一试:)谢谢!
    • 我可能会等一下请。我个人更喜欢记录在案的方法,但找不到。希望其他人知道我错过的一个技巧:)
    【解决方案2】:

    如果列值为空,是否可以使用围绕您关注的列的 case 语句修改原始 SQL 以返回“NULL”(或期望)字符串?

    例子

    SELECT column1, 
    CASE WHEN column2 IS NULL THEN 'NULL' ELSE column2 END as column2,
    CASE WHEN column3 IS NULL THEN 'NULL' ELSE column3 END as column3
    FROM table WHERE...
    

    或者,如果您想用一块石头杀死 2 只鸟,您可以使用 null 和空字符串,例如:

    SELECT column1, 
    CASE WHEN NULLIF(column2,'') IS NULL THEN 'NULL' ELSE column2 END as column2,
    CASE WHEN NULLIF(column3,'') IS NULL THEN 'NULL' ELSE column3 END as column3
    FROM table WHERE...
    

    请注意,您可以将“NULL”值更改为您喜欢的任何值,然后针对该值进行测试(例如“[omit]”或“[scrub]”)。

    希望对您有所帮助。

    祝你好运。

    【讨论】:

      猜你喜欢
      • 2016-09-15
      • 1970-01-01
      • 2020-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 2020-07-17
      • 1970-01-01
      相关资源
      最近更新 更多