英文:
How to deal with commas when conditionally forming queries
问题
我对使用ExpressJS创建API相对新手,并且在根据请求创建查询时遇到了这个问题:
UPDATE user
SET ${username ? `username = '${username}', ` : ``}${
password ? `password = '${password}'` : ``
}${isStaff ? `isStaff = '${isStaff}'` : ``
} WHERE email = '${email}';
这里,在用户名和密码之后有一个逗号,但不能保证请求会更新所有三列。例如,如果请求主体只包含用户名,那么最终查询会出现语法问题:
UPDATE user
SET username = 'exampleuser',
如何动态设置这个有条件的查询中的逗号,以便逗号只出现在我设置的列之间呢?
非常感谢您提前的帮助!
我尝试在每个列块中为每列设置条件,但显然这样做非常难看。
英文:
I'm fairly new to creating APIs with ExpressJS, and I came across this problem when forming a query based on the request:
UPDATE user
SET ${username ? `username = '${username}', ` : ``}${
password ? `password = '${password}'` : ``
}${isStaff ? `isStaff = '${isStaff}'` : ``
} WHERE email = '${email}'
Here, I have a comma after username and password, but there is no guarantee that the request would update all three columns. For example, if the request body only has username, then I'd end up with this query with a syntax issue:
UPDATE user
SET username = 'exampleuser',
How can I dynamically set the commas in this conditionally determined query so that the commas would only appear between the columns I'm setting?
Thanks a lot in advance!
I've tried setting a condition for every column in each column block, but that was obviously extremely ugly.
答案1
得分: 1
不要使用字符串连接参数,这会导致SQL注入攻击。
相反,你应该使用参数化查询。
所有著名的ORM、Node本机数据库驱动程序和查询构建器都提供了这个功能。
例如:
有时你可能需要在查询中使用原始表达式。原始查询对象可以注入到几乎任何你想要的地方,使用适当的绑定可以确保你的值被正确转义,防止SQL注入攻击。
英文:
Don't use string concatenating parameters, it will lead to SQL Injection attack
Instead, you should use Parameterized Query
All famous ORM, node native database drivers, and query builders provide this feature.
For example:
-
Parameterized Query of
node-postgres
. -
Raw query of knex.js provide Raw Parameter Binding feature.
> Sometimes you may need to use a raw expression in a query. Raw query object may be injected pretty much anywhere you want, and using proper bindings can ensure your values are escaped properly, preventing SQL-injection attacks.
答案2
得分: 1
在所有变量列后面加上逗号,并添加一个尾随的无操作更新作为最后一列锚点:
UPDATE user SET
${username ? `username = '${username}', ` : ``}
${password ? `password = '${password}', ` : ``}
${isStaff ? `isStaff = '${isStaff}', ` : ``}
email = email
WHERE email = '${email}'
即使没有提供任何变量列,最终的查询也将创建有效的SQL。例如,指定了前两列的情况下:
UPDATE user SET
username = 'foo',
password = 'mypass',
email = email
WHERE email = 'myuser@mydomain.com'
或者没有提供任何变量的情况下:
UPDATE user SET
email = email
WHERE email = 'myuser@mydomain.com'
将列更新为其本身不会引发问题。
与您的问题或此解决方案无关,您不应该将用户的文本直接放入您的SQL中,因为可能会引发SQL注入攻击。请使用安全的库创建一个准备好的语句,然后提供参数。
英文:
Put commas after all variable columns and add a trailing no-op update to be a last-column anchor:
UPDATE user SET
${username ? `username = '${username}', ` : ``}
${password ? `password = '${password}', ` : ``}
${isStaff ? `isStaff = '${isStaff}', ` : ``}
email = email
WHERE email = '${email}'
The final query will create valid SQL even if no variable columns are provided. For example, with the first 2 columns specified:
UPDATE user SET
username = 'foo',
password = 'mypass',
email = email
WHERE email = 'myuser@mydomain.com'
or with none provided:
UPDATE user SET
email = email
WHERE email = 'myuser@mydomain.com'
Updating a column to itself causes no problems.
Not related to your problem or this solution, you shouldn't be putting text from the user straight into your SQL due to possible SQL Injection attacks. Use a secure library to create a prepared statement that you provide the parameters for.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论