PL / SQL: «00904. 00000 - ”% s: неверный идентификатор" - PullRequest
0 голосов
/ 07 апреля 2020

Привет У меня есть следующий код:

CREATE OR REPLACE PROCEDURE instead_of_select(
where_in_sname IN VARCHAR2,
where_in_city IN VARCHAR2)
IS
BEGIN
    EXECUTE IMMEDIATE
    'DECLARE rowss  SAL%ROWTYPE;
        BEGIN SELECT * INTO rowss from SAL where SNAME=' || where_in_sname || 
        ' and CITY='|| where_in_city ||';
    END;';
END instead_of_select;

BEGIN 
    instead_of_select('Peel', 'London');
END;    

BUUT Я не могу понять, что не нравится, когда я запускаю это. Это дает мне следующую ошибку

PL / SQL: ORA-00904: «ЛОНДОН»: неверный идентификатор ORA-06550: строка 2, столбец 11: PL / SQL: SQL Оператор игнорируется ORA-06512: в "SYSTEM.INSTEAD_OF_SELECT", строка 7 ORA-06512: в строке 2 06550. 00000 - "строка% s, столбец% s: \ n% s" * Причина: обычно PL / SQL ошибка компиляции.

Таблица существует с данными справа, какая проблема может быть?

о боже, это сводит меня с ума

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

Вот предложение, которое поможет вам самостоятельно отладить подобные вещи. Вместо того, чтобы пытаться создать большую объединенную динамическую c строку как часть вашего EXE C IMMEDIATE, присвойте ее переменной, а затем используйте dbms_output.put_line, чтобы показать вас именно тем, что вы создали, тогда просто EXE C НЕМЕДЛЕННАЯ переменная.

CREATE OR REPLACE PROCEDURE instead_of_select(
where_in_sname IN VARCHAR2,
where_in_city IN VARCHAR2)
IS
rowss  SAL%ROWTYPE
v_sql varchar2(4000);
BEGIN
    v_sql := 'SELECT * INTO rowss from SAL where SNAME=' || where_in_sname || 
        ' and CITY='|| where_in_city ';
    dbms_output.put_line(v_sql);
     EXECUTE IMMEDIATE v_sql;
END instead_of_select;

Выше я просто показываю лучший способ настройки и запуска (и отладки) операторов EXE C IMMEDIATE. Я не обращался к необходимости избегать кавычек, если вы не используете переменные связывания. Также обратите внимание, что строка dbms_output предназначена только для целей отладки. Вы прокомментируете это, как только решите проблему.

0 голосов
/ 07 апреля 2020

Аргументы, которые вы передаете, являются строками, и вы объединяете их в свой динамический c запрос; но без кавычек, поэтому внутренний запрос заканчивается как:

SELECT * INTO rowss from SAL where SNAME=Peel and CITY=London;

Вы можете добавить кавычки вокруг этих значений (но они должны быть экранированы):

EXECUTE IMMEDIATE
'DECLARE rowss  SAL%ROWTYPE;
    BEGIN SELECT * INTO rowss from SAL where SNAME=''' || where_in_sname || 
    ''' and CITY='''|| where_in_city ||''';
END;';

, что вместо generate:

SELECT * INTO rowss from SAL where SNAME='Peel' and CITY='London';

Но гораздо лучше использовать переменные связывания:

EXECUTE IMMEDIATE
'DECLARE rowss  SAL%ROWTYPE;
    BEGIN SELECT * INTO rowss from SAL where SNAME=:where_in_sname' || 
    ' and CITY=:where_in_city' USING where_in_sname, where_in_city;
END;';

Переменная rowss существует только в пределах этого динамического оператора c, хотя процедура и ее вызывающая сторона не вижу результатов.

Во всяком случае, это не обязательно по Dynami c; Вы можете просто сделать:

CREATE OR REPLACE PROCEDURE instead_of_select(
    where_in_sname IN VARCHAR2,
    where_in_city IN VARCHAR2)
IS
    rowss SAL%ROWTYPE;
BEGIN
    SELECT * INTO rowss
    from SAL
    where SNAME=where_in_sname
    and CITY= where_in_city;
END instead_of_select;

Но звонящий по-прежнему не видит rowss. Непонятно, что вы ожидаете или хотите получить от результатов - возможно, вы хотите передать их обратно как переменную OUT, как запись или, возможно, как курсор ref. (Предположительно, фильтр делает результат уникальным, в противном случае вы получите ошибку «слишком много строк»; вы все равно можете получить «no-data-found»).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...