Insert SQL Command with dynamic Username and rowtypes

I'd like to generate a dynamic Insert statement with different Username and data from a rowtype

My snippet

create or replace procedure test()
is
TYPE cv_typ is REF CURSOR;
cv cv_typ;
stmt varchar(2000);
zieldb varchar(20);

vKunden "Kunden"%rowtype;

BEGIN

execute immediate 'select * from "Kunden" where "KndNr"=55 ' into vKunden;

stmt:='select kc.zieldb from test.kunden_copy kc, test.transrel vd 
where kc.zieldb=vd.dbname and kc.status=1 ';

OPEN cv FOR stmt;
LOOP
    FETCH cv into nachdb;
    EXIT WHEN cv%NOTFOUND;
    ...
    ...
    stmt:='insert into ' || nachdb || ' ."Kunden"   values  ' || vKunden;
    execute immediate stmt ;        
    ...
    ... 
END LOOP;
END;

Я получаю следующее сообщение об ошибке:

Please-00306 wrong number or types of arguments in call

With the following syntax

stmt:='insert into ' || nachdb || ' ."Kunden"   values   vKunden ';
execute immediate stmt ;        

Я получаю следующее сообщение:

ORA-03001: unimplemented feature

2 ответа

Решение

Кажется, ты не можешь этого сделать. В первой попытке вы пытаетесь объединить тип записи PL/SQL (из %rowtype) на строку; если бы он позволил вам тогда, что бы он поместил, свое внутреннее представление записи? Для того чтобы он был действительным оператором вставки, он должен был бы перевести его в список значений из записи, как (col1, col2, ...), который просит довольно много об этом.

Во второй версии, с ORA-03001, я думаю, что это потому, что он интерпретирует vKunden в качестве идентификатора объекта; переменная записи в блоке PL/SQL не входит в область действия оператора SQL.

Предположительно, вы пытались использовать для этого переменную связывания и обнаружили, что это невозможно, поскольку переменные связывания должны быть типов SQL (PLS-00457).

Вы могли бы возможно использовать DBMS_SQL пройти через %rowtype переменная и создать свой собственный values предложение, основанное на столбцах / полях, которые оно содержит, но это кажется болезненным.

Предположительно, хотя различные версии "Kunden" (идентификаторы объектов в кавычках? не кажется ли вам, что работать с ними очень больно?) все идентичны, в противном случае %rowtype вы используете, чтобы объявить vKunden в любом случае не будет применяться для вставки, и поэтому вы знаете все имена столбцов. Вы должны будете связать каждое значение столбца индивидуально:

stmt:='insert into ' || nachdb || ' ."Kunden" ("KndNr", "Col2", ...)'
    || ' values (:1, :2, ...)';
execute immediate stmt using vKunden."KndNR", vKunden."Col2", ...;

Хотя еще проще было бы:

stmt:='insert into ' || nachdb || ' ."Kunden"'
    || ' select * from "Kunden" where "KndNr"=55';
execute immediate stmt;

... который обходит vKunden и %rowtype выдать в целом. Вы делаете этот выбор несколько раз, но это не может быть значительным количеством накладных расходов

Просто чтобы добавить, почему это не сработает: 03001 потому что у вас нет скобок () вокруг значений. Даже с скобками это не сработает, потому что vKunden имеет%rowtype, поэтому вы не можете передать это в динамический sql (pls-00457). Вы можете проверить это, используя: execute немедленный 'select:1 from dual' using vKunden;

Другие вопросы по тегам