Knex Raw Select带变量的Postgresql
我可以在knex查询中使用变量吗?db.raw(Knex Raw Select带变量的Postgresql,postgresql,knex.js,Postgresql,Knex.js,我可以在knex查询中使用变量吗?db.raw(选择usr_vote.vote,其中usr_vote.user.id=${loggedInUserId})有什么问题?其他一切都很好 在不起作用的db.raw中,我尝试使用一个变量(loggedInUserId)来获取登录用户对问题的投票历史记录(他们可以向上投票/向下投票,因此值为-1或1或null)。提前感谢您的帮助 有4个表看起来像: 询问用户 身份证 用户名 提问问题 身份证 头衔 身体 标签 创建日期 用户id(FK引用askify
选择usr_vote.vote,其中usr_vote.user.id=${loggedInUserId}
)有什么问题?其他一切都很好
在不起作用的db.raw中,我尝试使用一个变量(loggedInUserId)来获取登录用户对问题的投票历史记录(他们可以向上投票/向下投票,因此值为-1或1或null)。提前感谢您的帮助
有4个表看起来像:
询问用户
- 身份证
- 用户名
- 身份证
- 头衔
- 身体
- 标签
- 创建日期
- 用户id(FK引用askify_users.id)
- 身份证
- 答复
- 问题id(FK引用askify_question.id)
- 用户id(FK引用askify_users.id)
- 列表项
- 问题id(FK引用askify_questions.id)
- 用户id(FK引用askify_users.id)
- 投票(-1或1)
- 主键(问题id、用户id)
getAllQuestions(db,loggedInUserId){
返回数据库
.from('askify_问题为q')
.选择(
“问题编号作为问题编号”,
“问题标题作为问题标题”,
“问题体作为问题体”,
“q.date_创建为date_创建”,
“q.tags”,
原始数据库(
`将(不同的ans)计数为回答的数量`
),
原始数据库(
`SUM(不同的usr_表决权。表决权)作为_表决权的总和`
),
原始数据库(
`选择usr_vote.vote,其中usr_vote.user_id=${loggedInUserId}`
),
原始数据库(
`json_strip_nulls(
json_构建_对象(
“用户id”,usr.id,
“用户名”,usr.user\u名称,
“全名”,usr.全名,
“创建日期”,usr.date\u创建
)
)作为“用户”`
)
)
.leftJoin(
“askify_回答为ans”,
“q.id”,
“回答问题”
)
.leftJoin(
“askify_用户作为usr”,
“q.user_id”,
“usr.id”
)
.leftJoin(
“askify_question_vote AS usr_vote”,
“q.id”,
“usr_投票。问题编号”
)
.groupBy('q.id','usr.id')
},
我注意到,关于绑定值,这里是正确的,但只是想详细说明一下:这里的关键是字符串替换发生的时间。如果您这样做:
db.raw(`SELECT vote WHERE user_id = ${loggedInUserId}`)
一旦JS解释器到达这一行,就会在JavaScript中进行替换。数据库引擎与loggedInUserId
中的任何内容都没有关系,Knex也没有关系:实际上,您绕过了所有内置保护
稍微好一点的是:
db.raw("SELECT vote WHERE user_id = ?", loggedInUserId)
这允许Knex转义loggedInUserId
中的字符串。如果愿意,可以使用命名绑定:
db.raw("SELECT vote WHERE user_id = :loggedInUserId", { loggedInUserId })
然而,通过使用Knex已经为子查询提供的功能,可以轻松避免绑定的所有这些麻烦:只需将子查询放入函数中即可
db
.from("askify_questions AS q")
.select(
"q.id AS question_id",
qb => qb.select("usr_vote.vote").where({ user_id: loggedInUserId })
)
.leftJoin(
"askify_question_vote AS usr_vote",
"q.id",
"usr_vote.question_id"
);
qb
参数代表“查询生成器”,由Knex传递给函数。它的行为非常类似于db
对象
这将生成类似于以下内容的SQL:
SELECT
"q"."id" AS "question_id",
(
SELECT "usr_vote"."user_id" WHERE "user_id" = ?
)
FROM "askify_questions AS q"
LEFT JOIN "askify_question_vote" AS "usr_vote"
ON "q"."id" = "usr_vote"."question_id"
你用什么语言<代码>${loggedInUserId}似乎不合适,因为javascript变量不是美元前缀javascript模板文字,请注意,当您使用
.raw
和客户端提供的值时,您将应用程序暴露于SQL注入.raw
接受具有绑定值的数组的第二个参数。db.raw('select usr\u vote.vote where usr\u vote.user\u id=?',[loggedInUserId])