выполнить немедленное обновление возвращает NULL, в то время как нестрочный запрос работает нормально - PullRequest
0 голосов
/ 26 марта 2019

У меня есть запрос на обновление, который работает нормально.как только я помещаю это в мой блок PLSQL, он возвращает NULL и ошибки нет.До этой части блока я вставляю значение по умолчанию в целевую таблицу, поэтому я знаю, что обновление фактически обновляет поля до NULL.Так как этот запрос подсчитывает строки каждой группы столбцов по другому столбцу, для него всегда есть значение. И я получаю правильное количество из запроса за пределами строки.

, когда я размещаю запросв моем блоке plsql я использую немедленное выполнение, и запрос будет представлять собой строку, в которой my_table_name и my_column_names и Table_1 являются переменными.

Я много раз искал и находил такие вещи, как я должен совершить и т. д. Но проблема все еще существует.

например: Нужна помощь в выполнении запроса немедленного обновления

    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 Ответ

2 голосов
/ 26 марта 2019

обновляет column_1 до NULL

Если ваш динамический SQL не возвращает строк, totalcount будет нулевым, поэтому max(totalcount) будет нулевым и в этом случае column_1 будетобновиться до нуля.

Существует несколько очевидных решений:

  1. выполняет обновление только при наличии значения: ... where r.column_3 = s.column_3 and totalcount is not null.
  2. обрабатывает нуль: select max(nvl(totalcount,0)) …

Теперь вы утверждаете, что запрос на обновление "работает нормально".Работает ли он нормально для всех значений, которые вы передаете как my_table_name? Другая причина, по которой динамический 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 в любом клиенте, который вы используете.


строка обновления находится внутри цикла, и кажется, что в каждом цикле цикла она действительно выполняет правильное обновление, но затем она обновляет остальное до NULL ... Но я не полностью понимаю, что ядолжен делать, так как я собираю сотни полей .. (sic)

Я догадался, что вы вызываете этот код из цикла.Таким образом, дело не в том, что вы не перезаписываете «правильное обновление» нулем, а в том, что вы не хотите перезаписывать любое значение любым последующим значением.Я могу предложить несколько предложений, но на самом деле это ваша модель данных и ваша бизнес-логика, поэтому только вы можете решить, как правильно с этим справиться.

  1. Агрегировать totalcount, например: set column_1 = column_1 + total_count.Чтобы это работало, вам нужно применить nvl(max(totalcount),0).
  2. Добавить столбец в TABLE_FINAL для хранения значений my_collumn_value.Ссылка на этот столбец в предложении WHERE оператора UPDATE.(Очевидно, это предполагает совершенно другой набор результатов из предыдущего предложения).Вам также может понадобиться столбец для значений my_table_name.
...