oracle – 将表列转换为键值对

我写加载从架构A一些数据架构B的PL / SQL程序,他们都非常不同的模式,我不能改变模式B的结构

在架构A的各种表的列(在视图中连接在一起)需要被插入到架构B为键=>值对在2列在一个表中,每一个单独的行.例如,员工的名字可能在Schema A中作为employee.firstname出现,但需要在Schema B中输入:

id=>1, key=>'A123', value=>'Smith'

有将近100个密钥,将来有可能增加更多密钥.这意味着我真的不想硬编码任何这些键.

示例代码:

create table schema_a_employees (
    emp_id number(8,0),
    firstname varchar2(50),
    surname varchar2(50)
);
insert into schema_a_employees values ( 1, 'James', 'Smith' );
insert into schema_a_employees values ( 2, 'Fred', 'Jones' );

create table schema_b_values (
    emp_id number(8,0),
    the_key varchar2(5),
    the_value varchar2(200)
);

我认为一个优雅的解决方案很可能涉及一个查找表来确定为每个键插入什么值,并且不涉及有效地硬编码几十个类似的语句,如….

insert into schema_b_values ( 1, 'A123', v_firstname );
insert into schema_b_values ( 1, 'B123', v_surname );

我希望能够做的就是在架构A本地查找表,列出所有的键从架构B,与给列的名称在架构A表中应使用一列沿填充,例如模式B中的密钥“A123”应填充模式A中“firstname”列的值,例如:

create table schema_a_lookup (
    the_key varchar2(5),
    the_local_field_name varchar2(50)
);
insert into schema_a_lookup values ( 'A123', 'firstname' );
insert into schema_a_lookup values ( 'B123', 'surname' );

但我不确定如何动态使用查找表中的值来告诉Oracle使用哪些列.

所以我的问题是,是否有一个优雅的解决方案来用schema_a_employees数据schema_b_values表没有硬编码每一个可能的密钥(即A123,B123等)?

干杯.

最佳答案 我衷心希望您的架构B不是
dreaded
key-value pair设计.虽然某些动态属性值表在某些情况下可能很有用,但您会发现除了最基本的查询之外的所有查询几乎都不可能在EAV设计中编写(即使像“找到所有名为John Smith的员工”这样的简单查询也是如此)很难写 – 也无法调整.

无论如何,在您的情况下,您想要编写一个如下所示的动态查询:

SQL> INSERT ALL
  2     INTO schema_b_values VALUES (emp_id, 'A123', firstname)
  3     INTO schema_b_values VALUES (emp_id, 'B123', surname)
  4     SELECT emp_id, firstname, surname
  5       FROM schema_a_employees;

4 rows inserted

您可以使用以下查询生成语句:

SQL> SELECT 'INSERT ALL ' sql_lines FROM dual
  2  UNION ALL
  3  SELECT 'INTO schema_b_values VALUES (emp_id, '''
  4            || dbms_assert.simple_sql_name(the_key)
  5            || ''', '
  6            || dbms_assert.simple_sql_name(the_local_field_name)
  7            ||')'
  8    FROM schema_a_lookup
  9  UNION ALL
 10  SELECT 'SELECT * FROM schema_a_employees' FROM dual;

SQL_LINES
--------------------------------------------------------------------------------
INSERT ALL
INTO schema_b_values VALUES (emp_id, 'A123', firstname)
INTO schema_b_values VALUES (emp_id, 'B123', surname)
SELECT * FROM schema_a_employees

然后,您可以使用EXECUTE IMMEDIATE或DBMS_SQL来执行该语句.

点赞