执行立即更新返回 NULL 而非字符串查询工作正常

Posted

技术标签:

【中文标题】执行立即更新返回 NULL 而非字符串查询工作正常【英文标题】:execute immediate update returns NULL whilst the non string query works fine 【发布时间】:2019-03-26 12:24:23 【问题描述】:

我有一个运行良好的更新查询。一旦我把它放在我的 PLSQL 块中,它就会返回 NULL 并且没有错误。在块的这一部分之前,我将默认值插入到目标表中,因此我知道更新实际上是将字段更新为 NULL。由于此查询是按另一列计算每个列组的行数,因此它总是有一个值。我从字符串外部的查询中得到正确的计数..

当我将查询放在我的 plsql 块中时,我使用立即执行,查询将是一个字符串,其中 my_table_name 和 my_column_names 和 Table_1 是可变的。

我搜索了很多,发现了我应该提交的东西等等。但问题仍然存在。

例如: Need help in execute immediate update query

    update Table_FINAL r
set column_1  = 
(
    select max(totalcount)
    from    (
            select 'my_table_name' as table_name, 'my_collumn_name' as column_name, column_3, count(*) as totalcount
            from  my_table_name a
            where exists (select 1 from Table_2 where Table_2.column_x = a.column_x)
            group by column_3
            ) s 
    where r.column_3 = s.column_3
)
;

这里是字符串:

    execute immediate 'update Table_FINAL r
set column_1  = 
(
    select max(totalcount)
    from    (
            select ''' || my_table_name || ''' as table_name, ''' || my_collumn_name || ''' as column_name, column_3, count(*) as totalcount
            from ' ||  my_table_name || ' a
            where exists (select 1 from Table_2 where Table_2.column_x = a.column_x)
            group by column_3
            ) s 
    where r.column_3 = s.column_3
)'
;

【问题讨论】:

更新不返回任何内容;你的意思是表的column_1 最终为空吗?我猜您错误地提供或使用了变量表/列名称 - 请显示更新的动态版本以及您如何在问题中执行它。 使用动态 SQL 时:将 动态创建的 UPDATE 放入变量中,并使用 DBMS_OUTPUT.PUT_LINE 将其显示在屏幕上。复制/粘贴它,单独运行(不在 PL/SQL 块中)看看会发生什么。 我添加了字符串,并在第一个查询中更正了某事。我用 my_table_name 替换了 Table_1,因为它是一个变量 Alex,很抱歉误用了返回词。是的,我的意思是它将 column_1 更新为 NULL。我如何执行它到底是什么意思?我有一个块,其中有多个执行立即数。所有的工作,都是字符串。只有这个更新实际上是在做我不想要的事情。在每个执行立即部分之后,我也有一个提交。 我的意思是您在编辑中显示的内容。什么都没有跳出来(就为什么它会表现不同而言),但是按照 Littlefoot 的建议做,并检查生成的动态字符串是否与原始状态语句完全匹配。 【参考方案1】:

它将 column_1 更新为 NULL

如果您的动态 SQL 没有返回任何行,totalcount 将为 null,因此max(totalcount) 将为 null,在这种情况下,column_1 将更新为 null。

有几个明显的解决方案:

    只有在有值时才执行更新:... where r.column_3 = s.column_3 and totalcount is not null。 处理空值:select max(nvl(totalcount,0)) …

现在,您断言更新查询“工作正常”。它是否适用于您作为my_table_name 传递的所有值? Another reason why 动态 SQL 的难点在于我们无法查看源代码并确定它在运行时会做什么。所以你需要做一些调试。在没有更新的情况下运行动态 SELECT 语句,看看你实际执行的是什么:

execute immediate ' select max(totalcount) from (
       select ''' || my_table_name || ''' as table_name, ''' || my_collumn_name || ''' as column_name, column_3, count(*) as totalcount
            from ' ||  my_table_name || ' a
            where exists (select 1 from Table_2 where Table_2.column_x = a.column_x)
            group by column_3)' into l_total_count;
dbms_ouput.put_line(my_table_name ||'.'|| my_collumn_name ||' max(totalcount) = ' ||  l_total_count);

请记住在您使用的任何客户端中启用 SERVEROUTPUT。


更新字符串在一个循环中,似乎在每个循环中它确实进行了正确的更新,但随后 ir 将其余部分更新为 NULL……但我没有完全明白我应该做什么,因为我有数百个字段。 .(原文如此)

我猜你是从循环中调用这段代码的。因此,并不是您不使用 null 覆盖“正确更新”,而是您不想用任何后续值覆盖任何值。我可以提供一些建议,但实际上这是您的数据模型和业务逻辑,因此只有您可以决定正确的处理方式。

    像这样聚合totalcountset column_1 = column_1 + total_count。为此,您需要申请 nvl(max(totalcount),0)。 向 TABLE_FINAL 添加一列以存储 my_collumn_value 的值。在 UPDATE 语句的 WHERE 子句中引用该列。 (显然,这假设了与先前建议完全不同的结果集)。您可能还需要一列来存储 my_table_name 的值。

【讨论】:

谢谢,但问题是实际上有一个值。正如我所说,只有当我将查询放入字符串时,它才会更新为 NULL。 谢谢你..只有一点。您正在写入变量的此选择将返回多行。由于我按 Column_3 分组,因此我将获取每个 Column_3 的最大值 好吧。这行得通,我设法打印出有效值。我依赖了一些东西。更新字符串在一个循环内,似乎在每个循环中它确实进行了正确的更新,但随后 ir 将其余部分更新为 NULL。我搜索了一下,我在这里找到了一个解决方案:asktom.oracle.com/pls/asktom/… 但我做到了因为我有数百个领域,所以没有完全得到我应该做的事情.. 我再次更新了我的答案。但这是最后一次了。

以上是关于执行立即更新返回 NULL 而非字符串查询工作正常的主要内容,如果未能解决你的问题,请参考以下文章

Hive 嵌套的 get_json_object 在选择查询中工作正常,但在创建表中返回 null 作为选择查询 - 奇怪的行为

特例模式(Special Case Pattern)与空对象模式(Null Pointer Pattern)—— 返回特例对象而非 null

执行更新查询时获取主键作为输出还是返回?

Bootstrap 方法返回 null - Android 在启动时立即崩溃

指针在if / else语句之前有地址但是立即变为0x0

mybatis oracle 不能返回 null 列