我编写了 PL/SQL 代码来将表非规范化为更易于查询的形式。该代码使用一个临时表来完成它的一些工作,将原始表中的一些行合并在一起。
该逻辑按照链接文章中的模式编写为流水线表函数。table 函数使用PRAGMA AUTONOMOUS_TRANSACTION
声明来允许临时表操作,并且还接受游标输入参数以将非规范化限制为某些 ID 值。
然后我创建了一个视图来查询表函数,将所有可能的 ID 值作为游标传递(该函数的其他用途将更具限制性)。
我的问题:这一切真的有必要吗?我是否完全错过了完成同一件事的更简单的方法?
每次我接触 PL/SQL 时,我都会觉得我打字太多了。
更新:我将添加我正在处理的表格的草图,让每个人都了解我正在谈论的非规范化。该表存储员工工作的历史记录,每个工作都有一个激活行和(可能)一个终止行。员工可能同时拥有多个工作,以及在不连续的日期范围内一遍又一遍地从事相同的工作。例如:
| EMP_ID | JOB_ID | STATUS | EFF_DATE | other columns...
| 1 | 10 | A | 10-JAN-2008 |
| 2 | 11 | A | 13-JAN-2008 |
| 1 | 12 | A | 20-JAN-2008 |
| 2 | 11 | T | 01-FEB-2008 |
| 1 | 10 | T | 02-FEB-2008 |
| 2 | 11 | A | 20-FEB-2008 |
查询它以找出谁在做什么工作是不平凡的。EMP_ID
因此,对于通过游标传入的任何 s,我的非规范化函数仅使用每个作业的日期范围填充临时表。传入EMP_ID
s 1 和 2 将产生以下结果:
| EMP_ID | JOB_ID | START_DATE | END_DATE |
| 1 | 10 | 10-JAN-2008 | 02-FEB-2008 |
| 2 | 11 | 13-JAN-2008 | 01-FEB-2008 |
| 1 | 12 | 20-JAN-2008 | |
| 2 | 11 | 20-FEB-2008 | |
(END_DATE
允许NULL
s 用于没有预定终止日期的工作。)
可以想象,这种非规范化的形式查询起来要容易得多,但是创建它——据我所知——需要一个临时表来存储中间结果(例如,激活行已被激活的作业记录)找到了,但没有终止……还没有)。使用流水线表函数填充临时表,然后返回其行是我想出的唯一方法。