带有 CTE 的 pg-promise 动态列
pg-promise Dynamic Columns with CTE
我正在尝试使用 pg-promise 在快速服务器上使用 AJAX 请求更新我的数据库。
到目前为止一切正常,但现在我想使用 CTE (WITH) 更新两个表,这也可以正常工作。我现在想做的是能够拥有动态列,具体取决于 PUT 请求。
澄清一下:
请求
{
"dob": "01.01.1970",
"email": "example@example.com",
"street": "street 1",
}
请求
{
"dob": "01.01.1970",
"email": "example@example.com",
"phone": "0000",
"tag": "blue",
}
我尝试了以下方法并且有效,但我的问题是:
- 我使用 pg-promise 正确吗?
- 这种方法仍然SQL 注入安全吗 (:raw)?
- 有没有更好的方法达到同样的效果?
QueryFile.sql
WITH update_table_one AS (
UPDATE table_one SET username=${username}
WHERE identification_number=${identification_number}
RETURNING identification_number
)
UPDATE table_two SET ${fromSet:raw}
WHERE identification_number=(SELECT identification_number FROM update_table_one);
Server.js
let qf = // ...QueryFile
let helpers = pgp.helpers;
let user = req.params.user;
let body = req.body;
let dbBody = {
username: user,
identification_number: 'ABC123',
fromSet: helpers.sets(body)
};
db.oneOrNone(qf, dbBody)
.then(data => {
res.json({ success: true, message: 'Yes!' });
})
.catch(error => {
res.json({ success: false, message: 'No!' });
});
对初始问题的补充(与我在评论中的问题有关):
{
"dob": "01.01.1970",
"email": "example@example.com",
"street": "street 1",
"phone": "0000",
"tag": "blue",
"group": "students",
"password": "hash",
"track": "one",
}
Am I using pg-promise correctly?
差不多。您的查询没有 return 任何内容,因此请改用 oneOrNone is logically incorrect, it should be none 方法。
Is this approach still SQL injection safe (:raw)?
是的,因为即使您正在注入原始数据集,列也会根据它们的 JavaScript 类型在 helpers 中自动预转义,因此任何注入尝试都会在那里被挫败。
Is there a better way to achieve the same results?
只有事先知道所有的列,才能将它们预先声明为 ColumnSet,以获得更好的性能 and/or 类型转换。但除此之外,没有。
另外请记住,如果您调用 helpers.sets(body)
不传递任何列,它将 return 一个空字符串,如 per the API,这反过来会导致无效UPDATE
.
我正在尝试使用 pg-promise 在快速服务器上使用 AJAX 请求更新我的数据库。
到目前为止一切正常,但现在我想使用 CTE (WITH) 更新两个表,这也可以正常工作。我现在想做的是能够拥有动态列,具体取决于 PUT 请求。
澄清一下:
请求
{ "dob": "01.01.1970", "email": "example@example.com", "street": "street 1", }
请求
{ "dob": "01.01.1970", "email": "example@example.com", "phone": "0000", "tag": "blue", }
我尝试了以下方法并且有效,但我的问题是:
- 我使用 pg-promise 正确吗?
- 这种方法仍然SQL 注入安全吗 (:raw)?
- 有没有更好的方法达到同样的效果?
QueryFile.sql
WITH update_table_one AS (
UPDATE table_one SET username=${username}
WHERE identification_number=${identification_number}
RETURNING identification_number
)
UPDATE table_two SET ${fromSet:raw}
WHERE identification_number=(SELECT identification_number FROM update_table_one);
Server.js
let qf = // ...QueryFile
let helpers = pgp.helpers;
let user = req.params.user;
let body = req.body;
let dbBody = {
username: user,
identification_number: 'ABC123',
fromSet: helpers.sets(body)
};
db.oneOrNone(qf, dbBody)
.then(data => {
res.json({ success: true, message: 'Yes!' });
})
.catch(error => {
res.json({ success: false, message: 'No!' });
});
对初始问题的补充(与我在评论中的问题有关):
{
"dob": "01.01.1970",
"email": "example@example.com",
"street": "street 1",
"phone": "0000",
"tag": "blue",
"group": "students",
"password": "hash",
"track": "one",
}
Am I using pg-promise correctly?
差不多。您的查询没有 return 任何内容,因此请改用 oneOrNone is logically incorrect, it should be none 方法。
Is this approach still SQL injection safe (:raw)?
是的,因为即使您正在注入原始数据集,列也会根据它们的 JavaScript 类型在 helpers 中自动预转义,因此任何注入尝试都会在那里被挫败。
Is there a better way to achieve the same results?
只有事先知道所有的列,才能将它们预先声明为 ColumnSet,以获得更好的性能 and/or 类型转换。但除此之外,没有。
另外请记住,如果您调用 helpers.sets(body)
不传递任何列,它将 return 一个空字符串,如 per the API,这反过来会导致无效UPDATE
.