Грешка в 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 := 'SELECT COUNT(*) FROM V$SESSION WHERE STATUS = ''INACTIVE'' AND LAST_CALL_ET > 0';

не :

sqlquery := 'SELECT COUNT(*) FROM V$SESSION WHERE STATUS = 'INACTIVE' AND 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