Как использовать ассоциативные массивы в PL / SQL в условии WHERE, при котором пары ключ-значение ассоциативного массива являются именами столбцов в моей таблице - PullRequest
1 голос
/ 30 января 2020

У меня есть вопрос, касающийся моей проблемы использования ассоциативных массивов внутри запроса sql.

Я использую ORDS (Oracle Rest Data Services) в качестве моего сервера RESTApi. Я могу определить переменные в строке запроса.

Представьте, что я передаю свою переменную в строке запроса следующим образом:

https://MY-HOST-ADDRESS:PORT/rest/v1/list?MyVariable=Value

Я определил свой ассоциативный массив следующим образом:

DECLARE
  TYPE xlatemap is TABLE OF VARCHAR2(64)
    INDEX BY VARCHAR2(64);

  col_xlate xlatemap;

BEGIN
  col_xlate('address')     := 'ci.CAMPUS';
  col_xlate('hostname')    := 'ci.VISIBLE_ID';
  col_xlate('serial')      := 'ci.SERIAL_NO';

То, что я хотел бы сделать, это получить удобные имена переменных (например, адрес , имя хоста и serial ) в строках запроса. Поэтому я создал этот hashmap (associative_array).

Моя цель - использовать этот ассо c массив в моем ГДЕ состоянии, как показано ниже:

SELECT  ci.CAMPIS, ci.VISIBLE_ID, ci.SERIAL_NO
FROM    tableName as ci
WHERE   col_xlate('hostname') like 'RT-101'

Знаете ли вы, как я могу использовать его внутри

1 Ответ

1 голос
/ 30 января 2020

Вы не можете, ассоциативный массив имеет тип данных PL / SQL и не поддерживается в SQL.

. Вы можете использовать коллекции и VARRAY s, определенные в области действия SQL в оператор SQL, но не ассоциативные массивы, так как они могут быть определены только в области PL / SQL.


Если вы хотите, чтобы значение из ассоциативного массива использовалось в качестве имени столбца в SQL тогда вам нужно будет оценить значение из ассоциативного массива в PL / SQL и использовать динамический c SQL для выполнения сгенерированного запроса. (Но вы не можете напрямую использовать ассоциативный массив в операторе SQL.)

DECLARE
  TYPE xlatemap is TABLE OF VARCHAR2(64)
    INDEX BY VARCHAR2(64);

  col_xlate xlatemap;

  p_campis     TABLENAME.CAMPIS%TYPE;
  p_visible_id TABLENAME.VISIBLE_ID%TYPE;
  p_serial_no  TABLENAME.SERIAL_NO%TYPE;
BEGIN
  col_xlate('address')     := 'ci.CAMPUS';
  col_xlate('hostname')    := 'ci.VISIBLE_ID';
  col_xlate('serial')      := 'ci.SERIAL_NO';

  EXECUTE IMMEDIATE 'SELECT  ci.CAMPIS, ci.VISIBLE_ID, ci.SERIAL_NO
                     FROM    tableName ci
                     WHERE   ' || col_xlate('hostname') || ' like ''RT-101'''
  INTO p_campis, p_visible_id, p_serial_no;
  -- this may need to be BULK COLLECT INTO if you are going to return multiple rows.

  -- do something with the variables;
END;
/

Если вы хотите сделать это в SQL, вам нужно будет использовать коллекцию (или VARRAY), определенный в области действия SQL:

Oracle Настройка :

CREATE TYPE key_value_pair AS OBJECT(
  key   VARCHAR2(64),
  value VARCHAR2(64)
);

CREATE TYPE key_value_pair_table AS TABLE OF key_value_pair;

Данные испытаний :

CREATE TABLE table_name ( CAMPIS, VISIBLE_ID, SERIAL_NO ) AS
SELECT 'A1', 'A2', 'A3' FROM DUAL UNION ALL
SELECT 'B1', 'B2', 'B3' FROM DUAL UNION ALL
SELECT 'C1', 'C2', 'C3' FROM DUAL

Запрос :

SELECT *
FROM   table_name
WHERE  CASE ( SELECT value
              FROM TABLE(
                key_value_pair_table(
                  key_value_pair( 'address',  'CAMPIS' ),
                  key_value_pair( 'hostname', 'VISIBLE_ID' ),
                  key_value_pair( 'serial',   'SERIAL_NO' )
                )
              )
              WHERE key = 'hostname'
            )
       WHEN 'CAMPIS'     THEN campis
       WHEN 'VISIBLE_ID' THEN visible_id
       WHEN 'SERIAL_NO'  THEN serial_no
       END
       IN ( 'A2', 'B2' )

, но кажется, что вы можете просто исключить массив и просто использовать оператор case:

SELECT *
FROM   table_name
WHERE  CASE 'hostname' -- your variable
       WHEN 'address' THEN campis
       WHEN 'hostname'THEN visible_id
       WHEN 'serial'  THEN serial_no
       END
       IN ( 'A2', 'B2' )

Выход :

Оба выхода:

CAMPIS | VISIBLE_ID | SERIAL_NO
:----- | :--------- | :--------
A1     | A2         | A3       
B1     | B2         | B3       

db <> скрипка здесь

...