【问题标题】:Pass a string parameter to command text with quotes将字符串参数传递给带引号的命令文本
【发布时间】:2019-11-20 08:46:00
【问题描述】:

我正在尝试将参数传递给查询,但使用引号作为字符串值。 但我似乎可以让它工作。 我在这里做错了什么。

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'

【问题讨论】:

  • SQL 参数不只是像这样插入到查询中 - 它们被传递作为参数到数据库。不管调试时是什么样子,执行查询时会发生什么?这对我来说基本上是正确的......
  • 代码运行正常。让它按照您期望的方式运行的唯一方法是在查询中使用字符串替换,而不是参数。
  • 是的。熟悉数据库的 Profiler 工具也是明智之举。一旦您开始变得更高级并使用 ORM 框架,事情变得更加不透明,您将感谢我们。
  • @TabAlleman 谢谢我在查询中替换了它而不是将其解析为参数并且它正在工作。
  • @NPras 是的,谢谢你的建议,我确实开始使用分析器工具,并且更容易调试 sql 查询。

标签: c# sql sql-server parameters parameter-passing


【解决方案1】:

除了实际呈现的 cmets 之外,PARAMETERS 会在 post 期间自动处理,而不是 LITERAL 在查询中以防止 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 忽略了语句中的输入键,因此它们仍然可以正常工作并提高可读性。

【讨论】:

    【解决方案2】:

    尝试在 Profiler 中捕获参数化查询。正确的查询看起来像

    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 参数不会插入到查询中。

    【讨论】:

      猜你喜欢
      • 2014-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      • 2018-03-26
      相关资源
      最近更新 更多