【问题标题】:sqlParameter conversionsql参数转换
【发布时间】:2008-10-08 11:10:25
【问题描述】:

我正在尝试调用下面的 SQL 语句,但得到以下错误:

System.Data.SqlClient.SqlException:转换时转换失败 varchar 值 '+@buildingIDs+' 到数据类型 int。

@"SELECT id, startDateTime, endDateTime 
    FROM tb_bookings 
   WHERE buildingID IN ('+@buildingIDs+') 
     AND startDateTime <= @fromDate";

buildingID 是 db 中的 int 类型列。我需要将 ID 作为整数数组传递吗?

【问题讨论】:

标签: .net sql sql-server


【解决方案1】:

Bravax 的方式有点危险。我会采用以下方法,以免您受到 SQL 注入的攻击:

int[] buildingIDs = new int[] { 1, 2, 3 };

/***/ @"SELECT id, startDateTime, endDateTime From tb_bookings WHERE buildingID IN (" +
      string.Join(", ", buildingIDs.Select(id => id.ToString()).ToArray())
      + ") AND startDateTime <= @fromDate"; 

【讨论】:

  • 说实话,我看不出代码有什么不同。我们都在构建一个字符串并执行它。您刚刚充实了如何构造 buildingIDs 字符串。如果 SQL 注入是一个问题,则使用存储过程,可能使用 Marc Gravell 的方法。
  • 差异很小但很重要-您的代码示例暗示使用传入的字符串进行字符串连接(这引入了 SQL 注入的可能性);这个例子传入一个整数数组,本质上是强制将干净的数据传递给它。
【解决方案2】:

请注意,LINQ 可以通过包含(映射到 IN)来执行此操作。使用常规 TSQL,另一种选择是将列表作为 CSV(等)varchar 传递,并使用表值 UDF 将 varchar 拆分为多个片段。这允许您使用单个 TSQL 查询(对 UDF 结果执行 INNER JOIN)。

【讨论】:

    【解决方案3】:

    如果可能的话,我宁愿建议使用存储过程,并将 ID 列表作为 xml 传递。您可以从 here 获取有关此方法的更多详细信息。

    【讨论】:

      【解决方案4】:

      它试图将 int 与字符串值 '+@buildingsIDs+' 进行比较
      所以它尝试转换字符串以将其转换为 int 并失败。

      请执行以下操作:
      buildingsIDs = "1, 5, 6";
      @"SELECT id, startDateTime, endDateTime From tb_bookings WHERE buildingID IN (" + buildingIDs + ") AND startDateTime <= @fromDate";

      【讨论】:

        猜你喜欢
        • 2017-09-04
        • 1970-01-01
        • 2013-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多