简体   繁体   中英

Run PostgreSQL UPDATE query for every object in array

Let's say I have a cart of grocery items and each item has a unique ID. When someone clicks "purchase", an array is sent with an object for each item in that cart. The cart varies so sometimes it might be 2 items and sometimes 6 items, etc.

Example:

[{id: 1, amt_purchased: 3}, {id: 2, amt_purchased: 4}]

I need my SQL table, "grocery items available", to update according to what was purchased.

For one grocery item, I would use the following:

UPDATE available 
SET amt_avail = amt_avail - 3
WHERE produce_id = 1

Since I have multiple items now, how can I get the query to run for each item that was purchased? Or as one massive query that will adapt according to how many items were purchased?

My project is Ionic/AngularJs and NodeJs, Express, MassiveJs.

Thanks guys! Still a noob so I'm having a hard time explaining what I need.

update available 
    set amt_avail = case 
         when produce_id = 1 then amt_avail - 3
         when produce_id = 2 then amt_avail - 4 
end;

You could use simple for loop to build such query

    var items = [{id: 1, amt_purchased: 3}, {id: 2, amt_purchased: 4}];

    function buildQuery(items) {
        var query = "update available set amt_avail = case ";
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            query += `when produce_id = ${item['id']} then amt_avail - ${item['amt_purchased']}`
        }
        return query += " end;";
}

PostgreSQL has an excellent feature UPDATE ... FROM ...; which gives a convenient way to update one table on another table. And second excellent feature - you can use a pseudo-table VALUES in this query:

UPDATE available a
SET amt_available = a.amt_available + v.amt_available
FROM (
  VALUES (1, 25), (3, 15), (7, -55)   -- just pass required values
) AS v (produce_id, amt_available)
WHERE a.produce_id=v.produce_id;

Here's a SQLFiddle to check an idea - http://sqlfiddle.com/#!17/04f24/22

If you are using Massive.js 3.0, that means you have access to its underlying driver pg-promise .

Unfortunately, I am not using Massive.js personally, so I don't know enough about doing updates directly through it. I can only advise you as the author of pg-promise , that you can access its driver to do the update you want as shown below.

const db; // your Massive.js database object;

const helpers = db.pgp.helpers; // pg-promise helpers namespace

// reusable ColumnSet:
const cs = new helpers.ColumnSet(['?id', 'amt_purchased'], {table: 'available '});

// your input data:
const data = [{id: 1, amt_purchased: 3}, {id: 2, amt_purchased: 4}];

// query to be executed:
const query = helpers.update(data, cs) + ' WHERE v.id = t.id';

db.instance.none(query)
    .then(() => {
        // success, updated all at once
    })
    .catch(error => {
        // error
    });

See also: pg-promise multi-row update .

Links:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM