'skip' 选项在多行更新中的使用
Usage of 'skip' option in multi-row update
我是 NodeJs 的新手,并尝试使用 pg-promise 来完成对我的 PG 数据库的所有请求。
我希望能够动态更新列,这意味着有时我只会更新一行的两列,有时我会更新所有列,等等......
我的输入将是 JSON.
因为我希望端点能够更新多行,所以我尝试将 helpers 命名空间与 ColumnSet.
一起使用
这是我的 Javascript 代码(灵感来自之前的 Whosebug 答案):
/* logic for skipping columns: */
const skip = c => !c.exists || c.value === undefined;
/* all the columns of the table */
const column_structure = new dbconfig.pgp.helpers.ColumnSet(
[ '?id',
{name: 'firstname', skip},
{name: 'surname', skip},
{name: 'yob', skip}, // year of birth
{name: 'defensive_skill', skip},
{name: 'offensive_skill', skip},
{name: 'login', skip},
{name: 'password', skip}
],
{table: 'players'});
这里是 JSON 我正在向端点馈送 :
[{
"id" : 25,
"firstname": "Stephen",
"surname": "Harrison",
"yob": 1991,
"defensive_skill": 5,
"offensive_skill": 3,
"login": "harry",
"password": "123456"
},
{
"id": 26,
"firstname": "Chris",
"surname": "Jackson",
"defensive_skill": 5,
"offensive_skill": 4,
"login": "chris",
"password": "123456"
}
]
这里是错误:
Property 'yob' doesn't exist.
如您所见,在我的数组的第二个对象中,我没有指定字段 'yob'。
我期望对于第二个对象,除了 'yob' 之外的所有列都将被更新。
我做错了什么吗?
它不起作用的原因是因为 skip
逻辑仅适用于 single-row 更新,如 documented in the API:
Used by methods update
(for a single object)...
Multi-row 更新语法不允许任何跳过逻辑,因此您需要在缺少 属性 时提供默认值,如下所示:
{name: 'yob', skip, def: defaultValue}
defaultValue
可以是上面的任何内容,包括 undefined
.
或者,您可以使用 属性 init
和 return 动态值。
所以在上面的代码中,如果将列声明更改为:
{name: 'yob', skip, def: null}
您的 update
调用将生成:
UPDATE "players" AS t SET "firstname"=v."firstname","surname"=v."surname","yob"=v."yob","defensive_skill"=v."defensive_skill","offensive_skill"=v."offensive_skill","login"=v."login","password"=v."password" FROM (VALUES(25,'Stephen','Harrison',1991,5,3,'harry','123456'),(26,'Chr
is','Jackson',null,5,4,'chris','123456')) AS v("id","firstname","surname","yob","defensive_skill","offensive_skill","login","password")
正如您从生成的 SQL 中看到的那样,使用这种语法不可能跳过一列,这就是 multi-row 更新忽略 skip
的原因。如果您一次传入一个对象,您可以看到它仍然有效,但这与您正在寻找的使用场景不同。
我是 NodeJs 的新手,并尝试使用 pg-promise 来完成对我的 PG 数据库的所有请求。 我希望能够动态更新列,这意味着有时我只会更新一行的两列,有时我会更新所有列,等等...... 我的输入将是 JSON.
因为我希望端点能够更新多行,所以我尝试将 helpers 命名空间与 ColumnSet.
一起使用这是我的 Javascript 代码(灵感来自之前的 Whosebug 答案):
/* logic for skipping columns: */
const skip = c => !c.exists || c.value === undefined;
/* all the columns of the table */
const column_structure = new dbconfig.pgp.helpers.ColumnSet(
[ '?id',
{name: 'firstname', skip},
{name: 'surname', skip},
{name: 'yob', skip}, // year of birth
{name: 'defensive_skill', skip},
{name: 'offensive_skill', skip},
{name: 'login', skip},
{name: 'password', skip}
],
{table: 'players'});
这里是 JSON 我正在向端点馈送 :
[{
"id" : 25,
"firstname": "Stephen",
"surname": "Harrison",
"yob": 1991,
"defensive_skill": 5,
"offensive_skill": 3,
"login": "harry",
"password": "123456"
},
{
"id": 26,
"firstname": "Chris",
"surname": "Jackson",
"defensive_skill": 5,
"offensive_skill": 4,
"login": "chris",
"password": "123456"
}
]
这里是错误:
Property 'yob' doesn't exist.
如您所见,在我的数组的第二个对象中,我没有指定字段 'yob'。 我期望对于第二个对象,除了 'yob' 之外的所有列都将被更新。 我做错了什么吗?
它不起作用的原因是因为 skip
逻辑仅适用于 single-row 更新,如 documented in the API:
Used by methods
update
(for a single object)...
Multi-row 更新语法不允许任何跳过逻辑,因此您需要在缺少 属性 时提供默认值,如下所示:
{name: 'yob', skip, def: defaultValue}
defaultValue
可以是上面的任何内容,包括 undefined
.
或者,您可以使用 属性 init
和 return 动态值。
所以在上面的代码中,如果将列声明更改为:
{name: 'yob', skip, def: null}
您的 update
调用将生成:
UPDATE "players" AS t SET "firstname"=v."firstname","surname"=v."surname","yob"=v."yob","defensive_skill"=v."defensive_skill","offensive_skill"=v."offensive_skill","login"=v."login","password"=v."password" FROM (VALUES(25,'Stephen','Harrison',1991,5,3,'harry','123456'),(26,'Chr
is','Jackson',null,5,4,'chris','123456')) AS v("id","firstname","surname","yob","defensive_skill","offensive_skill","login","password")
正如您从生成的 SQL 中看到的那样,使用这种语法不可能跳过一列,这就是 multi-row 更新忽略 skip
的原因。如果您一次传入一个对象,您可以看到它仍然有效,但这与您正在寻找的使用场景不同。