У нас большой объем данных на сервере Oracle 11g. Большинство инженеров используют Tableau для визуализации данных, но в настоящее время не существует отличного решения для визуализации прямо с сервера Oracle из-за структуры базы данных. К сожалению, это невозможно изменить, поскольку оно очень глубоко интегрировано с остальными нашими системами. Есть таблица «словарь», назовем ее tab_keys
:
name | key
---------------
AB-7 | 19756
BG-0 | 76519
FY-10 | 79513
JB-2 | 18765
...
...
И есть также таблицы, фактически содержащие данные. Каждая запись в tab_keys
имеет соответствующую таблицу данных, названную префиксом ключа с идентификатором, в этом случае мы будем использовать «dat_». Таким образом, AB-7 будет хранить все свои данные в таблице с именем dat_19756
. Эти ключи не известны пользователю и используются только для отслеживания «за кадром». Пользователь знает только прозвище AB-7.
Tableau позволяет взаимодействовать с серверами Oracle с помощью стандартных операторов выбора SQL, но поскольку пользователь не знает значения ключа, он не может написать оператор SQL для запроса данных.
Tableau недавно добавила возможность пользователям запрашивать функции таблиц Oracle, поэтому я начал идти по пути написания табличной функции для запроса ключа и возврата таблицы результатов для использования в Tableau. Проблема состоит в том, что каждая таблица dat_ в основном уникальна с различным количеством столбцов, меток, количества записей и типов данных из следующей таблицы dat_.
Как правильно решить эту проблему? Могу ли я:
1) Написать функцию (какая таблица может вызывать inline в обычном SQL), чтобы возвращать объединенное имя таблицы, которое генерируется динамически? Я попробовал это:
create or replace FUNCTION TEST_FUNC
(
V_NAME IN VARCHAR2
) RETURN user_tables.table_name%type AS
V_KEY VARCHAR(100);
V_TABLE user_tables.table_name%type;
BEGIN
select KEY into V_KEY from my_schema.tab_keys where NAME = V_NAME;
V_TABLE := dbms_assert.sql_object_name('my_schema.dat_' || V_KEY);
RETURN V_TABLE;
END TEST_FUNC;
а затем SELECT * from TABLE(TEST_FUNC('AB-7'));
но я получаю:
ORA-22905: cannot access rows from a non-nested table item
22905. 00000 - "cannot access rows from a non-nested table item"
*Cause: attempt to access rows of an item whose type is not known at
parse time or that is not of a nested table type
*Action: use CAST to cast the item to a nested table type
Я не мог придумать хороший способ ЗАКРЫТЬ таблицу как нужный мне тип таблицы. Можно ли это сделать в функции перед возвратом?
2) Написать табличную функцию? Якобы Tableau может запрашивать подобные таблицы, но затем я сталкиваюсь с проблемой динамической генерации типов (что, как я понимаю, нелегко), но с дополнительным усложнением необходимости одновременного использования несколькими пользователями, поэтому каждому пользователю потребуется Тип данных генерируется для них каждый раз, когда они подключаются к таблице (если я правильно понимаю).
Я должен думать, что мне не хватает чего-то простого. Как привести результат этого запроса к типу данных другой таблицы?