【问题标题】:pg-promise update multiple not setting columns correctlypg-promise 更新多个未正确设置列
【发布时间】:2021-09-27 18:31:47
【问题描述】:

我有一个项目需要一次更新多行。我发现如何做到这一点的例子是文档:documentation

我已经使用了一个列集,因为在文档中建议这样做。我设置了?feature_id,所以它只在WHERE子句中使用。

我的代码生成的错误如下:error: column "created_on" is of type timestamp with time zone but expression is of type text。我注意到正在生成的查询,这似乎与示例一致。

此代码有一个插入语句,用于表示新功能并且似乎可以正常工作。该错误仅在更新查询中引发。

    const insertValues = [];
    const updateValues = [];
    for (let i = 0; i < features.length; i += 1) {
      const feature = features[i];

      if (!excistingFeaturesIds.includes(feature.id)) {
        insertValues.push({
          plot_id: plotId,
          type: feature.type,
          area: feature.area,
          created_on: currendDate,
          updated_on: currendDate,
          geo_feature: feature.geoFeature,
        });
      } else {
        updateValues.push({
          feature_id: feature.id,
          plot_id: plotId,
          type: feature.type,
          area: feature.area,
          created_on: currendDate,
          updated_on: currendDate,
          geo_feature: feature.geoFeature,
        });
      }
    }

    const insertColumnSet = new pgp.helpers.ColumnSet(['plot_id', 'type', 'area', 'created_on', 'updated_on', 'geo_feature'], { table: 'features' });
    const updateColumnSet = new pgp.helpers.ColumnSet(['?feature_id', 'plot_id', 'type', 'area', 'created_on', 'updated_on', 'geo_feature'], { table: 'features' });

    if (insertValues && insertValues.length > 0) {
      const insertQuery = pgp.helpers.insert(
        insertValues, insertColumnSet,
      );

      await promiseDB.none(insertQuery);
    }

    if (updateValues && updateValues.length > 0) {
      const updateQuery = `${pgp.helpers.update(
        updateValues, updateColumnSet,
      )} WHERE v.feature_id = t.feature_id`;
      console.log(updateQuery);

      await promiseDB.none(updateQuery);
    }

    return res.status(201).json({
      message: 'Features added!',
    });
  } catch (err) {
    console.log(err);
    return res.status(400).send(err);
  }
UPDATE
    "features" AS t
SET
    "plot_id" = v. "plot_id",
    "type" = v. "type",
    "area" = v. "area",
    "created_on" = v. "created_on",
    "updated_on" = v. "updated_on",
    "geo_feature" = v. "geo_feature"
FROM (
    values(1, 3, 'roof', 342.01520314642977, '2021-07-20T09:56:10.007+02:00', '2021-07-20T09:56:10.007+02:00', '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[coords...]]]},"properties":{"UIDN":6338864,"OIDN":5290477,"VERSIE":1,"BEGINDATUM":"2015-09-23","VERSDATUM":"2015-09-23","TYPE":1,"LBLTYPE":"hoofdgebouw","OPNDATUM":"2015-08-25","BGNINV":5,"LBLBGNINV":"kadastralisatie","type":"roof","tools":"polygon","description":"D1","id":5290477,"area":342.01520314642977,"roofType":"saddle","roofGreen":"normal","database":true},"id":1}'),
        (2,
            3,
            'roof',
            181.00725895629216,
            '2021-07-20T09:56:10.007+02:00',
            '2021-07-20T09:56:10.007+02:00',
            '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":6338518,"OIDN":5290131,"VERSIE":1,"BEGINDATUM":"2015-09-23","VERSDATUM":"2015-09-23","TYPE":1,"LBLTYPE":"hoofdgebouw","OPNDATUM":"2015-08-25","BGNINV":5,"LBLBGNINV":"kadastralisatie","type":"roof","tools":"polygon","description":"D2","id":5290131,"area":181.00725895629216,"roofType":"flat","roofGreen":"normal","database":true},"id":2}'),
        (3,
            3,
            'roof',
            24.450163203958745,
            '2021-07-20T09:56:10.007+02:00',
            '2021-07-20T09:56:10.007+02:00',
            '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":5473377,"OIDN":4708120,"VERSIE":1,"BEGINDATUM":"2014-07-04","VERSDATUM":"2014-07-04","TYPE":2,"LBLTYPE":"bijgebouw","OPNDATUM":"2014-05-27","BGNINV":4,"LBLBGNINV":"bijhouding binnengebieden","type":"roof","tools":"polygon","description":"D3","id":4708120,"area":24.450163203958745,"roofType":"saddle","roofGreen":"normal","database":true},"id":3}'),
        (4,
            3,
            'water',
            57.65676046589426,
            '2021-07-20T09:56:10.007+02:00',
            '2021-07-20T09:56:10.007+02:00',
            '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":473256,"OIDN":199890,"VERSIE":2,"BEGINDATUM":"2017-03-08","VERSDATUM":"2021-05-06","VHAG":-9,"NAAM":"nvt","OPNDATUM":"2017-01-30","BGNINV":4,"LBLBGNINV":"bijhouding binnengebieden","type":"water","tools":"polygon","description":"W1","id":199890,"area":57.65676046589426,"waterType":"natural","database":true},"id":4}')) 
AS v ("feature_id",
        "plot_id",
        "type",
        "area",
        "created_on",
        "updated_on",
        "geo_feature")
WHERE
    v.feature_id = t.feature_id
INSERT INTO "features" ("plot_id", "type", "area", "created_on", "updated_on", "geo_feature")
        values(3, 'roof', 342.01520314642977, '2021-07-20T10:17:04.565+02:00', '2021-07-20T10:17:04.565+02:00', '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":6338864,"OIDN":5290477,"VERSIE":1,"BEGINDATUM":"2015-09-23","VERSDATUM":"2015-09-23","TYPE":1,"LBLTYPE":"hoofdgebouw","OPNDATUM":"2015-08-25","BGNINV":5,"LBLBGNINV":"kadastralisatie","type":"roof","tools":"polygon","description":"D1","id":5290477,"area":342.01520314642977,"roofType":"saddle","roofGreen":"normal","database":true},"id":1}'), (3, 'roof', 181.00725895629216, '2021-07-20T10:17:04.565+02:00', '2021-07-20T10:17:04.565+02:00', '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":6338518,"OIDN":5290131,"VERSIE":1,"BEGINDATUM":"2015-09-23","VERSDATUM":"2015-09-23","TYPE":1,"LBLTYPE":"hoofdgebouw","OPNDATUM":"2015-08-25","BGNINV":5,"LBLBGNINV":"kadastralisatie","type":"roof","tools":"polygon","description":"D2","id":5290131,"area":181.00725895629216,"roofType":"flat","roofGreen":"normal","database":true},"id":2}'), (3, 'roof', 24.450163203958745, '2021-07-20T10:17:04.565+02:00', '2021-07-20T10:17:04.565+02:00', '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":5473377,"OIDN":4708120,"VERSIE":1,"BEGINDATUM":"2014-07-04","VERSDATUM":"2014-07-04","TYPE":2,"LBLTYPE":"bijgebouw","OPNDATUM":"2014-05-27","BGNINV":4,"LBLBGNINV":"bijhouding binnengebieden","type":"roof","tools":"polygon","description":"D3","id":4708120,"area":24.450163203958745,"roofType":"saddle","roofGreen":"normal","database":true},"id":3}'), (3, 'water', 57.65676046589426, '2021-07-20T10:17:04.565+02:00', '2021-07-20T10:17:04.565+02:00', '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":473256,"OIDN":199890,"VERSIE":2,"BEGINDATUM":"2017-03-08","VERSDATUM":"2021-05-06","VHAG":-9,"NAAM":"nvt","OPNDATUM":"2017-01-30","BGNINV":4,"LBLBGNINV":"bijhouding binnengebieden","type":"water","tools":"polygon","description":"W1","id":199890,"area":57.65676046589426,"waterType":"natural","database":true},"id":4}')

【问题讨论】:

    标签: postgresql pg-promise


    【解决方案1】:

    您的列 created_onupdated_on 需要 SQL 类型转换,因此会出现错误。

    而且没有必要重新创建相同的表列表 -> 列。

    总而言之,您的列集可以这样创建:

    const insertColumnSet = new pgp.helpers.ColumnSet([
        'plot_id',
        'type',
        'area',
        {name: 'created_on', cast: 'timestamptz'},
        {name: 'updated_on', cast: 'timestamptz'},
        'geo_feature'
    ], { table: 'features' });
    
    const updateColumnSet = insertColumnSet.extend(['?feature_id']};
    

    查看Column 的完整语法,以及extend 方法。

    更新

    请注意,严格来说,只有UPDATE 需要类型转换,而您的INSERT 可以自动推断类型,您可以像这样在列集中反映:

    const insertColumnSet = new pgp.helpers.ColumnSet(['plot_id', 'type', 'area',
                 'created_on', 'updated_on', 'geo_feature'], { table: 'features' });
    
    const updateColumnSet = insertColumnSet.merge([
        {name: 'feature_id', cnd: true}, // or just '?feature_id'
        {name: 'created_on', cast: 'timestamptz'},
        {name: 'updated_on', cast: 'timestamptz'}    
    ]};
    

    不过,这两种方法在您的情况下都可以正常工作;)

    参见merge 方法。

    【讨论】:

    • 感谢您的回答!我已经尝试过你的解决方案。但现在我收到一条错误消息:error: cannot cast type integer to timestamp with time zone。我不明白为什么要使用 timestamptz 对 ID 进行类型转换。
    • 我还在努力回答你太快了 :) 再试一次以上;)
    • 我能问一下为什么我应该在更新时投射而不是在插入时投射吗?
    • 因为 INSERT 值类型是自动推断的,但不是为了更新,不知何故。这就是 PostgreSQL 的工作原理。另外,我进行了最后一次更新 - 在我最初忘记的 feature_id 前面添加了 ? ;)
    • @Stephen 我已经为UPDATE 添加了一个更新部分;)
    猜你喜欢
    • 2017-04-03
    • 2018-04-15
    • 2017-11-29
    • 2017-10-10
    • 2019-01-04
    • 2016-09-14
    • 1970-01-01
    • 2017-05-28
    • 2017-06-03
    相关资源
    最近更新 更多