строка в кавычках неправильно завершена в блоке pl sql - PullRequest
1 голос
/ 12 марта 2020

У меня есть таблица ot.config как: enter image description here

У меня есть таблица ot.stu как:

enter image description here

У меня есть блок pl sql как:

declare
vquery long;
cursor c1 is
select * from ot.config1;
begin
for i in c1
loop
vquery :='INSERT INTO all_acc_num(code,nbr_value) 
select '''||i.acct_nbr||''','||i.acct_nbr||' from ot.stu';
commit;
execute immediate vquery;
end loop;

end;
/

Но при компиляции я получаю сообщение об ошибке:

ORA-01756: quoted string not properly terminated
ORA-06512: at line 10

Как обработать эту ошибку?

Мой ожидаемый результат: enter image description here

Ответы [ 2 ]

0 голосов
/ 12 марта 2020

Вы можете передать значение с помощью параметра bind, если вы хотите использовать его в качестве литерального значения, и использовать конкатенацию строк, если вы хотите использовать его для динамической генерации имени столбца.

Так что, если ваши таблицы :

CREATE TABLE config1 ( acct_nbr, table_name ) AS
SELECT 'REGEXP_REPLACE(a.name,''/*/'')', 'abc' FROM DUAL;

CREATE TABLE stu ( name ) AS
SELECT 'as' FROM DUAL UNION ALL
SELECT 'bb' FROM DUAL UNION ALL
SELECT 'cc' FROM DUAL;

CREATE TABLE all_acc_num( code VARCHAR2(50), nbr_value VARCHAR2(20) );

Тогда ваш анонимный блок может передать литеральное значение с помощью EXECUTE IMMEDIATE ... USING .... Кроме того, если ваш идентификатор a.name, вам также необходимо определить псевдоним a:

DECLARE
  vquery CLOB;
  cursor c1 is
    select * from config1;
BEGIN
  FOR i IN c1 LOOP
    vquery :='INSERT INTO all_acc_num(code,nbr_value) 
select :1,'||i.acct_nbr||' from stu a';
    DBMS_OUTPUT.PUT_LINE( vquery );
    EXECUTE IMMEDIATE vquery USING i.acct_nbr;
  END LOOP;
END;
/

, который выдает:

INSERT INTO all_acc_num(code,nbr_value) 
select :1,REGEXP_REPLACE(a.name,'/*/') from stu a

и:

SELECT * FROM all_acc_num;

Выходы:

CODE                         | NBR_VALUE
:--------------------------- | :--------
REGEXP_REPLACE(a.name,'/*/') | as       
REGEXP_REPLACE(a.name,'/*/') | bb       
REGEXP_REPLACE(a.name,'/*/') | cc       

дБ <> скрипка здесь

0 голосов
/ 12 марта 2020

Вы должны обрабатывать апострофы в acct_nbr, используйте replace(). Также вам нужно добавить псевдоним a для ot.stu, потому что вы используете a.name в регулярном выражении.

declare
  vquery varchar2(32767);
  cursor c1 is select * from config1;
begin
  for i in c1 loop
    vquery :='INSERT INTO all_acc_num(code,nbr_value) 
              select '''||replace(i.acct_nbr, '''', '''''')||''', '||i.acct_nbr||' from ot.stu a';
    dbms_output.put_line(vquery);
    -- execute immediate vquery;
  end loop;
end;

dbfiddle

Используйте dbms_output, чтобы увидеть, действительно ли ваш код выдает sql. После того, как все в порядке, комментарий dbms_output и раскомментируйте execute immediate.

...