2

我们在 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 允许使用标准 SQL 选择语句与 Oracle 服务器进行通信,但由于用户不知道键值,他们无法编写 SQL 语句来查询数据。

Tableau 最近增加了用户查询 Oracle 表函数的能力,所以我开始写一个表函数来查询键,并返回一个结果表供 Tableau 使用。问题是每个 dat_ 表基本上是唯一的,具有不同数量的列、标签、记录数和下一个 dat_ 表的数据类型。

处理这个问题的正确方法是什么?我可以吗:

1)编写一个函数(哪个tableau可以在常规SQL中调用内联)来返回一个动态生成的bonified表名?我试过这个:

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 可以查询这些类似的表,但后来我遇到了动态生成类型的问题(我理解这并不容易),但是这增加了需要多个用户同时使用的复杂性,所以每个用户都需要一个每次连接到表时为他们生成的数据类型(如果我理解正确的话)。

我不得不认为我错过了一些简单的东西。如何将此查询的返回转换为其他表的数据类型?

4

2 回答 2

1

没有简单的方法可以让单个泛型函数返回动态可配置的嵌套表。对于其他产品,您可以使用 Ref Cursor(映射到 ODBC 或 JDBCResultSet对象),但我的理解是 Tableau 不支持该选项。

您可以做的一件事是从数据字典生成视图。您可以使用此查询生成一次性脚本。

select 'create or replace view "' || name || '" as select * from dat_' || key || ';'
from tab_keys;  

由于破折号,双引号是必要的,因为AB-7它在 Oracle 中不是有效的对象名称。

这将允许您的用户像这样查询他们的数据:

select * from "AB-7";

请注意,他们也必须使用双引号。

显然,任何时候插入一行tab_keys都需要创建所需的视图。这可以通过触发器来完成。

于 2019-03-26T17:33:36.393 回答
0

您可以使用开源程序Method4在 SQL 中构建动态 SQL :

select * from table(method4.dynamic_query(
    q'[
        select 'select *  from dat_'||key
        from tab_keys
        where name = 'AB-7'
    ]'
));

A
-
1

该程序将 Oracle Data Cartridge Interface 与ANYDATASET创建一个可以返回动态类型的函数相结合。

可能有一种方法可以进一步简化界面,但我还没有弄清楚。这些 Oracle Data Cartridge Interface 功能非常挑剔,不容易重新打包。

这是我使用的示例架构:

create table tab_keys(name varchar2(100), key varchar2(100));
insert into tab_keys
select 'AB-7' , '19756' from dual union all
select 'BG-0' , '76519' from dual union all
select 'FY-10', '79513' from dual union all
select 'JB-2' , '18765' from dual;

create table dat_19756 as select 1 a from dual;
create table dat_76519 as select 2 b from dual;
create table dat_79513 as select 3 c from dual;
create table dat_18765 as select 4 d from dual;
于 2019-03-27T00:32:59.810 回答