Ошибка недопустимого оператора SQL с рефкурсором

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

ORA-00900: недопустимый оператор SQL ORA-01008: не все переменные связаны ORA-00900: недопустимый оператор SQL

VARIABLE reader refcursor;
DECLARE
  line varchar2(32767);
BEGIN
  line := 'SELECT role_id,';
  FOR n IN (SELECT name
              FROM (SELECT competence.skill_role.role_id,
                           competence.skill_label.name,
                           competence.skill_role.target_value
                      FROM competence.skill_role,
                           competence.skill_label
                     WHERE competence.skill_label.skill_id =
                           competence.skill_role.skill_id
                       AND competence.skill_label.language_id = 1)
                       matrix_result ) LOOP
    line := line || '(decode(name,''' || n.name ||
            ''',target_value)) "' || n.name || '",';
  END LOOP;
  line := RTRIM(line, ',') ||
    ' FROM (SELECT competence.skill_role.role_id,
                   competence.skill_label.name,
                   competence.skill_role.target_value
              FROM competence.skill_role, competence.skill_label
             WHERE competence.skill_label.skill_id =
                   competence.skill_role.skill_id
               AND competence.skill_label.language_id = 1) matrix_result';
--dbms_output.put_line(line);
--execute immediate line;
 OPEN :reader FOR line;
END;
/
PRINT :reader;

Табличные данные

CREATE TABLE competence.skill_role
  (skill_id  NUMBER,
   role_id NUMBER,
   target_value NUMBER)
/
INSERT ALL 
INTO competence.skill_role VALUES (3432030, 1421866, 2)
INTO competence.skill_role VALUES (3434962, 1421866, 2)
INTO competence.skill_role VALUES (3488025, 3488804, 4)


SELECT * FROM competence.skill_role

SKILL_ID ROLE_ID     target_value
---------- -------   -----------
3432030 1421866       2
3434962 1421866       2
3488025 3488804       4


CREATE TABLE competence.skill_label
  (skill_id  NUMBER,
   name vchar2 (30))
/
INSERT ALL 
INTO competence.skill_label VALUES (3432030, 'Alueen projektipätevyys')
INTO competence.skill_label VALUES (3434962, 'Moottorin koekäyttö')
INTO competence.skill_label VALUES (3488025, 'Etähallintajärjestelmät')


SELECT * FROM arc_competence.skill_label

SKILL_ID NAME
---------- -------
3432030, Alueen projektipätevyys
3434962, Moottorin koekäyttö
3488025, Etähallintajärjestelmät

Я бы хотел получить следующий результат по первому запросу. Из вашего ответа (если я правильно понял) кажется, что мне нужно вручную запустить полученный запрос, чтобы получить ответ. Я бы хотел получить результат без выполнения результирующего запроса :-) У меня сейчас нет доступа к клиентской машине, но я собираюсь туда сейчас.

ROLE_ID     Alueen projektipätevyys  Moottorin koekäyttö    Etähallintajärjestelmät          
1421866          2                      2
3488804                                                            4       

person Jaanna    schedule 24.04.2012    source источник
comment
Если вы раскомментируете вызов dbms_output.put_line перед вашим OPEN, какой оператор SQL он показывает?   -  person Justin Cave    schedule 24.04.2012
comment
Я получаю результат SQL-запроса (который сам по себе является действительным SQL-запросом для динамического поворота)   -  person Jaanna    schedule 24.04.2012
comment
Тогда я в замешательстве. Если line является допустимым SQL-запросом, ваш код будет успешно выполнен (как я продемонстрировал ниже). Если вы получаете сообщение об ошибке, это означает, что генерируемый вами оператор SQL недействителен или что существует еще одна проблема, о которой вы не упомянули.   -  person Justin Cave    schedule 24.04.2012


Ответы (1)


Если я исправлю ваш код, чтобы он компилировался

  • В ваших INSERT ALL заявлениях отсутствует SELECT
  • Столбец name в skill_label определяется как vchar2(30), а не как varchar2(30)
  • Ваш анонимный блок ссылается на столбец language_id, который ваш DDL не включает

код работает без ошибок. Если единственная проблема заключается в том, что вы хотите объединить первые две строки в одну, вам просто нужно добавить MAX ко всем столбцам, кроме ROLE_ID, и добавить GROUP BY role_id к вашему запросу.

SQL> ed
Wrote file afiedt.buf

  1  CREATE TABLE skill_role
  2    (skill_id  NUMBER,
  3     role_id NUMBER,
  4*    target_value NUMBER)
SQL> /

Table created.

SQL> ed
Wrote file afiedt.buf

  1  INSERT ALL
  2  INTO skill_role VALUES (3432030, 1421866, 2)
  3  INTO skill_role VALUES (3434962, 1421866, 2)
  4  INTO skill_role VALUES (3488025, 3488804, 4)
  5* select * from dual
SQL> /

3 rows created.


SQL> ed
Wrote file afiedt.buf

  1  CREATE TABLE skill_label
  2    (skill_id  NUMBER,
  3*    name varchar2 (30))
SQL> /

Table created.

SQL> ed
Wrote file afiedt.buf

  1  INSERT ALL
  2  INTO skill_label VALUES (3432030, 'Alueen projektipΣtevyys')
  3  INTO skill_label VALUES (3434962, 'Moottorin koekΣytt÷')
  4  INTO skill_label VALUES (3488025, 'EtΣhallintajΣrjestelmΣt')
  5* select * from dual
SQL> /

3 rows created.

SQL> commit;

Commit complete.

SQL> variable reader refcursor;

SQL> ed
Wrote file afiedt.buf

  1  DECLARE
  2    line varchar2(32767);
  3  BEGIN
  4    line := 'SELECT role_id,';
  5    FOR n IN (SELECT name
  6                FROM (SELECT skill_role.role_id,
  7                             skill_label.name,
  8                             skill_role.target_value
  9                        FROM skill_role,
 10                             skill_label
 11                       WHERE skill_label.skill_id =
 12                             skill_role.skill_id
 13                         )
 14                         matrix_result ) LOOP
 15      line := line || 'max(decode(name,''' || n.name ||
 16              ''',target_value)) "' || n.name || '",';
 17    END LOOP;
 18    line := RTRIM(line, ',') ||
 19      ' FROM (SELECT skill_role.role_id,
 20                     skill_label.name,
 21                     skill_role.target_value
 22                FROM skill_role, skill_label
 23               WHERE skill_label.skill_id =
 24                     skill_role.skill_id
 25                 ) matrix_result ' ||
 26       ' GROUP BY role_id' ;
 27    dbms_output.put_line(line);
 28    --execute immediate line;
 29    OPEN :reader FOR line;
 30* END;
 31  /

PL/SQL procedure successfully completed.

SQL> print reader

   ROLE_ID Alueen projektipΣtevyys Moottorin koekΣytt÷ EtΣhallintajΣrjestelmΣt
---------- ----------------------- ------------------- -----------------------
   1421866                       2                   2
   3488804                                                                   4
person Justin Cave    schedule 24.04.2012
comment
Спасибо .. Я только что отредактировал свой исходный вопрос, так что покажите желаемый результат. (кстати, как я могу добавить код в свой ответ, потому что теперь я отредактировал свой исходный вопрос, чтобы добавить строки для желаемого результата. - person Jaanna; 25.04.2012
comment
хммм .. где читатель объявлен в вашем коде? (из строки 28) - person Jaanna; 25.04.2012
comment
@Jaanna - Мое объявление reader такое же, как и ваше. Просто кажется, что я забыл включить эту первую строку в свою копию и вставку. Я исправил это и скорректировал код, чтобы возвращать желаемые результаты. - person Justin Cave; 25.04.2012