我正在尝试将参数传递给查询,但将引号作为字符串值。 但我似乎可以让它发挥作用。 我在这里做错了什么。
SqlConnection conn = new SqlConnection(SERP_FT_connection);
SqlCommand cmd = new SqlCommand("SELECT sp.* "
+ " FROM [serp_post] sp "
+ " LEFT JOIN [serp_m3_data] m3 ON m3.serp_post_id = sp.serp_post_id "
+ " WHERE sp.[serp_status_id]='CLEAR_DONE' AND sp.m3UpdateStatus <> '2' AND sp.process_type='POST' AND m3.EGTRCD = '40' AND m3.EPPYME = @paymentTerm ", conn);
cmd.CommandType = CommandType.Text;
conn.Open();
SqlParameter param = new SqlParameter();
param.ParameterName = "@paymentTerm";
param.Value = paymentTerm; // when debugged here it shows as "CH1"
cmd.Parameters.Add(param);
调试时查询看起来像这样,
SELECT sp.* FROM [serp_post] sp LEFT JOIN [serp_m3_data] m3 ON m3.serp_post_id = sp.serp_post_id WHERE sp.[serp_status_id]='CLEAR_DONE' AND sp.m3UpdateStatus <> '2' AND sp.process_type='POST' AND m3.EGTRCD = '40' AND m3.EPPYME = @paymentTerm
最后查询应该看起来像这个用引号传递的值
SELECT sp.* FROM [serp_post] sp LEFT JOIN [serp_m3_data] m3 ON m3.serp_post_id = sp.serp_post_id WHERE sp.[serp_status_id]='CLEAR_DONE' AND sp.m3UpdateStatus <> '2' AND sp.process_type='POST' AND m3.EGTRCD = '40' AND m3.EPPYME = 'CH1'
尝试在探查器中捕获参数化查询。正确的查询看起来像这样
exec sp_executesql N' SET FMTONLY OFF; SET NO_BROWSETABLE ON;SELECT sp.* FROM [serp_post] sp LEFT JOIN [serp_m3_data] m3 ON m3.serp_post_id = sp.serp_post_id WHERE sp.[serp_status_id]='CLEAR_DONE' AND sp.m3UpdateStatus <> '2' AND sp.process_type='POST' AND m3.EGTRCD = '40' AND m3.EPPYME = @paymentTerm',N'@paymentTerm varchar(10)',@paymentTerm='CH1'
正如 Jon Skeet 所说,SQL 参数不会插入到查询中。
除了实际呈现的注释之外,参数会在发布过程中自动处理,而不是查询中的文字,以防止 sql 注入。
至于关于双引号的其他答案,我已经养成了用 C# 编写 sql 的习惯,如下所示,以帮助防止意外使用双引号。
SqlCommand cmd = new SqlCommand( "", conn);
cmd.CommandText =
@"SELECT
sp.*
FROM
[serp_post] sp
LEFT JOIN [serp_m3_data] m3
ON m3.serp_post_id = sp.serp_post_id
WHERE
sp.[serp_status_id]='CLEAR_DONE'
AND sp.m3UpdateStatus <> '2'
AND sp.process_type='POST'
AND m3.EGTRCD = '40'
AND m3.EPPYME = @paymentTerm ";
注意完全可读的查询,无需滚动或忘记下一行的右双引号 + 等...同样,这只是构建 sql 命令的一种风格。 前导@表示整个文本,直到它关闭其他双引号。 由于 SQL 忽略语句中的输入键,因此它们仍然可以正常工作并提高可读性。