Встроенная таблица в Oracle SQL - PullRequest
1 голос
/ 31 марта 2011

Я пытаюсь интегрироваться с некоторым программным обеспечением (которое я не могу изменить), которое запрашивает базу данных, которую я могу изменить.

Я могу дать этому программному обеспечению SQL-запросы, например, так "выберите имя пользователя, имя, фамилия от пользователей, где имя пользователя в? "

Программное обеспечение, чем заполняет?с чем-то вроде ('Алиса', 'Боб'), и получает информацию о пользователях для них.

Дело в том, что есть еще одна часть программного обеспечения, которую я снова не могу изменить, которая иногда генерирует таких пользователей, как 'user2343290и передает их на первый кусок программного обеспечения.Конечно, он выдает ошибки, потому что не может найти этого пользователя.

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

select username, firstname, lastname from users where username in ?
UNION ALL
select t.column1, 'Unknown', 'Unknown' from create_table(?) t

, где create_table генерирует таблицу со строкамиупоминается в?, с первым столбцом с именем column1.

Или в качестве альтернативы:

select username, firstname, lastname from users where username in ?
UNION ALL
select t.column1, 'Unknown', 'Unknown' from _universe_ t where t.column1 in ?

, где _universe_ - это некоторая поддельная таблица, которая содержит все возможные значения в column1 (т.е. бесконечно большие).

Я пробовал выбрать?от двойного, но, к сожалению, это работало только когда?было что-то вроде ('x'), а не ('x', 'y').

Имейте в виду, я не могу изменить формат как?выходит, так что я не могу сделать select 'alice' from dual union all select 'bob' from dual.

Кто-нибудь знает, как я могу сделать то, что я упомянул, или что-то еще, чтобы получить аналогичный эффект?

Ответы [ 2 ]

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

Вы можете превратить разделенную строку имен в тип таблицы следующим образом:

CREATE TYPE name_tab AS TABLE OF VARCHAR2(30);
/

SELECT * FROM table(name_tab('alice','bob'));

Так что вам просто нужно создать тип, тогда ваш пример станет:

select username, firstname, lastname from users where username in ?
UNION ALL
select t.column1, 'Unknown', 'Unknown' from table(name_tab ?) t

(Я предполагаю, что? Заменяется простой текстовой подстановкой - потому что IN не будет работать, если это было сделано как переменная связывания - и что замещенный текст содержит круглые скобки.)

Однако я не уверен, что результат этого будет полезен, поскольку, когда дается список хороших имен пользователей, теперь у вас будет две строки результатов для каждого имени пользователя, одна с действительной информацией, а другая со значениями «Неизвестно».

Лучшим способом формулировки запроса может быть:

select t.column_value username,
       NVL(users.firstname,'Unknown'),
       NVL(users.lastname,'Unknown')
  from table(name_tab ?) t left join users on users.username = t.column_value

Это должно дать вам одну строку на имя пользователя, с фактическими данными, если они существуют, или значениями «Неизвестно», если онне.

0 голосов
/ 31 марта 2011

Вы можете использовать конвейерную функцию:

create type empname_t is table of varchar2(100);

create or replace function to_list(p_Names in string) return empname_t pipelined is
begin
  pipe row(p_Names);
  return;
end;

select * from table(to_list('bob'))

Если вам нужно разделить имена (например, «bob, alice»), вы можете использовать функцию, принимающую строку и возвращающую empname_t, например, Список участников Тома Кайта, см.
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:210612357425
и измените функцию to_list для перебора коллекции и передачи каждого элемента из коллекции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...