今天调试到方法中代码:

String hotelCodes =”’’,’’,’’”;
string sqltext ="select * from HotelMedalInfo where hotelCode in(@hotelCodes)";
SqlParameter[] parameters = {
new SqlParameter("@hotelCodes", hotelCodes)
};
DataTable dt = DBHelper.ExecuteData(sqlText, parameters); if (dt == null || dt.Rows.Count <= )
{
return null;
}

返回数据一直不正确。

调试后,发现应该是ExecuteData生成的Sql有问题。于是想看看到底是怎么回事。我一步步的找到了SqlCommand下的BuildExecuteSql 方法。

其代码如下:

 private void BuildExecuteSql(CommandBehavior behavior, string commandText, SqlParameterCollection parameters, ref _SqlRPC rpc)
{
int num;
int num2 = this.CountSendableParameters(parameters);
if (num2 > )
{
num = ;
}
else
{
num = ;
}
this.GetRPCObject(num2 + num, ref rpc);
rpc.ProcID = ;
rpc.rpcName = "sp_executesql";
if (commandText == null)
{
commandText = this.GetCommandText(behavior);
}
SqlParameter parameter = new SqlParameter(null, ((commandText.Length << ) <= 0x1f40) ? SqlDbType.NVarChar : SqlDbType.NText, commandText.Length);
parameter.Value = commandText;
rpc.parameters[] = parameter;
if (num2 > )
{
string str = this.BuildParamList(this._stateObj.Parser, this.BatchRPCMode ? parameters : this._parameters);
parameter = new SqlParameter(null, ((str.Length << ) <= 0x1f40) ? SqlDbType.NVarChar : SqlDbType.NText, str.Length);
parameter.Value = str;
rpc.parameters[] = parameter;
bool inSchema = CommandBehavior.Default != (behavior & CommandBehavior.SchemaOnly);
this.SetUpRPCParameters(rpc, num, inSchema, parameters);
}
} 其中有用到BuildParamList方法: internal string BuildParamList(TdsParser parser, SqlParameterCollection parameters)
{
StringBuilder builder = new StringBuilder();
bool flag = false;
bool isYukonOrNewer = parser.IsYukonOrNewer;
int count = ;
count = parameters.Count;
for (int i = ; i < count; i++)
{
SqlParameter p = parameters[i];
p.Validate(i, CommandType.StoredProcedure == this.CommandType);
if (ShouldSendParameter(p))
{
if (flag)
{
builder.Append(',');
}
builder.Append(p.ParameterNameFixed);
MetaType internalMetaType = p.InternalMetaType;
builder.Append(" ");
if (internalMetaType.SqlDbType == SqlDbType.Udt)
{
string udtTypeName = p.UdtTypeName;
if (ADP.IsEmpty(udtTypeName))
{
throw SQL.MustSetUdtTypeNameForUdtParams();
}
builder.Append(this.ParseAndQuoteIdentifier(udtTypeName, true));
}
else if (internalMetaType.SqlDbType == SqlDbType.Structured)
{
string typeName = p.TypeName;
if (ADP.IsEmpty(typeName))
{
throw SQL.MustSetTypeNameForParam(internalMetaType.TypeName, p.ParameterNameFixed);
}
builder.Append(this.ParseAndQuoteIdentifier(typeName, false));
builder.Append(" READONLY");
}
else
{
internalMetaType = p.ValidateTypeLengths(isYukonOrNewer);
builder.Append(internalMetaType.TypeName);
}
flag = true;
if (internalMetaType.SqlDbType == SqlDbType.Decimal)
{
byte actualPrecision = p.GetActualPrecision();
byte actualScale = p.GetActualScale();
builder.Append('(');
if (actualPrecision == )
{
if (this.IsShiloh)
{
actualPrecision = 0x1d;
}
else
{
actualPrecision = 0x1c;
}
}
builder.Append(actualPrecision);
builder.Append(',');
builder.Append(actualScale);
builder.Append(')');
}
else if (internalMetaType.IsVarTime)
{
byte num6 = p.GetActualScale();
builder.Append('(');
builder.Append(num6);
builder.Append(')');
}
else if (((!internalMetaType.IsFixed && !internalMetaType.IsLong) && ((internalMetaType.SqlDbType != SqlDbType.Timestamp) && (internalMetaType.SqlDbType != SqlDbType.Udt))) && (SqlDbType.Structured != internalMetaType.SqlDbType))
{
int size = p.Size;
builder.Append('(');
if (internalMetaType.IsAnsiType)
{
object coercedValue = p.GetCoercedValue();
string str = null;
if ((coercedValue != null) && (DBNull.Value != coercedValue))
{
str = coercedValue as string;
if (str == null)
{
SqlString str4 = (coercedValue is SqlString) ? ((SqlString) coercedValue) : SqlString.Null;
if (!str4.IsNull)
{
str = str4.Value;
}
}
}
if (str != null)
{
int num4 = parser.GetEncodingCharLength(str, p.GetActualSize(), p.Offset, null);
if (num4 > size)
{
size = num4;
}
}
}
if (size == )
{
size = internalMetaType.IsSizeInCharacters ? 0xfa0 : 0x1f40;
}
builder.Append(size);
builder.Append(')');
}
else if ((internalMetaType.IsPlp && (internalMetaType.SqlDbType != SqlDbType.Xml)) && (internalMetaType.SqlDbType != SqlDbType.Udt))
{
builder.Append("(max) ");
}
if (p.Direction != ParameterDirection.Input)
{
builder.Append(" output");
}
}
}
return builder.ToString();
}

看到这里我有点明白为什么了。原来其内部根据参数构建sql时用到了‘,’。我们为参数中包含的逗号,应该是被它误解或者屏蔽了。

对此,我们可以创建一个函数,根据字符串hotelCodes,返回一个表。Sql条件根据函数的结果来判断。

1.创建函数

CREATE   FUNCTION   [dbo].[f_split](@c   varchar(2000),@split   varchar(2))
returns @t TABLE(col varchar(20))
AS
begin
while(charindex(@split,@c)<>0)
begin
INSERT @t(col) VALUES (substring(@c,1,charindex(@split,@c)-1))
SET @c = stuff(@c,1,charindex(@split,@c),'')
end
INSERT @t(col) VALUES (@c)
RETURN
end
GO

2.程序sql文本部分做如下修改:

string sqltext ="select * from HotelMedalInfo where hotelCode in (select * from dbo.f_split(@hotelCodes,’,'))";

关于SqlParameter中IN子句查询的问题的更多相关文章

  1. SQL Fundamentals: 子查询 || WHERE,HAVING,FROM,SELECT子句中使用子查询,WITH子句

    SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...

  2. 子查询三(在FROM子句中使用子查询)

    FROM子句中使用子查询一般都是返回多行多列,可以将其当作一张数据表 示例一.查询出每个部门的编号,名称,位置,部门人数,平均工资 SELECT d.deptno,d.dname,d.loc,temp ...

  3. 在form子句中使用子查询时的注意事项

    今天中午为了弄清这个问题,本人真的是头都搞大了!最后明白了一点,在from子句中使用子查询是,一定要将临时表的别名带上,否则会灰常痛苦!!!

  4. 详细讲述MySQL中的子查询操作 (来自脚本之家)

    继续做以下的前期准备工作: 新建一个测试数据库TestDB: ? 1 create database TestDB; 创建测试表table1和table2: ? 1 2 3 4 5 6 7 8 9 1 ...

  5. 在update语句中使用子查询

    在update 中的 where 子句中使用子查询: UPDATE mg_page_log as a  SET  page_num=1 WHERE id in( SELECT id  from mg_ ...

  6. 浅谈T-SQL中的子查询

    引言 这篇文章我们来简单的谈一下子查询的相关知识.子查询可以分为独立子查询和相关子查询.独立子查询不依赖于它所属的外部查询,而相关子查询则依赖于它所属的外部查询.子查询返回的值可以是标量(单值).多值 ...

  7. oracle中的连接查询与合并查询总结

    连接查询: 连接查询是指基于多张表或视图的查询.使用连接查询时,应指定有效的查询条件,不然可能会导致生成笛卡尔积.如现有部门表dept,员工表emp,以下查询因查询条件无效,而产生笛卡尔积:   (各 ...

  8. LINQ中的一些查询语句格式

    LINQ的基本格式如下所示:var <变量> = from <项目> in <数据源> where <表达式> orderby <表达式> ...

  9. 在 SQL Server 数据库的 WHERE 语句中使用子查询

    这是关于子查询语句的一系列文章中的第三篇.在这篇文章中我们将讨论WHERE语句中的子查询语句.其他的文章讨论了其他语句中的子查询语句. 本次课程中的所有例子都是基于Microsoft SQL Serv ...

随机推荐

  1. php学习日志(3)-echo&print

    在php中,结果输出一共有两种方式:echo和print,下面将对两种方式做一个比较. echo与print的区别:   echo print 连续输出字符串 能连续输出多个字符串 只能输出一个字符串 ...

  2. 关于python多线程编程中join()和setDaemon()的一点儿探究

    关于python多线程编程中join()和setDaemon()的用法,这两天我看网上的资料看得头晕脑涨也没看懂,干脆就做一个实验来看看吧. 首先是编写实验的基础代码,创建一个名为MyThread的  ...

  3. ENVI栅格文件增强后将LUT保存完输出img图像进行分类

    ENVI栅格文件储存 图像原始的DN(Digital Number)值记录图像的光谱信息,不能轻易更改。在窗口中显示的一般是经过拉伸等增强处理的LUT上的灰度值,在保存文件时,就有不同的方式。 1.  ...

  4. 进程(Process)和线程(Thread)的关系和区别

    Definition定义-------------Process进程是应用程序的一次运行活动:从操作系统核 心角度来说,进程是操作系统分配和调度系统内存资源.cpu时间片等资源的基本单位,为正在运行的 ...

  5. 微软职位内部推荐-SDE II-MODC-Beijing

    微软近期Open的职位: JOB TITLE: Software Design Engineer IIDEPARTMENT: Microsoft Office Division ChinaIMMEDI ...

  6. HDFS(Hadoop Distributed File System )

    HDFS(Hadoop Distributed File System ) HDFS(Hadoop Distributed File System )Hadoop分布式文件系统.是根据google发表 ...

  7. 在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新。

    UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0 ...

  8. Linux学习笔记(7)-系统资源查看

    监控系统资源:vmstat #vmstat [采样时间] [ 采样次数] 如:#vmstat 3 2 每3秒采样一次,总共采样2次 输出信息各字段解释 r 表示运行队列,如果运行队列多大表示CPU很繁 ...

  9. 3.5 spring-replaced-method 子元素的使用与解析

    1.replaced-method 子元素 方法替换: 可以在运行时用新的方法替换现有的方法,与之前的 look-up不同的是replace-method 不但可以动态地替换返回的实体bean,而且可 ...

  10. Hibernate - SQLQuery

    使用SQLQuery 对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口.下面来描述如何使用这个API进行查询. 标量查询 ...