当前位置: 首页 > 知识库问答 >
问题:

节点中的后格雷SQL多行更新.js

白云
2023-03-14

正如我已经在这里发现的那样 在堆栈溢出上,可以通过执行类似操作来更新一个查询中的多个行

update test as t set
    column_a = c.column_a,
    column_c = c.column_c
from (values
    ('123', 1, '---'),
    ('345', 2, '+++')  
) as c(column_b, column_a, column_c) 
where c.column_b = t.column_b;

特别感谢@Roman Pekar的明确回答。

现在我正在尝试将这种更新方式与查询NodeJS中的postgreSQL数据库合并。

这是我的代码片段:

var requestData = [
    {id: 1, value: 1234}
    {id: 2, value: 5678}
    {id: 3, value: 91011}
]


client.connect(function (err) {
    if (err) throw err;

client.query(buildStatement(requestData), function (err, result) {
    if (err) throw err;

    res.json(result.rows);

    client.end(function (err) {
        if (err) throw err;
    });
});
});


var buildStatement = function(requestData) {
var params = [];
var chunks = [];

for(var i = 0; i < requestData.length; i++) {

    var row = requestData[i];
    var valuesClause = [];

    params.push(row.id);
    valuesClause.push('$' + params.length);
    params.push(row.value);
    valuesClause.push('$' + params.length);

    chunks.push('(' + valuesClause.join(', ') + ')');

}

return {
    text: 'UPDATE fit_ratios as f set ratio_budget = c.ratio_budget from (VALUES ' +  chunks.join(', ') + ') as c(ratio_label, ratio_budget) WHERE c.ratio_label = f.ratio_label', values: params
        }
}

我没有得到错误,但它不会更新我的表,我真的不知道这里出了什么问题。可能是查询代码中的语法错误?在NodeJS-pg包中更新时,我没有找到任何具体的多行查询示例

共有2个答案

陶成化
2023-03-14

首先,我确实接受了@vitaly-t的回答,因为他教我使用更好更快的图书馆pg-promise,它确实解决了我的问题。(句号)

但是,为了回答我自己的问题,对于那些最终可能会遇到同样问题并希望继续使用库pg的人,这里是我犯错误的地方(这只是语法)

在我的原始代码中,我最后有这一行

return {
    text: 'UPDATE fit_ratios as f set ratio_budget = c.ratio_budget from (VALUES ' +  chunks.join(', ') + ') as c(ratio_label, ratio_budget) WHERE c.ratio_label = f.ratio_label', values: params
        }
}

我第一次看到这个很难理解,所以很容易犯一些错误。将这一行代码更改为您在下面看到的内容,可以修复我原来的问题

return {
    text: 'UPDATE fit_ratios as f set ratio_budget = c.value from (VALUES ' +  chunks.join(', ') + ') as c(id, value) WHERE c.id = f.ratio_id',
                values: params
}

我只是错过了使用列名而不是使用对象的键。(例如c.ratio_label到c.id,…)

林烨华
2023-03-14

下面的示例基于库pg-Promise,其方法helpers.update:

// library initialization, usually placed in its own module:
const pgp = require('pg-promise')({
    capSQL: true // capitalize all generated SQL
});

const db = pgp(/*your connection details*/);

// records to be updated:
const updateData = [
    {id: 1, value: 1234},
    {id: 2, value: 5678},
    {id: 3, value: 91011}
];

// declare your ColumnSet once, and then reuse it:
const cs = new pgp.helpers.ColumnSet(['?id', 'value'], {table: 'fit_ratios'});

// generating the update query where it is needed:
const update = pgp.helpers.update(updateData, cs) + ' WHERE v.id = t.id';
//=> UPDATE "fit_ratios" AS t SET "value"=v."value"
//   FROM (VALUES(1,1234),(2,5678),(3,91011))
//   AS v("id","value") WHERE v.id = t.id

// executing the query:
await db.none(update);

这种生成多行更新的方法可分为以下几点:

    < li >非常快,因为它依赖于为查询生成实现智能缓存的类型ColumnSet < li >完全安全,因为所有数据类型都经过库的查询格式化引擎,以确保所有数据都被正确格式化和转义。 < li >非常灵活,因为列定义支持高级ColumnConfig语法。 < li >非常易于使用,因为pg-promise实现了简化的界面。

请注意,我们在列 ID 前面使用 来指示该列是条件的一部分,但不会更新。有关完整的列语法,请参见类列和列配置结构。

相关问题:带pg promise的多行插入。

 类似资料:
  • 我有这个密码 但是,如果要更新节点的值,该怎么办?我试着在箱子里做value=newValue,但似乎不被允许。 我的树/节点的结构:

  • SyntaxError:无效输入“h”:预期为“I/I”(第10行,第28列(偏移量:346))“merge(p:primaryconsumer),其中p.name=svc.name” 我100%确信这些名称是唯一的,并且将与现有节点集中的唯一使用者名称相匹配(有待观察)。 当唯一节点属性匹配时,如何将现有属性添加到新数据中?(我希望获得唯一的ID,但我必须能够在匹配上执行新数据的更新)

  • 而这是我的主课,有没有其他方法做得更有效率?

  • 问题内容: 假设有一个完全填充的数据String [n] [3] myData数组。 我想做这个: 显然,我已经遗漏了很多东西,但是我想尽可能简洁地表达这个想法。 有一个简单的方法可以在单个DB命令中执行此操作吗?一个不太简单的方法怎么样? 编辑:数据不是来自另一个表(这是Web表单提交-多项选择考试)。 由于该应用是面向Web的,因此必须是防注入的。参数化查询是我首选的处理方式。 我正在使用MS

  • 问题内容: 我正在使用Vaadin 8.5.1网格来显示1000行。一旦使用属性的更改更新了行,我将使用 或 无法更新行。 我需要显式查看该行的更新属性。 我正在使用下面的代码片段来创建网格 欣赏是否有人可以分享有关如何解决此问题的指针 TIA 问题答案: 为了使一个项目被视为同一项目(以及刷新工作),您需要在该对象上正确实现和方法。 从文档中 公共无效refreshItem(T项目) 从接口:D

  • 使用< code>node-postgres我想更新我的用户模型中的列,目前我有这个 所以我可以做到这一点 但是,如果我想更新多个列和值,我目前正在做一些非常低效的事情,并调用该方法x次(即对于每个查询) 我如何通过只调用一次数据库来生成这个。 谢谢