你目前正处于脱机状态,正在等待 Internet 重新连接

HOWTO: 实现助手类以使用 SqlParameter IN 子句中的值列表

注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。如果您发现了错误并希望帮助我们提高机器翻译技术,请完成文章末尾的在线调查。

点击这里察看该文章的英文版: 555167
作者
William Ryan MVP
社区解决方案内容免责声明
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的或衍生性的损失或任何种类的损失,均不负任何责任,无论该等诉讼是合同之诉、疏忽或其它侵权行为之诉。
症状
您正在试图隔开分隔符, 到 SQL 语句或 StoredProcedure 它将使用列表 IN 语句中多个值中传递而传递作为单个列表中 .
原因
这实际上是由一种功能  使参数有益要首先使用 - 它们转义值插入到和传递中作为一个文本。 因此如果将 @ SomeValue = 1,2,3,4,5, SELECT 中使用它 WHERE [ ColumnName ] IN @ SomeValue, 您不匹配 [ ColumnName ] 中的值是等于 1,2,3,4 或 5 FROM [ TableName ] *。 您而想只匹配值完全是 " 1,2,3,4,5 "。 因此如果这是我们过程:
<CODE>
CREATEPROCEDURE up_ProcedureHelper
     @ 令牌 AS VARCHAR (50) -- 或需要将任何长度
AS
SELECT * FROM [ TableName ]
WHERE [ FieldName ] IN (@ 令牌)
</CODE>
此代码将失败:
<CODE>
字符串 cs = ConfigurationSettings.AppSettings("ConnectString"));
using(SqlConnection cn = new SqlConnection(cs)){
      SqlCommand cmd = 新 SqlCommand (" up_ProcedureHelper ", ConnectionName);
      cmd.CommandType = CommandType.StoredProcedure;
      cmd.Parameters.Add("@token", "1,2,3,4,5);
      应将 Try/Finally / Catch 中包装 //In 现实 Connection.Open 以及 ExecuteReader cn.Open)
      dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);    
      Debug.Assert (dr.HasRows, " 我们有行但不 " 应该) ; //Fails 因为 ColumnName 是 Integer 域并且不保存 " 1,2,3,4,5 "

} </CODE>
解决方案
更改您存储过程以 Accommodate 新方法
  要解决此问题一个简单方法是: 创建临时表使用 SQL Server 2000 的临时表功能。 我们使用简单循环来分析通过是给定分隔符隔开, 我们已经传递变量。 每通过循环, 上我们会将每个变量插入临时表。 最后, 我们将使用子查询来匹配 子句中值:
<CODE>
CREATEPROCEDURE up_ProcedureHelper
     @ 令牌 AS VARCHAR (50) -- 或需要将任何长度
AS
DECLARE @ temp AS VARCHAR(50)
CREATE TABLE # HOLDER(TokenValues VARCHAR(50))
WHILE LEN(@tokens) 大于 0
    BEGIN
       IF CHARINDEX(',', @tokens) = 0
          BEGIN
             SET @TEMP = @tokens  
             SET @tokens =
             INSERTINTO (TokenValues) #Holder VALUES(@Temp)
          终点
       ELSE
          BEGIN
             SET @temp = LEFT (@tokens, CHARINDEX(',', @tokens) - 1)     
             INSERTINTO (TokenValues) #Holder VALUES(@Temp)
             SET @tokens = RIGHT (@tokens, LEN(@tokens)-LEN(@Temp)-1)
       终点
    终点
SELECT * FROM [ TableName ]
WHERE [ FieldName ] IN (SELECT TokenValues FROM #holder)
</CODE>
 
因此, 假设参数 " 1,2,3,4,5 ", 我们必须 Temp 表分别命名 #Holder 1,2,3,4 & 5 值和 5 行。 只要是实时连接下创建它, 该表将存在。 只要我们关闭表将删除自动。 在普通情况是绝对必要记得关闭, 您 . 您不想此处采取任何可能性并希望, 因此使用连接获取关闭, 过程和调用中阻止  从那里方法。 如果您使用 , 您可环绕块中使用您结合中语句  阻止并确保 是  以及  是 (相同原则适用于所有其他连接类型)。
<CODE>
字符串 cs = ConfigurationSettings.AppSettings("ConnectString"));
using(SqlConnection cn = new SqlConnection(cs)){
      SqlCommand cmd = 新 SqlCommand (" up_ProcedureHelper ", ConnectionName);
      cmd.CommandType = CommandType.StoredProcedure;
      cmd.Parameters.Add("@token", "1,2,3,4,5");
      应将 Try/Finally / Catch 中包装 //In 现实 Connection.Open 以及 ExecuteReader cn.Open)
      dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);    
      Debug.Assert(dr.HasRows, "We should have Rows but Don't") 断言成功 - //Now, 我们有 5 行。
}
</CODE>
更多信息
 SQLServer 中参数化存储过程
好讨论了  和时很适合
有关为何要好讨论  查询
如何动态 SQL 语句以编程方式转换  查询

警告:本文已自动翻译

属性

文章 ID:555167 - 上次审阅时间:07/24/2004 23:15:00 - 修订版本: 1.0

Microsoft ADO.NET 1.1, Microsoft ADO.NET 1.0

  • kbpubtypecca kbpubmvp kbhowto KB555167 KbMtzh kbmt
反馈