为什么连接SQL字符串是一个坏主意?

我已经读过这样连接SQL字符串是个坏主意:

cmd.CommandText = "Insert INTO workers Values (" + User.Identity.Name + "," + WorkerName.Text + "," + GetUniqueWorkerKey() + ");"; 

所以推荐的方式是:

 cmd.CommandText = "Insert INTO workers Values (@Username, @WorkerName, @WorkerKey)"; cmd.Parameters.AddWithValue("@Username", User.Identity.Name); cmd.Paramters.AddWithValue("@WorkerName", TheWorkerNameYouPassedToThisMethod); 

自从我读到它以来,我一直在避免连接SQL字符串,但我从未真正知道不这样做的理由。 AddWithValue()方法最终不会在场景后面执行相同的字符串连接吗?

也许该方法剥离特殊字符并将字符转换为html实体以防止sql注入,但我可以在连接我的SQL之前完成所有这些,我也得到相同的效果,不是吗? 或者是否有其他原因不练习SQL的字符串连接?

简短回答:通过连接字符串来构建查询通常允许SQL注入。

想象一下,有人试图创建一个名为“ Bob, Joe, 12345); DROP TABLE workers; -- ”的用户。 您最终构建查询“ Insert INTO workers Values(Bob, Joe, 12345); DROP TABLE workers; --name, 34345236); ”Bye-bye数据库。 SQL注入还可以导致查询返回不应该返回的数据,例如密码表。 只要你有SQL注入,就假设你允许任意第三方向你的数据库发出任意命令。

AddWithValue()方法称为“参数化查询”。 它会生成非常相似的命令,但AddWithValue()会处理参数值中的空格和引号之类的奇怪内容,这些内容可能会导致命令的含义超出您希望的含义。 当然,你可以手动逃避,但要弄清楚可能会很棘手。 让图书馆为您处理它会更容易,更安全。

强制性XKCD