【问题标题】:node-postgres: parameterised insert query cached, failing on 2nd runnode-postgres:参数化插入查询缓存,第二次运行失败
【发布时间】:2015-07-18 20:39:24
【问题描述】:

我正在尝试使用node-postgres 运行两个参数化插入查询:第一个指定主键列,第二个不指定。

第二个查询,即使没有指定主键列,也不能说有一个重复的主键。

我的 pg 表:

CREATE TABLE teams (
  id serial PRIMARY KEY,
  created_by int REFERENCES users,
  name text,
  logo text
);

重现此问题的代码:

var pg = require('pg');

var insertWithId = 'INSERT INTO teams(id, name, created_by) VALUES($1, $2, $3) RETURNING id';
var insertWithoutId = 'INSERT INTO teams(name, created_by) VALUES($1, $2) RETURNING id';

pg.connect(process.env.POSTGRES_URI, function (err, client, releaseClient) {
  client.query(insertWithId, [1, 'First Team', 1], function (err, result) {
    releaseClient();

    if (err) {
      throw err;
    }

    console.log('first team created');
  });
});

pg.connect(process.env.POSTGRES_URI, function (err, client, releaseClient) {
  client.query(insertWithoutId, ['Second Team', 1], function (err, result) {
    releaseClient();

    if (err) {
      console.log(err);
    }
  });
});

以及运行这个的输出:

first team created

{ [error: duplicate key value violates unique constraint "teams_pkey"]
  name: 'error',
  length: 173,
  severity: 'ERROR',
  code: '23505',
  detail: 'Key (id)=(1) already exists.',
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: 'public',
  table: 'teams',
  column: undefined,
  dataType: undefined,
  constraint: 'teams_pkey',
  file: 'nbtinsert.c',
  line: '406',
  routine: '_bt_check_unique' }

我从阅读node-postgres 源代码中收集到的信息,参数化查询被视为准备好的查询,如果它们重用name 参数,它们会被缓存;虽然通过挖掘它的来源,它似乎并不认为我的查询具有 name 属性。

有人对如何避免这种情况有任何想法吗?

【问题讨论】:

  • 第一个插入为id 提供了一个值,因此序列号不会增加。序列号仍然是1。第二个插入没有为id 提供值,因此使用了序列号 (=1)。这是重复的。最好的解决方案是只使用第二条语句,如果需要,让应用程序使用返回的id
  • 好吧,我没想到,经过一番谷歌搜索,看起来确实是问题所在。将您的评论变成答案,我会接受:)

标签: node.js postgresql node-postgres


【解决方案1】:

第一个插入为id 提供一个值,因此序列号不会递增。第一次插入后,序列号仍为 1。第二个插入id 提供值,因此使用序列号(=1)。这是重复的。最好的解决方案是使用第二条语句,如果需要,让应用程序使用返回的 id。

简而言之:不要干扰连续剧。


如果您需要更正序列的下一个值,您可以使用类似于以下语句的内容。

SELECT setval('teams_id_seq', (SELECT MAX(id) FROM teams) )
        ;

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 2017-05-20
    • 2011-09-02
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多