通过阅读一些 SQL 书籍,我发现示例在查询中倾向于使用问号(?)。它代表什么?
?
?是一个未命名的参数,可以通过运行查询的程序来填充,以避免 SQL 注入。
它通常表示由客户端提供的参数。
它是一个参数。您可以在执行 query 时指定它。
我认为这在 SQL 中没有任何意义。您可能正在查看 JDBC 中的准备好的语句或其他内容。在这种情况下,问号是语句参数的占位符。
?允许 参数化查询。这些参数化查询允许在用各自的值替换 ?时使用特定于类型的值。
就这些了。
有几个原因解释了为什么使用参数化查询是一个很好的实践。实际上,它更容易读取和调试,并且可以规避 SQL 注入攻击。
你看到的是一个 参数化查询参数化查询。它们经常用于从程序中执行动态 SQL。
例如,不写这个(注意: 伪代码) :
ODBCCommand cmd = new ODBCCommand("SELECT thingA FROM tableA WHERE thingB = 7") result = cmd.Execute()
你这样写:
ODBCCommand cmd = new ODBCCommand("SELECT thingA FROM tableA WHERE thingB = ?") cmd.Parameters.Add(7) result = cmd.Execute()
这有很多好处,这可能是显而易见的。其中最重要的一点是: 解析参数的库函数非常聪明,可以确保字符串被正确地转义。例如,如果你这样写:
string s = getStudentName() cmd.CommandText = "SELECT * FROM students WHERE (name = '" + s + "')" cmd.Execute()
当用户输入这个时会发生什么?
Robert'); DROP TABLE students; --
(答案是 给你)
改写如下:
s = getStudentName() cmd.CommandText = "SELECT * FROM students WHERE name = ?" cmd.Parameters.Add(s) cmd.Execute()
然后库将 消毒输入,生成以下内容:
"SELECT * FROM students where name = 'Robert''); DROP TABLE students; --'"
并非所有 DBMS 使用 ?.MSSQL 都使用 名字参数,我认为这是对 巨大的改进:
cmd.Text = "SELECT thingA FROM tableA WHERE thingB = @varname" cmd.Parameters.AddWithValue("@varname", 7) result = cmd.Execute()