Выполнение запроса с использованием коллекции в качестве аргумента в Oracle - PullRequest
0 голосов
/ 09 мая 2020

Есть ли способ немедленно выполнить запрос с коллекцией в качестве аргумента.

Я хочу определить тип как type my_type as table of number, а затем выполнить динамический c запрос (созданный путем правильного объединения частей), используя execute immediate QUERY using COLLECTION.

Когда я пишу такой код, я получаю PLS-00457 expressions has to be of SQL types.

Ответы [ 2 ]

0 голосов
/ 10 мая 2020

Да, вы можете это сделать, но 1) тип должен быть определен как OBJECT 2) Oracle версия должна быть 11g или выше 3) если ваш блок Dynami c имеет код pl sql, вы можете назначить эту коллекцию значение внутри переменной блока Dynami c, а затем используйте его 4) если ваш блок Dynami c всего лишь какой-то sql, вам нужно сначала преобразовать коллекцию в таблицу, используя ключевое слово Table (collection)

0 голосов
/ 09 мая 2020

Из oracle документации : https://docs.oracle.com/cd/B12037_01/appdev.101/b10807/11_dynam.htm Пример 7-4 Dynami c SQL для типов объектов и коллекций

В приведенном ниже примере показано использование объектов и коллекций. . Предположим, вы определяете тип объекта Person и тип VARRAY Hobbies следующим образом:

CREATE TYPE Person AS OBJECT (name VARCHAR2(25), age NUMBER);
CREATE TYPE Hobbies IS VARRAY(10) OF VARCHAR2(25);

Используя динамический c SQL, вы можете написать пакет, который использует эти типы:

CREATE OR REPLACE PACKAGE teams AS
   PROCEDURE create_table (tab_name VARCHAR2);
   PROCEDURE insert_row (tab_name VARCHAR2, p Person, h Hobbies);
   PROCEDURE print_table (tab_name VARCHAR2);
END;
/

CREATE OR REPLACE PACKAGE BODY teams AS
   PROCEDURE create_table (tab_name VARCHAR2) IS
   BEGIN
      EXECUTE IMMEDIATE 'CREATE TABLE ' || tab_name ||
         ' (pers Person, hobbs Hobbies)';
   END;

   PROCEDURE insert_row (
      tab_name VARCHAR2,
      p Person,
      h Hobbies) IS
   BEGIN
      EXECUTE IMMEDIATE 'INSERT INTO ' || tab_name ||
         ' VALUES (:1, :2)' USING p, h;
   END;

   PROCEDURE print_table (tab_name VARCHAR2) IS
      TYPE RefCurTyp IS REF CURSOR;
      cv RefCurTyp;
      p  Person;
      h  Hobbies;
   BEGIN
      OPEN cv FOR 'SELECT pers, hobbs FROM ' || tab_name;
      LOOP
         FETCH cv INTO p, h;
         EXIT WHEN cv%NOTFOUND;
         -- print attributes of 'p' and elements of 'h'
      END LOOP;
      CLOSE cv;
   END;
END;
/

Из анонимного блока вы можете вызывать процедуры пакета TEAMS:

DECLARE
   team_name VARCHAR2(15);
BEGIN
   team_name := 'Notables';
   teams.create_table(team_name);
   teams.insert_row(team_name, Person('John', 31),
      Hobbies('skiing', 'coin collecting', 'tennis'));
   teams.insert_row(team_name, Person('Mary', 28),
      Hobbies('golf', 'quilting', 'rock climbing'));
   teams.print_table(team_name);
END;
/
...