Как использовать Collection как таблицу для UPDATE с предложением IN - PullRequest
0 голосов
/ 11 июня 2019

Мне нужен этот фрагмент кода в хранимой процедуре, чтобы я мог передать массив идентификаторов и обновить соответствующие записи.Мне интересно, должен ли я использовать цикл вместо использования предложения IN в sp.

SET SERVEROUTPUT ON

DECLARE 
  P_IDS PKGINFO.t_ids; --type: table of NUMBER index by pls_integer;
  P_RESULT NUMBER;  

BEGIN 
  p_IDS(1) := 12345;

--this works fine:  
  for i in ( select * from table(p_ids))
    loop    
    UPDATE TABLE1
    SET FD1 = 'test'    
    WHERE     P_ID = i.column_value;
   end loop;

--this works fine too:   
   SELECT COUNT(*) INTO p_RESULT FROM TABLE1
   WHERE  P_ID IN (SELECT * FROM TABLE (p_ids));

--but this does not work, why????? how to make it work?
  UPDATE TABLE1
    SET FD1 = 'test'    
    WHERE  P_ID IN (SELECT * FROM TABLE (p_ids));

END;

--==================PKGINFO.t_ids==================
CREATE OR REPLACE package dbname.PKGINFO as
  -- package created to perform Associative array calls
  type t_ids is table of NUMBER index by pls_integer;
end PKGINFO;
/

Я ожидал, что UPDATE может использовать предложение IN, но выдает ошибку INVALID TYPE.

1 Ответ

1 голос
/ 11 июня 2019

До недавнего времени Oracle не разрешал типы PL / SQL в операторах SQL, в том числе в выражении коллекции таблиц .Похоже, вы используете версию, в которой была добавлена ​​поддержка для select, но нет (пока) для update.Если у вас есть один доступный, то вы можете использовать тип уровня схемы.Также взгляните на member of.

С имеющимся у вас типом вы можете использовать FORALL, что будет более эффективным, чем цикл с отдельными обновлениями ::

FORALL i IN p_ids.first..p_ids.last
UPDATE TABLE1
  SET FD1 = 'test'    
  WHERE P_ID = p_ids(i); 
...