Oracle:纯PL / SQL数据提取和使用临时表的匿名化,只读权限

我正在尝试创建一个PL / SQL脚本,它从oracle生产数据库中提取所有子项和其他相关信息的根“对象”.目的是创建一组测试数据以重新创建生产中遇到的问题.由于数据保护法,数据在提取时需要匿名化 – 对象名称,某些类型的ID和货币金额需要被替换.

我试图创建一个或多个临时转换表,其中包含原始值和匿名版本.然后我将真实数据与转换表一起加入,并在需要时输出匿名值.

DECLARE
  rootId integer := 123456;

  TYPE anonTableRow IS RECORD 
  (
    id NUMBER,
    fieldC NUMBER,
    anonymizedFieldC NUMBER
  );

  TYPE anonTable IS TABLE OF anonTableRow;
  anonObject anonTable;
BEGIN

  FOR cursor_row IN 
  (
    select 
     id,
     fieldC,
     1234 -- Here I would create anonymized values based on rowNum or something similar
    from 
    prodTable
    where id = rootId
  ) 
  LOOP       
    i := i + 1;
    anonObject(i) := cursor_row; 
  END LOOP;

  FOR cursor_row IN 
  (
    select 
    prod_table.id,
    prod_table.fieldB,
    temp_table.anonymizedFieldC fieldC,
    prod_table.fieldD
    from 
    prod_table
    inner join table(temp_table) on prod_table.id = temp_table.id
    where prod_table.id = 123456789
  ) 
  LOOP       
   dbms_output.put_line('INSERT INTO prod_table VALUES (' || cursor_row.id || ', ' || cursor_row.fieldB || ', ' || cursor_row.fieldC || ', , ' || cursor_row.fieldD);
  END LOOP;
END;
/

但是我遇到了这种方法的几个问题 – 似乎几乎不可能将oracle PL / SQL表与真实的数据库表连接起来.我对生产数据库的访问受到严格限制,因此我无法创建全局临时表,声明PL / SQL之外的类型或任何类型的类型.

我尝试声明自己的PL / SQL类型失败了问题mentioned in this question – 由于权限有限,解决方案对我不起作用.

有没有纯粹的PL / SQL方式,不需要花哨的权限来实现上述的东西?

请注意:上面的代码示例经过了简化,并不需要单独的转换表 – 实际上我需要在几个不同的查询中访问原始值和翻译值,所以我不希望在任何地方“重新计算”翻译.

最佳答案 如果您的数据已正确规范化,那么我猜这只应该是内部ID所必需的(不知道为什么您需要翻译它们).

以下代码应该适合您,保持映射在Associative Arrays

DECLARE
  TYPE t_number_mapping IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER;

  mapping_field_c   t_number_mapping;
BEGIN
  -- Prepare mapping
  FOR cur IN (
    SELECT 101 AS field_c FROM dual UNION ALL SELECT 102 FROM dual -- test-data
  ) LOOP
    mapping_field_c(cur.field_c) := mapping_field_c.COUNT;  -- first entry mapped to 1
  END LOOP;

  -- Use mapping
  FOR cur IN (
    SELECT 101 AS field_c FROM dual UNION ALL SELECT 102 FROM dual -- test-data
  ) LOOP
    -- You can use the mapping when generating the `INSERT` statement
    dbms_output.put_line( cur.field_c || ' mapped to ' || mapping_field_c(cur.field_c) );
  END LOOP;
END;

输出:

101 mapped to 1
102 mapped to 2
点赞