Ошибка в коде plsql

Пожалуйста, помогите мне решить эту ошибку в plsql.

 sqlquery := 'SELECT COUNT(*) FROM V$SESSION WHERE STATUS = 'INACTIVE' AND LAST_CALL_ET > 0';
 EXECUTE IMMEDIATE sqlquery into s_count;

ниже ошибка:

  ERROR at line 57:
  ORA-06550: line 57, column 66:
  PLS-00103: Encountered the symbol "INACTIVE" when expecting one of the following:
  * & = - + ; < / > at in is mod remainder not rem
  <an exponent (**)> <> or != or ~= >= <= <> and or like like2
  like4 likec between || multiset member submultiset
  The symbol "* was inserted before "INACTIVE" to continue.
  ORA-06550: line 79, column 4:
  PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following:
  ( begin case declare else elsif end exit for goto if loop mod
  null pragma raise return select update while with <an identifier> <a double-quoted
  ORA-06550: line 81, column 7:
  PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
  end not pragma final instantiable order overriding static member constructor map

person user3422419    schedule 11.04.2014    source источник
comment
Это действительно нужно делать с EXECUTE IMMEDIATE? Запрос не является динамическим, поэтому вы сможете реализовать его со стандартным курсором и OPEN, FETCH, CLOSE или SELECT INTO.   -  person Rob Baillie    schedule 11.04.2014
comment
По сути, это та же проблема, что и, например. stackoverflow.com/a/22810334/272735   -  person user272735    schedule 11.04.2014
comment
Этот вопрос кажется не по теме, потому что речь идет о простой опечатке.   -  person Jeffrey Kemp    schedule 11.04.2014
comment
Также как stackoverflow.com/questions/48172315/   -  person William Robertson    schedule 26.02.2018


Ответы (9)


Кавычки вокруг INACTIVE разбивают строку и вызывают синтаксическую ошибку...

sqlquery := 'SELECT COUNT(*) FROM V$SESSION WHERE STATUS = ''INACTIVE'' AND LAST_CALL_ET > 0';
EXECUTE IMMEDIATE sqlquery into s_count;

Конечно, если оператор на самом деле не является динамическим, вам не нужен EXECUTE IMMEDIATE, и вместо этого вы можете использовать:

SELECT COUNT(*)
INTO   s_count
FROM   V$SESSION
WHERE  STATUS = 'INACTIVE'
AND    LAST_CALL_ET > 0';
person Rob Baillie    schedule 11.04.2014

Используйте следующий запрос:

sqlquery := 'SELECT COUNT(*) FROM V$SESSION WHERE STATUS = ''INACTIVE'' AND LAST_CALL_ET > 0';
person Shamim Ahmed    schedule 02.11.2015

Решение с немедленным выполнением

set serveroutput on;
declare
   l_status varchar2(30):= '''INACTIVE''';
   s_count number:= 0;
sqlquery varchar2(32767) := null;
begin
sqlquery := 'SELECT COUNT(*) FROM V$SESSION WHERE STATUS = '||l_status||' AND LAST_CALL_ET > 0';
EXECUTE IMMEDIATE sqlquery into s_count;
dbms_output.put_line(s_count);
end;
person Vedran Turković    schedule 31.03.2015

Пожалуйста, измените запрос как sqlquery := 'SELECT COUNT(*) FROM V$SESSION WHERE STATUS = '''INACTIVE''' AND LAST_CALL_ET > 0'; НЕМЕДЛЕННО ВЫПОЛНИТЬ sqlquery в s_count;

person Arun nath    schedule 22.10.2015

Свяжите переменные, как сказала Чандра!

Один из способов, которым мне нравится назначать SQL:

declare
  vSQL varchar2( 100 ) ;
begin
  vSQL := q'[select 'done' from dual ]' ;
  dbms_output.put_line( vSQL ) ;
end ;

поэтому вы бы сделали:

sqlquery := q'[SELECT COUNT(*) FROM V$SESSION WHERE STATUS = :status AND LAST_CALL_ET > 0]';
person JustinKaisse    schedule 09.03.2016

использовать :

sqlquery := 'ВЫБЕРИТЕ COUNT(*) ИЗ V$SESSION, ГДЕ СТАТУС = ''НЕАКТИВНО'' AND LAST_CALL_ET > 0';

нет :

sqlquery := 'ВЫБЕРИТЕ COUNT(*) ИЗ V$SESSION, ГДЕ СТАТУС = 'НЕАКТИВНО' И LAST_CALL_ET > 0';

person Chakib Arrama    schedule 09.02.2017

используйте этот код, он будет работать отлично

set serveroutput on
    DECLARE
    sqlquery    varchar2(1000);
    INACTIVE    varchar2(100):='INACTIVE';
    s_count     number;
    begin
    sqlquery := 'SELECT COUNT(*) FROM V$SESSION WHERE STATUS = '''||INACTIVE||''' AND LAST_CALL_ET > 0';
    EXECUTE IMMEDIATE sqlquery into s_count;
    DBMS_OUTPUT.PUT_LINE(s_count);
    end;
    /
person Sakib Mulla    schedule 12.08.2018

Другой способ сделать это:

            set serveroutput on;
            DECLARE
                sqlquery VARCHAR2(4000);
                s_count number;
            begin
                sqlquery := 'SELECT COUNT(*) FROM V$SESSION WHERE STATUS = '||chr(39)||'INACTIVE'||chr(39)||' AND LAST_CALL_ET > 0';
                EXECUTE IMMEDIATE sqlquery into s_count;
                dbms_output.put_line('s_count--'||s_count);
            end;
            /
person sudhirkondle    schedule 24.07.2019

person    schedule
comment
Пожалуйста, объясните свой ответ - person Suresh Karia; 22.07.2015
comment
в переменной sqlquery вы можете видеть: a используется в качестве переменной привязки. Позже это значение передается при выполнении EXECUTE IMMEDIATE sqlquery в s_count с помощью l_status ; с помощью l_status. Это похоже на подготовленныйStatment в java. - person Chandra kishor Gauro; 23.07.2015
comment
это также безопасно по сравнению с традиционной конкатенацией строк. - person clq; 15.10.2015