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

时间:2019-03-26 12:24:24

标签: oracle plsql dynamic-sql

我有一个更新查询,可以正常工作。一旦将其放入PLSQL块中,它将返回NULL,并且没有错误。在块的这一部分之前,我将默认值插入目标表,因此我知道更新实际上是将字段更新为NULL。由于此查询是按另一列对每个列组的行进行计数,因此始终有一个值。我从字符串之外的查询中获得了正确的计数。

当我将查询放在plsql块中时,我使用Execute立即执行,查询将是其中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
)'
;

1 个答案:

答案 0 :(得分:2)

  

它将column_1更新为NULL

如果动态SQL不返回任何行,则totalcount将为空,因此max(totalcount)将为空,并且在这种情况下,column_1将被更新为空。

有两种明显的解决方案:

  1. 仅在存在以下值时执行更新:... where r.column_3 = s.column_3 and totalcount is not null
  2. 处理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覆盖“正确的更新”,而是不想用任何后续值覆盖任何值。我可以提供一些建议,但实际上这是您的数据模型和业务逻辑,因此只有您可以决定正确的处理方式。

  1. 这样汇总totalcountset column_1 = column_1 + total_count。为此,您需要应用nvl(max(totalcount),0)
  2. 在TABLE_FINAL中添加一列以存储my_collumn_value的值。在UPDATE语句的WHERE子句中引用该列。 (显然,这假定与之前的建议完全不同的结果集)。您可能还需要为my_table_name设置一列。