首页 新闻 会员 周边

带SqlParameter参数的Sql语句,执行的结果却不是预期的

0
悬赏园豆:30 [已解决问题] 解决于 2013-09-10 17:14
 1         /// <summary>
 2         /// 根据页码、书的分类、查询的条件(出版日期、价格)   来获得某类型某页书的相关查询条件的书列表
 3         /// </summary>
 4         /// <param name="PageIndex">页码</param>
 5         /// <param name="CategoryID">书分类ID</param>
 6         /// <param name="orderCondition">按照出版日期、价格等条件,不允许为空</param>
 7         /// <returns></returns>
 8         public DataTable GetBooksByPageIndex(int PageIndex, int CategoryID,string orderCondition)
 9         {
10             int PageSize = 10;//设置每页的书信息条数,可以写到配置文件中
11             int Start = (PageIndex - 1) * PageSize + 1;
12             int End = PageIndex * PageSize;
13             string sql = string.Empty;
14             sql="select * from (select *,ROW_NUMBER() over({1}) as RN from Books {0} ) as T  where T.RN between @StartPage and @EndPage";
15 
16            sql=string.Format(sql, 
17                CategoryID == 0 ? "" : " where CategoryId=@CategoryId " //替换占位符{0}
18                , "order by @ordercondition" //替代占位符{1}
19                );
20 
21             SqlParameter[] parameters = { 
22                                         new SqlParameter("@StartPage",Start),
23                                         new SqlParameter("@EndPage",End),
24                                         new SqlParameter("@CategoryId",CategoryID)
25                                         ,new SqlParameter("@ordercondition",orderCondition)
26                                         };
27             return DbHelperSQL.Query(sql,parameters).Tables[0];
28         }

 

 

想法是最终得到如下:

select * from (select *,ROW_NUMBER() over(order by UnitPrice) as RN from Books  ) as T  where T.RN between 1 and 10

 

 

结果并没有按照价格UnitPrice进行升序排序

 

 

 

但是修改Sql语句,直接进行Sql语句拼接,却能成功

 1            sql=string.Format(sql, 
 2                CategoryID == 0 ? "" : " where CategoryId=@CategoryId " //替换占位符{0}
 3                , "order by "+orderCondition//替代占位符{1}
 4                );
 5 
 6             SqlParameter[] parameters = { 
 7                                         new SqlParameter("@StartPage",Start),
 8                                         new SqlParameter("@EndPage",End),
 9                                         new SqlParameter("@CategoryId",CategoryID)
10                                        // ,new SqlParameter("@ordercondition",orderCondition)
11                                         };

 

 


 

 

求大神讲述下,为什么Sql语句修改前为什么不能超过

Little_C的主页 Little_C | 初学一级 | 园豆:193
提问于:2013-09-09 23:27
< >
分享
最佳答案
0

这个,你只需要断点即可,绝对是你代码的问题。

收获园豆:20
幻天芒 | 高人七级 |园豆:37175 | 2013-09-10 00:09

我也调试了,@ordercondition参数也是转为orderCondition传来的值

Little_C | 园豆:193 (初学一级) | 2013-09-10 09:31

@Little_C: 把sql变量的值贴出来。

幻天芒 | 园豆:37175 (高人七级) | 2013-09-10 10:02

@幻天芒: 

1             SqlParameter[] parameters = { 
2                                         new SqlParameter("@StartPage",1),
3                                         new SqlParameter("@EndPage",10),
4                                         new SqlParameter("@CategoryId",0)
5                                         ,new SqlParameter("@ordercondition","UnitPrice")
6                                         };
Little_C | 园豆:193 (初学一级) | 2013-09-10 10:18

@Little_C: string sql,我需要看下sql的值。怀疑是你的语句构造出来的结果有问题。

幻天芒 | 园豆:37175 (高人七级) | 2013-09-10 11:16

@幻天芒: 

select * from (select *,ROW_NUMBER() over(order by @ordercondition) as RN from Books  ) as T  where T.RN between @StartPage and @EndPage
Little_C | 园豆:193 (初学一级) | 2013-09-10 12:46

@Little_C: 结果显而易见,你的sql语句中没排序~

over(order by @ordercondition),开窗函数中你的这个参数是无效的。(猜想:系统会理解按照常量排序)

所以显示为默认排序。

幻天芒 | 园豆:37175 (高人七级) | 2013-09-10 12:56

@幻天芒: 你的意思是说开窗函数中不能带参数化查询吗?

Little_C | 园豆:193 (初学一级) | 2013-09-10 15:08

@Little_C: 不接受这种参数,参数化只有值才可以。不是所有的语句都可以用参数化拼出来的。

也可以理解为:”开窗函数中不能带参数化查询“

幻天芒 | 园豆:37175 (高人七级) | 2013-09-10 15:12

@幻天芒: 

但是SqlParameter.ParameterName=@ordercondition的时候,SqlParameter.Value="UnitPrice";

这应该是参数有值传过去了吧。

如果不这样带参数查询的话,那是不是只有在Sql语句把orderCondition的值拼接进去了呢?

像这样:

sql=string.Format(sql, 
 2                CategoryID == 0 ? "" : " where CategoryId=@CategoryId " //替换占位符{0}
 3                , "order by "+orderCondition//替代占位符{1}
 4                );

 

Little_C | 园豆:193 (初学一级) | 2013-09-10 16:08

@Little_C: 参数的确过去了,不过会被当成一个常量使用,相当于默认排序。

幻天芒 | 园豆:37175 (高人七级) | 2013-09-10 16:42

@幻天芒: 我那个擦=。= ,这么坑 

————————————

那只好用Sql语句拼接来实现。。。

Little_C | 园豆:193 (初学一级) | 2013-09-10 17:03

@Little_C: 被坑得多了,就能避免一些坑了,哈哈~

幻天芒 | 园豆:37175 (高人七级) | 2013-09-10 17:08

感谢关注。谢谢大神。

——————————

要是早知道博客园的园友这么热心,就早来了。

 

 

再次感谢各位

Little_C | 园豆:193 (初学一级) | 2013-09-10 17:09

@Little_C: You must believe,this is cnblogs!

幻天芒 | 园豆:37175 (高人七级) | 2013-09-10 23:44

@幻天芒: 我知道了,因为通过传参这种方式本来就是当常量用的。以前老师在讲课时就提到了,用传参是比较安全的方式。它可以避免sql注入。它的功能应该是屏蔽掉了关键字像select、where、and这样的和字段名像你问题中提到的orderCondition

angelshelter | 园豆:9887 (大侠五级) | 2013-09-11 09:19

@angelshelter: 嗯,对于没法传参的。我一般declare @sql varchar(2000),然后exec(@sql)

幻天芒 | 园豆:37175 (高人七级) | 2013-09-11 09:49
其他回答(5)
0

没报错误吗???运行能通过??18行的orderCondition和25行的ordercondition能对应不???c变成小写了。

收获园豆:2
angelshelter | 园豆:9887 (大侠五级) | 2013-09-10 09:18

不好意思,这个是在写这问题的时候,复制第二段代码,修改错了。

现在把18行的@orderCondition修改为@ordercondition了,问题还是不变

支持(0) 反对(0) Little_C | 园豆:193 (初学一级) | 2013-09-10 09:36
0
你把这句注视掉试试。。。int CategoryID要等0、
SqlParameter[] parameters = { 22 new SqlParameter("@StartPage",Start), 23 new SqlParameter("@EndPage",End), 24 //new SqlParameter("@CategoryId",CategoryID) 25 ,new SqlParameter("@ordercondition",orderCondition) 26 }; 27 return DbHelperSQL.Query(sql,parameters).Tables[0];

 

收获园豆:2
..00.. | 园豆:49 (初学一级) | 2013-09-10 10:09

试了,没有用。

 

支持(0) 反对(0) Little_C | 园豆:193 (初学一级) | 2013-09-10 12:45
0

自己调试一下就会出来的,不可能是数据库问题。

收获园豆:2
Albert Fei | 园豆:2102 (老鸟四级) | 2013-09-10 10:38

感谢关注。谢谢

支持(0) 反对(0) Little_C | 园豆:193 (初学一级) | 2013-09-10 17:07
0

select * from

(select *,ROW_NUMBER() over(order by UnitPrice) as RN from Books )

as T where T.RN between 1 and 10 

order by UnitPrice

-----------------------------个人理解 -不知道对不对

你排序的范围 的问题。

内外应该一致 排序方式

收获园豆:4
Mundo Novo | 园豆:69 (初学一级) | 2013-09-10 14:34

select *,ROW_NUMBER() over(order by UnitPrice) as RN from Books

这就话的意思是 :

按照价格顺序将Books表重新排序(默认升序),再加了一列RN组成一张新表T,这一列就是序号 1 2 3 4 .......

 

 

T.RN between 1 and 10    就是根据组成的新表中的RN列中的序号1~10,来获得对应行的数据,

所以表外可以不用加order by UnitPrice,因为组成的新表已经是排序好了的

支持(0) 反对(0) Little_C | 园豆:193 (初学一级) | 2013-09-10 15:05

@Little_C: 

-----------------------

去MSDN问问吧. 

支持(0) 反对(0) Mundo Novo | 园豆:69 (初学一级) | 2013-09-10 16:56

好吧。。。谢谢关注。

————————

第一次来问问题,这么多热心人,非常感谢。

支持(0) 反对(0) Little_C | 园豆:193 (初学一级) | 2013-09-10 17:06
0

蛋疼的是SQL 不支持order by + @参数变量 这个模式。 这个是规定死的。不知道为什么要这样规定。。。。。

wgscd | 园豆:202 (菜鸟二级) | 2019-05-14 11:23
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册