关于SqlParameter中IN子句查询的问题
今天调试到方法中代码:
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子句查询的问题的更多相关文章
- SQL Fundamentals: 子查询 || WHERE,HAVING,FROM,SELECT子句中使用子查询,WITH子句
SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...
- 子查询三(在FROM子句中使用子查询)
FROM子句中使用子查询一般都是返回多行多列,可以将其当作一张数据表 示例一.查询出每个部门的编号,名称,位置,部门人数,平均工资 SELECT d.deptno,d.dname,d.loc,temp ...
- 在form子句中使用子查询时的注意事项
今天中午为了弄清这个问题,本人真的是头都搞大了!最后明白了一点,在from子句中使用子查询是,一定要将临时表的别名带上,否则会灰常痛苦!!!
- 详细讲述MySQL中的子查询操作 (来自脚本之家)
继续做以下的前期准备工作: 新建一个测试数据库TestDB: ? 1 create database TestDB; 创建测试表table1和table2: ? 1 2 3 4 5 6 7 8 9 1 ...
- 在update语句中使用子查询
在update 中的 where 子句中使用子查询: UPDATE mg_page_log as a SET page_num=1 WHERE id in( SELECT id from mg_ ...
- 浅谈T-SQL中的子查询
引言 这篇文章我们来简单的谈一下子查询的相关知识.子查询可以分为独立子查询和相关子查询.独立子查询不依赖于它所属的外部查询,而相关子查询则依赖于它所属的外部查询.子查询返回的值可以是标量(单值).多值 ...
- oracle中的连接查询与合并查询总结
连接查询: 连接查询是指基于多张表或视图的查询.使用连接查询时,应指定有效的查询条件,不然可能会导致生成笛卡尔积.如现有部门表dept,员工表emp,以下查询因查询条件无效,而产生笛卡尔积: (各 ...
- LINQ中的一些查询语句格式
LINQ的基本格式如下所示:var <变量> = from <项目> in <数据源> where <表达式> orderby <表达式> ...
- 在 SQL Server 数据库的 WHERE 语句中使用子查询
这是关于子查询语句的一系列文章中的第三篇.在这篇文章中我们将讨论WHERE语句中的子查询语句.其他的文章讨论了其他语句中的子查询语句. 本次课程中的所有例子都是基于Microsoft SQL Serv ...
随机推荐
- linux crontab 命令
Linux 系统提供了使用者控制计划任务的命令 :crontab 命令. 一.crond简介 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划 ...
- Thinkphp3.2.2的上传问题
学习了Thinkphp3.2.2的上传,报出了FILE: F:\development\yxk\Cord\Library\Think\Upload.class.php LINE: 257错误 这应该是 ...
- mac上xampp配置
sudo su /Applications/XAMPP/xamppfiles/xampp security
- psutil--跨平台的进程管理
原文地址:http://www.jianshu.com/p/64e265f663f6 Python处理Windows进程 psutil(Python system and process utilit ...
- wancms从apache迁移至nginx
首先解决nginx1.2不支持pathinfo问题,见上一篇博文 其次是数据库的用户名变了之后,修改各种配置,wancms的,ucenter的,bbs的 还有一个是wacms的后台站点管理里面的uc配 ...
- CSS3圆角气泡框,评论对话框
<title>CSS3圆角气泡框,评论对话框</title> <style> body { ; ; font:1em/1.4 Cambria, Georgia, s ...
- 原生JS的对象常用操作总结
前端时间写了篇怎么判断js对象相等的文章,一直在期待大神给点消息,无奈一直杳无音讯,还是自己写个函数来进行判断,下面总结一些常用的对象操作的方法. 咋们来个先抑后扬的方式,先放出几个基本的 ...
- 团体程序设计天梯赛-练习集L1-007. 念数字
L1-007. 念数字 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 翁恺 输入一个整数,输出每个数字对应的拼音.当整数为负数时,先 ...
- Linux下去掉^M的方法
cat -A filename 就可以看到windows下的断元字符 ^M 要去除他,最简单用下面的命令: dos2unix filename 第二种方法: sed -i 's/^M//g ...
- VS2005(vs2008,vs2010)使用map文件查找程序崩溃原因
VS 2005使用map文件查找程序崩溃原因 一般程序崩溃可以通过debug,找到程序在那一行代码崩溃了,最近编一个多线程的程序,都不知道在那发生错误,多线程并发,又不好单行调试,终于找到一个比较好的 ...