Получение ошибки ORA-00933: команда SQL неправильно завершилась, когда я пытаюсь запустить хранимую процедуру Oracle, которую я написал - PullRequest
0 голосов
/ 01 декабря 2018

В рамках проекта я работаю над отображением данных записей и полей peopleoft, используемых в нашей компании.Есть более 25K полей, которые я должен документировать, но это утомительно и займет гораздо больше времени, чем у меня, если бы я сделал это обычным способом.Итак, я написал хранимую процедуру, чтобы уменьшить часть работы по документированию значений перевода.

Вот код моей хранимой процедуры:

CREATE OR REPLACE PROCEDURE SP_DATAMAPPINGINFO AS 
TYPE EmpCurTyp IS REF CURSOR;
newrow_cursor    EmpCurTyp;
txtable_cursor EmpCurTyp;

recname varchar2(30);
recdescr varchar2(200);
fieldnum number(3);
fieldname varchar2(30);
fieldescr varchar2(2000);
keyflag varchar2(1);
fieldtype varchar2(20);
distinctcount number(10);

query1_str varchar(300);
query2_str varchar(300);
query3_str varchar(300);

fieldvalue varchar2(200);
hyphen varchar2(5);
txvalue varchar2(200);
fielduse varchar2(500);

tablename varchar2(40);
intertxtabname varchar2(30);
txtablename varchar2(40);

CURSOR get_fields is
        select A.RECNAME as "Record", A.RECDESCR as "Record Description"
        , B.FIELDNUM as "FieldNum", B.FIELDNAME as "Field", C.DESCRLONG as "Field Description", CASE WHEN
        EXISTS(select K.FIELDNAME FROM PSRECFLDDBKEYVW K WHERE K.RECNAME = A.RECNAME AND K.FIELDNAME=B.FIELDNAME)
        THEN 'Y' ELSE 'N' END as "Key (Y/N)", DECODE (C.FIELDTYPE,
                 0, 'Character',
                 1, 'Long Char',
                 2, 'Number',
                 3, 'Signed Number',
                 4, 'Date',
                 5, 'Time',
                 6, 'DateTime',
                 8, 'Image/ Attachment',
                 9, 'Image Reference',
                 'Unknown') as "FieldType"
        FROM PSRECDEFN A, PSRECFIELDDB B LEFT JOIN PSDBFIELD C ON (B.FIELDNAME = C.FIELDNAME)
        WHERE B.RECNAME = A.RECNAME
        AND A.RECNAME IN (select R.RECNAME from PSRECDEFN R, DBA_TABLES T
        WHERE ('PS_'||R.RECNAME=T.TABLE_NAME)
        AND T.NUM_ROWS > 0
        AND R.RECTYPE=0)
        order by A.RECNAME, B.FIELDNUM;

BEGIN
OPEN get_fields;
    LOOP
    FETCH get_fields INTO recname, recdescr, fieldnum, fieldname, fieldescr, keyflag, fieldtype;


    fielduse := '';
    tablename := 'PS_' || recname;
    hyphen := ' - ';
    fieldvalue := '';
    txvalue := '';
    intertxtabname := '';
    txtablename := '';

    if (fieldname <> '%EMPLID%' and fieldname <> '%DESCR%' and fieldname <> '%COMMENT%') THEN
        query1_str := 'select RI.EDITTABLE FROM PSRECDEFN RD, PSRECFIELDDB RI WHERE RD.RECNAME = RI.RECNAME 
        AND RD.RECNAME = ' || recname || 'AND RI.FIELDNAME = ' || fieldname;

        OPEN txtable_cursor FOR query1_str;
            FETCH txtable_cursor INTO intertxtabname;
        CLOSE txtable_cursor;

        query2_str := 'select count(distinct T.' || fieldname || ') FROM ' || tablename;

        IF (intertxtabname IS NOT NULL) THEN
            txtablename := 'PS_' || intertxtabname;
            query3_str := 'select distinct T.' || fieldname || ', TR.DESCR FROM ' || tablename || ' T left join ' || txtablename || ' TR ON T.' 
            || fieldname || ' = TR.' || fieldname || ' order by T.' || fieldname;
        ELSE
            txtablename := '';
            query3_str := 'select distinct DT.' || fieldname || ', DTR.XLATLONGNAME FROM ' || tablename || ' DT left join PSXLATITEM DTR on 
            (DTR.FIELDNAME = ''' || fieldname || ''' and DT.' || fieldname || ' = DTR.FIELDVALE) order by DT.' || fieldname;
        END IF;

        execute immediate query2_str into distinctcount;

        if(distinctcount > 150) THEN
            fielduse := 'More than 150';
        ELSE
            OPEN newrow_cursor FOR query3_str USING 'fieldname';
                LOOP
                FETCH newrow_cursor INTO fieldvalue, txvalue;
                fielduse := fieldvalue || ' - ' || txvalue;
                EXIT WHEN newrow_cursor%NOTFOUND;
                END LOOP;
            CLOSE newrow_cursor;
        END IF;

    ELSE
        fielduse := 'SKIPPING';
    END IF;

    dbms_output.put_line(recname || ',' || recdescr || ',' || fieldnum || ',' || fieldname || ',' || fieldescr || ',' || keyflag || ',' || fieldtype || ',' || fielduse);
    END LOOP;
CLOSE get_fields;

NULL;
END SP_DATAMAPPINGINFO;

Хранимая процедура компилируется без ошибок, нокогда я его выполняю, я получаю следующую ошибку:

Ошибка запуска в строке: 1 в команде -

BEGIN SP_DATAMAPPINGINFO;END;

Отчет об ошибке -

ORA-00933: команда SQL неправильно завершена

ORA-06512: в "SYSADM.SP_DATAMAPPINGINFO", строка 69

ORA-06512: в строке 1

00000 - «Команда SQL не завершена должным образом»

* Причина:

* Действие:

Строка 69 в хранимой процедуре: OPEN txtable_cursor FOR query1_str;

Я пытался использовать переменную связывания, но я все еще получаю ошибку, и, возможно, я использовал ее неправильно.

У меня могут быть другие проблемы вкод.Было бы здорово, если бы вы могли указать на это.В настоящее время мы находимся в Oracle 12c

1 Ответ

0 голосов
/ 01 декабря 2018

Строка 69 в хранимой процедуре: OPEN txtable_cursor FOR query1_str;.

Очевидно, мы не можем запустить ваш код, так как у нас нет вашей схемы, поэтому мы не можем скомпилировать и проверитьваш динамический SQL.Однако, глядя на собранную строку, поразительно, что происходит объединение текста шаблона и столбцов:

AND RD.RECNAME = ' || recname || 'AND RI.FIELDNAME = ' || fieldname

Если вы посмотрите внимательно, то заметите, что после кавычки в 'AND RI.FIELDNAME нет места.Это означает, что значение recname объединено с AND.Это ваш ORA-00933 прямо здесь.

Как только вы исправите это, вы, вероятно, столкнетесь с ORA-00936: missing expression.Из объявлений переменных мы знаем, что recname и fieldname являются строками, но вы не рассматриваете их как строки .Код не содержит кавычек вокруг переменных, поэтому выполненный запрос будет обрабатывать их как столбцы или что-то в этом роде.Вот что вам нужно исправить:

AND RD.RECNAME = ''' || recname || ''' AND RI.FIELDNAME = ''' || fieldname ||''''

Позже вы откроете курсор следующим образом:

OPEN newrow_cursor FOR query3_str USING 'fieldname';

Итак, вы передаете параметр динамическому запросу, который не включаетлюбые параметры-заполнители.Это должно выкинуть

ORA-01006: переменная связывания не существует

Динамический SQL сложен, потому что он превращает ошибки компиляции в ошибки времени выполнения.Вам нужно проявить хладнокровие, чтобы смотреть на ваш код, чтобы определить их.Одна вещь, которая поможет, - это использовать протоколирование для записи динамического оператора (DBMS_OUTPUT лучше, чем ничего).Обычно, когда у нас есть фактическое утверждение перед нашими глазами, легко обнаружить наших шароваров.Но если мы не можем, по крайней мере, можем выполнить запрос и позволить компилятору указать их.

...