可以使用 QueryFile 添加动态 WHERE 子句吗?
Possible to add dynamic WHERE clause with a QueryFile?
我有一个复杂的查询存储在 SQL 文件中,我想将它重复用于各种路由,但根据路由更改 WHERE 子句。这将代替在多个文件中进行大型复杂查询,唯一的区别是 WHERE 语句。
使用QueryFile时是否可以动态添加WHERE?下面的简化示例:
SELECT "id", "userId", "locationId", "title", "body",
(
SELECT row_to_json(sqUser)
FROM (
SELECT "id", "firstname", "lastname"
FROM "users"
WHERE "users"."id" = "todos"."userId"
) sqUser
) as "user"
FROM "todos"
const queryIndex = new pgp.QueryFile('sql/todos/index.pgsql', queryOptions);
// 1. Use as is to get a list of all todos
// 2. OR Append WHERE "locationId" = to get list filtered by location
// 3. OR Append WHERE "id" = to get a specific item
// without having three separate SQL files?
看起来(也许?)您可以在查询文件中添加以下内容,但仍然感觉有局限性(=
和 LIKE
仍然需要两个文件,而且它仍然仅限于一个 WHERE 条件)。做一些像 WHERE 1 = 1 这样的事情来让所有记录到 return.
也感觉很奇怪
WHERE =
我很想听听人们对此的想法,或者是否有更好的方法。
您可以将动态条件注入到查询文件中,如 Raw Text:
SELECT "id", "userId", "locationId", "title", "body",
(
SELECT row_to_json(sqUser)
FROM (
SELECT "id", "firstname", "lastname"
FROM "users"
${condition:raw}
) sqUser
) as "user"
FROM "todos"
预格式化参数,基于条件:
// Generate a condition, based on the business logic:
const condition = pgp.as.format('WHERE col_1 = AND col_2 = ', [111, 222]);
正在执行您的查询文件:
await db.any(myQueryFile, {condition});
高级
以上是当您有一个您想要在代码中生成的简单动态条件时的场景。但有时您可能有想要交替的复杂静态条件。在这种情况下,您可以让主查询文件引用从查询文件中的条件(开箱即用地支持嵌套查询文件)。在这种情况下,您甚至不需要使用 :raw
过滤器,因为默认情况下查询文件作为原始文本注入:
主查询:
SELECT * FROM table ${condition}
加载具有复杂条件的从属查询文件(当应用程序启动时):
const conditionQueryFile1 = new QueryFile(...);
const conditionQueryFile2 = new QueryFile(...);
根据业务逻辑选择正确的从属查询:
const condition = conditionQueryFile1; // some business logic here;
正在以从属作为参数执行主查询:
await db.any(myQueryFile, {condition});
我有一个复杂的查询存储在 SQL 文件中,我想将它重复用于各种路由,但根据路由更改 WHERE 子句。这将代替在多个文件中进行大型复杂查询,唯一的区别是 WHERE 语句。
使用QueryFile时是否可以动态添加WHERE?下面的简化示例:
SELECT "id", "userId", "locationId", "title", "body",
(
SELECT row_to_json(sqUser)
FROM (
SELECT "id", "firstname", "lastname"
FROM "users"
WHERE "users"."id" = "todos"."userId"
) sqUser
) as "user"
FROM "todos"
const queryIndex = new pgp.QueryFile('sql/todos/index.pgsql', queryOptions);
// 1. Use as is to get a list of all todos
// 2. OR Append WHERE "locationId" = to get list filtered by location
// 3. OR Append WHERE "id" = to get a specific item
// without having three separate SQL files?
看起来(也许?)您可以在查询文件中添加以下内容,但仍然感觉有局限性(=
和 LIKE
仍然需要两个文件,而且它仍然仅限于一个 WHERE 条件)。做一些像 WHERE 1 = 1 这样的事情来让所有记录到 return.
WHERE =
我很想听听人们对此的想法,或者是否有更好的方法。
您可以将动态条件注入到查询文件中,如 Raw Text:
SELECT "id", "userId", "locationId", "title", "body",
(
SELECT row_to_json(sqUser)
FROM (
SELECT "id", "firstname", "lastname"
FROM "users"
${condition:raw}
) sqUser
) as "user"
FROM "todos"
预格式化参数,基于条件:
// Generate a condition, based on the business logic:
const condition = pgp.as.format('WHERE col_1 = AND col_2 = ', [111, 222]);
正在执行您的查询文件:
await db.any(myQueryFile, {condition});
高级
以上是当您有一个您想要在代码中生成的简单动态条件时的场景。但有时您可能有想要交替的复杂静态条件。在这种情况下,您可以让主查询文件引用从查询文件中的条件(开箱即用地支持嵌套查询文件)。在这种情况下,您甚至不需要使用 :raw
过滤器,因为默认情况下查询文件作为原始文本注入:
主查询:
SELECT * FROM table ${condition}
加载具有复杂条件的从属查询文件(当应用程序启动时):
const conditionQueryFile1 = new QueryFile(...);
const conditionQueryFile2 = new QueryFile(...);
根据业务逻辑选择正确的从属查询:
const condition = conditionQueryFile1; // some business logic here;
正在以从属作为参数执行主查询:
await db.any(myQueryFile, {condition});