【问题标题】:Is there a way to prevent a query from setting the serial primary key?有没有办法阻止查询设置串行主键?
【发布时间】:2020-06-02 18:33:19
【问题描述】:

我有一堆在主键上带有“serial”关键字的表,这样自动增量就可以工作了。问题是我可以使用任何覆盖自动增量的 ID 号进行查询以插入一行。是否有一个原因?或者,有没有办法阻止用户添加/更改此值?

这是我的表配置示例:

create table if not exists departments (
    department_id serial primary key,
    name varchar(64) not null unique
);

如果我运行以下查询,我可以将任意数字添加到主键:

insert into departments (department_id, name) values (9001, 'FooBar')

我想我想防止这种情况发生。我想听听一些意见。

【问题讨论】:

  • 'serial' 是表格行的名称还是单元格中的值?,如果它被定义为主键并且你尝试插入一个现有的数字,它会抛出一个错误。
  • 'serial' 是 postgresql 中允许自动递增的关键字。我会用更多信息更新我的问题。
  • 你运行的是什么版本的 postgresql?
  • @BarryPiccinni 我认为是 11。它是 aws RDS,似乎无法使用他们的门户找到完整的版本号。
  • 有几种方法可以做到这一点。我使用的一种方法是创建一个触发器,该触发器使用序列中的下一个值更新列,无论您插入什么。你可以在这里阅读:dba.stackexchange.com/questions/116054/…

标签: sql postgresql


【解决方案1】:

使用标识列:

create table if not exists departments (
    department_id integer primary key generated always as identity,
    name varchar(64) not null unique
);

这将防止插入覆盖生成的值。您仍然可以通过在 INSERT 语句中指定 OVERRIDING SYSTEM VALUE 来规避这种情况。但除非您指定该选项,否则为列提供值将导致错误。

相关:PostgreSQL: serial vs identity

【讨论】:

    【解决方案2】:

    除非 '9001' 不在寄存器中,否则不会造成任何问题。 如果归档的 'department_id' 已经是自动递增的,你可以像

    一样运行你的插入语句
    INSERT INTO departments (name) VALUES ('FooBar')
    

    【讨论】:

    • 根据您的问题,如果用户可以更改它,除非用户可以直接访问寄存器或插入语句,否则该字段将继续增加而不会出现问题。
    • 有没有办法配置表格让用户不能添加自己的id?
    【解决方案3】:

    我使用的是 Microsoft sql server,您可以通过下面的 sql 命令控制在标识列中插入值

    SET IDENTITY_INSERT [ [ 数据库名称 . ] 架构名称。 ] 表名 { 开 |关闭}

    通过将其设置为“关闭”,您无法在标识列中插入值。

    更多信息请参考:https://docs.microsoft.com/en-us/sql/t-sql/statements/set-identity-insert-transact-sql?view=sql-server-ver15

    【讨论】:

    猜你喜欢
    • 2019-10-20
    • 1970-01-01
    • 2022-11-21
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    相关资源
    最近更新 更多