PL SQL Проблема: PLS-00382: выражение имеет неправильный тип, и параметры одного типа - PullRequest
0 голосов
/ 31 марта 2020

У меня есть процедура, которая будет l oop строка, разделенная запятыми, и будет выполнять оператор обновления на основе каждого значения, это таблица:

ID                        NUMBER
MOVEMENT_NUMBER           VARCHAR(150)
STATUS                    VARCHAR(500)

, и это код pl sql

 PROCEDURE updateAutomotiveDeliveryStatus(P_MOVEMENT_NUMBERS IN varchar)
  is
  temp varchar2(500);
  BEGIN
 FOR temp IN
   (SELECT trim(regexp_substr(P_MOVEMENT_NUMBERS, '[^,]+', 1, LEVEL)) l
     FROM dual
        CONNECT BY LEVEL <= regexp_count(P_MOVEMENT_NUMBERS, ',')+1
      )
      LOOP
      update hr.test1 te set te.status = 'completed'
      where status = temp ;
       --dbms_output.put_line(MOVEMENT_NUM.*);
    END LOOP;
  END;

но я продолжаю получать эту ошибку в условии where

[Ошибка] PLS-00382 (28: 22): PLS-00382: выражение имеет неправильный тип

Ответы [ 2 ]

1 голос
/ 31 марта 2020

Вы отправили слишком много кода, поэтому я удалил его.

Что касается полученной ошибки: вы не можете установить значение курсор , но переменная курсора - temp.l в вашем случае.

Пример данных:

SQL> create table test1 (status varchar2(20));

Table created.

SQL> insert into test1
  2    select 'A' from dual union all
  3    select 'C' from dual union all
  4    select 'D' from dual;

3 rows created.

SQL> select * From test1;

STATUS
--------------------
A
C
D

SQL>

Процедура: обратите внимание, что объявленная вами переменная (строка # 4) вообще не используется, поэтому удалите ее. Это temp отличается от temp, используемого в курсоре for l oop.

SQL> create or replace
  2  PROCEDURE updateAutomotiveDeliveryStatus(P_MOVEMENT_NUMBERS IN varchar)
  3    is
  4    -- temp varchar2(500); unnecessary; you don't do anything with it
  5  BEGIN
  6    FOR temp IN
  7     (SELECT trim(regexp_substr(P_MOVEMENT_NUMBERS, '[^,]+', 1, LEVEL)) l
  8       FROM dual
  9          CONNECT BY LEVEL <= regexp_count(P_MOVEMENT_NUMBERS, ',')+1
 10     )
 11     LOOP
 12       update test1 te set te.status = 'completed'
 13         where status = temp.l ;
 14     END LOOP;
 15  END;
 16  /

Procedure created.

Тестирование:

SQL> exec updateAutomotiveDeliveryStatus('A,B,C');

PL/SQL procedure successfully completed.

SQL> select * from test1;

STATUS
--------------------
completed
completed
D

SQL>
1 голос
/ 31 марта 2020

temp - курсор . Вам нужно ссылаться на его атрибуты, в данном случае на псевдоним l.

temp, объявленный в разделе переменных, игнорируется, так как находится вне области видимости. То есть конструкция FOR ... L OOP определяет курсор, а код в l oop ссылается на курсор, а не на любую переменную, определенную вне курсора.

PROCEDURE updateAutomotiveDeliveryStatus(P_MOVEMENT_NUMBERS IN varchar)
  is
BEGIN
  FOR temp IN
    (SELECT trim(regexp_substr(P_MOVEMENT_NUMBERS, '[^,]+', 1, LEVEL)) l
     FROM dual
        CONNECT BY LEVEL <= regexp_count(P_MOVEMENT_NUMBERS, ',')+1
     )
  LOOP
    update hr.test1 te 
    set te.status = 'completed'
    where status = temp.l ;
       --dbms_output.put_line(MOVEMENT_NUM.*);
  END LOOP;
END;

но что означает l

l - псевдоним столбца. Мы не можем ссылаться на выражение типа trim(regexp_substr(P_MOVEMENT_NUMBERS, '[^,]+', 1, LEVEL)), поэтому мы даем ему псевдоним, который мы можем использовать в SQL или PL / SQL. Обычно рекомендуется использовать значимое имя, например, movement_number, чтобы сделать код более читабельным.

...