Вставить в не работает на PL sql в oracle - PullRequest
0 голосов
/ 03 марта 2020
declare
vquery long;
cursor c1 is
select * from temp_name;

begin

for i in c1
loop
vquery :='INSERT INTO ot.temp_new(id)
select '''||i.id||''' from ot.customers';
dbms_output.put_line(i.id);
end loop;

end;
/

Вывод select * from temp_name:

ID                                                                              
--------------------------------------------------------------------------------
customer_id                                                                     
1 row selected.

У меня есть таблица клиентов, в которой есть столбец customer_id. Я хочу вставить все customer_id в таблицу temp_new, но она не вставляется. Блок PL SQL успешно выполняется, но таблица temp_new пуста. Вывод dbms_output.put_line(i.id); равен

customer_id

Что там не так?

1 Ответ

6 голосов
/ 03 марта 2020

Основная проблема в том, что вы генерируете динамический оператор c, который вы никогда не выполняете; в какой-то момент вам нужно сделать:

execute immediate vquery;

Но есть и другие проблемы. Если вы выведете сгенерированную строку vquery, вы увидите, что она содержит:

INSERT INTO ot.temp_new(id)
select 'customer_id' from ot.customers

, что означает, что для каждой строки в customers вы получите одну строку в temp_new с идентификатором, установленным на тот же фиксированный литерал 'customer_id'. Вряд ли это то, что вы хотите; если customer_id - это имя столбца из customers, тогда оно не должно быть в одинарных кавычках.

Как и предположил @mathguy, long не является разумным типом данных для использования; Вы можете использовать CLOB, но здесь вам действительно нужен varchar2. Итак, что-то вроде этого, где я также переключился на использование неявного курсора:

declare
  l_stmt varchar2(4000);
begin
  for i in (select id from temp_name) 
  loop
    l_stmt := 'INSERT INTO temp_new(id) select '||i.id||' from customers';
    dbms_output.put_line(i.id);
    dbms_output.put_line(l_stmt);
    execute immediate l_stmt;
  end loop;
end;
/

db <> fiddle

l oop не ' правда, имеет смысл; если в вашей таблице temp_name было несколько строк с разными именами столбцов, вы бы попытались вставить соответствующие значения из этих столбцов таблицы customers в несколько строк в temp_new, все в одном столбце id, как показано в этой базе данных <> fiddle .

Я думаю, что это отправная точка для чего-то более сложного, но все же кажется немного странным.

...