自动递增的差异标识和序列/触发器

时间:2016-03-09 19:22:59

标签: database oracle oracle-apex oracle12c

我是apex / oracle db的新手,发现你要么使用序列+触发器(通常用于版本< 12c),要么使用身份列(版本> = 12c)。

什么是更好的做法,两者之间有什么区别?

谢谢:)

2 个答案:

答案 0 :(得分:3)

一个很大的区别是处理父子插入 - 这里首先需要插入父节点,然后使用父表中生成的ID值作为子表插入中的外键。

在这些情况下,使用标识列,您需要能够使用RETURNING子句来获取刚刚插入的ID(所有中间件都不支持),或者您插入父记录然后查询获取已创建的ID,以便您可以将其用作子表中的FK值。如果您的表没有自然键来轻松识别刚刚插入的行 - 这可能会有问题。

另一方面,对于这些情况,如果不使用IDENTITY,则首先对序列执行SELECT以获取下一个增量值,然后直接在父和子insert语句中使用它。这是一个更便携的解决方案,如果您可能需要为给定客户端安装到早期版本的Oracle,则与所有Oracle版本兼容。在这种情况下,您没有触发器从序列中进行选择以设置值 - 您自己动手。

是的,这是DB的额外往返,以获得sequence.nextval,但如果您的中间件不支持RETURNING条款,那么您将进行往返无论如何都要获取插入的ID,并且几乎肯定会使用更昂贵的查询。

此外,如果您有一堆PL / SQL库代码使用非常方便的%ROWTYPE约定来操作数据,并且如果您的IDENTITY列设置为GENERATED ALWAYS,那么您可以开始在插入时遇到问题{{{ 3}}。如果想在现有代码库下切换到IDENTITY列,需要注意的事项。

答案 1 :(得分:2)

问题中提到的两个替代方法(IDENTITY列和序列+触发器):即创建一个序列并在列上设置默认值,例如:

CREATE SEQUENCE my_sequence;

CREATE TABLE my_table
( my_column NUMBER DEFAULT my_sequence.nextval NOT NULL
, my_other_column DATE DEFAULT SYSDATE NOT NULL
);