如何在有条件地构建查询时处理逗号

huangapple go评论48阅读模式
英文:

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:

> 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.

huangapple
  • 本文由 发表于 2023年7月10日 11:50:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76650588.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定