您看到的是一个参数化查询。 从程序执行动态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都使用?。MS SQL使用命名参数,我认为这是一个巨大的改进:
cmd.Text = "SELECT thingA FROM tableA WHERE thingB = @varname"
cmd.Parameters.AddWithValue("@varname", 7)
result = cmd.Execute()