如何在Postgres中创建SQL Server的标识列的等效项

时间:2017-01-11 06:06:09

标签: sql postgresql auto-increment

有一个应用程序使用MSSQL作为其后端。现在我正在开发代码,以便它可以使用PostgreSQL。我几乎完成了它,除了执行时有这一区别:

保存新应用时

SQL Server代码:

create table tower 
(
  npages integer, 
  ifnds integer, 
  ifnid integer, 
  name varchar(20), 
  towid integer not null IDENTITY
)

PostgreSQL代码:

create table tower 
(
  npages integer, 
  ifnds integer, 
  ifnid integer, 
  name varchar(20)
)

为什么在通过PostgreSQL执行时不会自动生成towid字段(默认字段)?

任何可能的原因?触发器?程序

2 个答案:

答案 0 :(得分:5)

TL;博士

现在在Postgres 10中,根据SQL标准指定GENERATED BY DEFAULT AS IDENTITY

create table tower 
(
  npages integer, 
  ifnds integer, 
  ifnid integer, 
  name varchar(20), 
  towid integer GENERATED BY DEFAULT AS IDENTITY    -- per SQL standard
)

标识列

Postgres 10现在支持identity column的概念,并使用标准的SQL语法。虽然我不是MS SQL Server的专家,但我相信这种新的标准支持是等效的。

GENERATED … AS IDENTITY

GENERATED … AS IDENTITY期间使用的CREATE TABLE命令会创建隐式序列。与SERIAL不同,该序列的创建,命名,权限和删除对您来说是透明的。现在非常直观。如果您授予表的使用权限,则他们将获得序列的权限。如果删除表,则会自动删除序列。

两种标准语法。只有传递值而不是生成值时,差异才有意义。通常,人们总是依赖于生成的值,因此通常只需使用第一个版本GENERATED BY DEFAULT AS IDENTITY

  • GENERATED BY DEFAULT AS IDENTITY
    • 生成值,除非INSERT命令提供值。
  • GENERATED ALWAYS AS IDENTITY
    • 忽略INSERT提供的任何值,除非指定OVERRIDING SYSTEM VALUE

有关文档,请参阅CREATE TABLE页面。

阅读Peter Eisentraut的this interesting page。他用SERIAL解释了一些奇怪的问题。新标识列功能没有此类问题。所以没有理由再使用SERIAL,没有缺点,只有上升空间; SERIALGENERATED … AS IDENTITY 取代。

请注意,标识列不一定是主键,也不会自动编入索引。因此,如果您的意图(通常是这种情况),您仍然需要明确指定PRIMARY KEY

CREATE TABLE person_ (

    id_ 
        INTEGER 
        GENERATED BY DEFAULT AS IDENTITY   -- Replaces SERIAL. Implicitly creates a SEQUENCE, specified as DEFAULT.
        PRIMARY KEY                        -- Creates index. Specifies UNIQUE. Marks column for relationships.
        ,

    name_ 
        VARCHAR( 80 )

) ;

目的是让您隐藏内部实施细节。您无需知道正在生成的序列的名称。例如,您可以通过列重置计数器,而不知道基础序列。

ALTER TABLE person_ 
    ALTER COLUMN id_ 
    RESTART WITH 1000      -- Reset sequence implicitly, without a name.
;

隐式指定身份:

  • 标记专栏NOT NULL
  • 创建序列
    • 序列类型与列匹配(32位64位等)
  • 将序列绑定到列
    • 继承权限
    • Cascades下降
    • 即使重新命名列
    • ,仍会保留与列关联
  • 指定序列作为该列的默认值的来源

标识列可以采用与CREATE SEQUENCE相同的选项:

  • START WITH start
  • MINVALUE minvalue | NO MINVALUE
  • MAXVALUE maxvalue | NO MAXVALUE
  • INCREMENT [ BY ] increment
  • CYCLE | NO CYCLE
  • CACHE缓存
  • OWNED BY NONE
    (指定所有权标识列对我来说没有意义,因为所有权是自动管理的)

选项的愚蠢例子:

id_ INTEGER 
GENERATED BY DEFAULT AS IDENTITY ( 
    START WITH 200 
    MINVALUE 100 
    MAXVALUE 205 
    CYCLE 
    INCREMENT BY 3 
) PRIMARY KEY

添加4行:

  

200

     

203

     

100

     

103

答案 1 :(得分:3)

PostgreSQL将完全按照您的要求创建表格。它不会自动生成一些列(几乎,但这是低级别)。您需要在请求中添加towid serial primary key