在做项目中,我们经常遇到复杂的查询方法,要根据用户的输入,判断某个参数是否合法,合法的话才能当作过滤条件,我们通常的做法是把查询SQL赋值给一个字符串变量,然后根据判断条件动态的拼接where条件进行查询。下面来简单说一下写SQL中遇到的问题和解决办法。

 一、不确定字段名,而产生的SQL字符串拼接

  比如,有个公司要做一个系统,要支持多语言,这个时候我们就要将语音信息存储在数据库中。然后,根据客户选择查询对应的语言字段,进行显示。下面我们来模拟这个场景,打开SQL Server,新建SysLanguage表,添加一些语言字段,如English,Chinese,French,这里French不知道是什么,就都设置为Empty。

建表的SQL和插入一些简单的数据,SQL如下:

CREATE TABLE SysLanguage(
Id INT PRIMARY KEY,
English NVARCHAR(100),
Chinese NVARCHAR(100),
French NVARCHAR(100)
) INSERT INTO SysLanguage VALUES (1, 'Hello', '你好', 'Empty')
INSERT INTO SysLanguage VALUES (2, 'world', '世界', 'Empty')
INSERT INTO SysLanguage VALUES (3, 'Book', '书', 'Empty')
INSERT INTO SysLanguage VALUES (4, 'Open', '打开', 'Empty')
INSERT INTO SysLanguage VALUES (5, 'Save', '保存', 'Empty')
INSERT INTO SysLanguage VALUES (6, 'New', '新建', 'Empty')

那么,考虑到系统性能,我们可能会使用存储过程,来减少网络通信量和提高响应速度。那么,在存储过程中,我们会传入一个参数,然后根据参数来查询指定的语言字段,那么SQL该怎么写呢?

这个时候,我们会想到在C#代码中,我们都是把SQL拼好,然后传给SQL Server执行,我们可以拼接字符串啊,然后有了下面的写法:

DECLARE @sql NVARCHAR(100);
DECLARE @para NVARCHAR(20);
SET @para = 'Chinese';
SET @sql = 'select ID, ' + @para + ' from SysLanguage'
print @sql
exec(@sql)

当然这样写没有任何问题,但是当SQL很复杂的时候,很多的引号和字符转义,还有拼接字符串带来的缺少空格的问题,会令人崩溃!下面来说一种不拼接字符串的写法,代码如下:

DECLARE @para NVARCHAR(20);
SET @para = 'Chinese';
SELECT ID,
CASE @para
WHEN 'English' THEN English
WHEN 'Chinese' THEN Chinese
ELSE
French
END
AS [Language]
FROM
SysLanguage

这里使用了CASE WHEN语句来进行判断,当判断条件太多时,写起来也很累,我们可以写一个Function来进行封装,当然,具体用那种方法,要看具体情况了。

这里说道了CASE WHEN,就不得不提另外一种查询了。先来看下需求:从学生表中查询出男生的人数,女生的人数和学生总人数。

看到这个,我们首先想到了SUM函数,但是,然后呢?好像哪里不对?那么,到底该怎么写呢,当然还是用CASE WHEN,来看下代码吧

SELECT SUM(CASE StuSex WHEN 1 THEN 1 ELSE 0 END) AS Boys,
SUM(CASE StuSex WHEN 1 THEN 0 ELSE 1 END) AS Girls,
SUM(StuID) AS Total
FROM Student

看到代码,感觉是不是很简单啊,就是当时没想到,呵呵!

 二、不定查询条件产生的SQL字符串拼接

  习惯了C#代码,突然写起SQL来,感觉还是有点那么不顺手!下面来看看,当有多个查询条件,但是又不确定几个查询条件时,SQL该怎么写?我们经常遇到这种需求,页面上很多控件,要根据用户的输入进行查询,这个时候我们就要判断传入的控件的值是否符合指定条件,符合条件了才能被作为查询条件,否则就忽略这个条件。

拼接字符串的写法相信大家都经常用,这里就不写了,我们之接来看布拼接SQL怎么查询!

比如现在要查询指定条件的学生,用户可能查询所有,或查询男生,或查询指定Id的学生,或……等待,可能很多种情况。下面我们来写布拼接字符串的SQL,代码如下:

DECLARE @ID INT;
DECLARE @Sex BIT;
DECLARE @Name NVARCHAR(50); SET @ID = -1;
SET @Sex = NULL;
SET @Name = 'Ja'; SELECT * FROM Student
WHERE (@ID = -1 OR StuID = @ID)
AND (@Sex IS NULL OR StuSex = @Sex)
AND (@Name IS NULL OR StuName LIKE '%' + @Name + '%')

这里声明三个变量,当做传入的参数,传入的参数都有默认值,或者为NULL,我们在where添加里面用了OR添加判断,首先判断@ID = -1,如果条件成立了,OR就不会再判断OR后面的条件,到这里就(@ID = -1 OR StuID = @ID)就返回一个TRUE,相当于WHERE TRUE AND ……,所以就会忽略这个查询条件继续走下面的过滤判断。这样写,比拼接字符串好的多吧!

最后来说一下数据库中N字符的作用,说白了就是将后面的字符串内容,转换成Unicode编码,来写段SQL测试一下吧

DECLARE @a NVARCHAR(20)
DECLARE @b NVARCHAR(20)
SET @a = N'中文'
SET @b = '中文'
IF(@a = @b)
PRINT '数值相等'
ELSE
PRINT '不相等'

输出结果如下:

在中文版的系统中,是相等的,在英文版的系统中,@b会显示乱码。大家可以测试一下!

作者:雲霏霏

博客地址:http://www.cnblogs.com/yunfeifei/

声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。

必须知道的SQL编写技巧,多条件查询不拼字符串的写法的更多相关文章

  1. 转15个必须知道的chrome开发者技巧GIF

    在Web开发者中,Google Chrome是使用最广泛的浏览器.六周一次的发布周期和一套强大的不断扩大开发功能,使其成为了web开发者必备的工具.你可能已经熟悉了它的部分功能,如使用console和 ...

  2. 15个必须知道的chrome开发者技巧(转)

    15个必须知道的chrome开发者技巧 在Web开发者中,Google Chrome是使用最广泛的浏览器.六周一次的发布周期和一套强大的不断扩大开发功能,使其成为了web开发者必备的工具.你可能已经熟 ...

  3. CakePHP程序员必须知道的21条技巧

    这篇文章可以说是CakePHP 教程中最经典的了.虽然不是完整的手把手系列, 但作者将自己使用CakePHP 的经验总结了21条,这些尤其是对新手十分有用. 翻译时故意保留了一些CakePHP 中特有 ...

  4. 学python必须知道的30个技巧

    收集这些有用的捷径技巧 1. 原地进行交换两个数字 我们对赋值的右侧进行一个新的元组,左侧解析(unpack)那个(未被引用的)元组到变量 <a> 和 <b> 赋值完成时,新的 ...

  5. 15个必须知道的chrome开发者技巧

    在Web开发者中,Google Chrome是使用最广泛的浏览器.六周一次的发布周期和一套强大的不断扩大开发功能,使其成为了web开发者必备的工具.你可能已经熟悉了它的部分功能,如使用console和 ...

  6. JS开发必须知道的41个技巧

    JS是前端的核心,但有些使用技巧你还不一定知道:本文梳理了JS的41个技巧,帮助大家提高JS的使用技巧: Array 1.数组交集 普通数组 const arr1 = [, , , , , ,],ar ...

  7. 【转】15个必须知道的chrome开发者技巧

    一.快速切换文件 如果你使用过sublime text,那么你可能不习惯没有Go to anything这个功能的覆盖.你会很高兴听到chrome开发者功能也有这个功能,当DevTools被打开的时候 ...

  8. Webservice WCF WebApi 前端数据可视化 前端数据可视化 C# asp.net PhoneGap html5 C# Where 网站分布式开发简介 EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下? SQL Server之深入理解STUFF 你必须知道的EntityFramework 6.x和EntityFramework Cor

    Webservice WCF WebApi   注明:改编加组合 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下, ...

  9. 你必须知道的10个提高Canvas性能技巧

    你还在抱怨自己写的canvas demo徘徊在10帧以下吗?你还在烦恼打开自己写的应用就听见CUP风扇转吗?你正在写一个javascript Canvas库吗?那么下面九点就是你必须知道的! 一.预渲 ...

随机推荐

  1. Ceph剖析:Paxos算法实现

    作者:吴香伟 发表于 2014/10/8 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 Recovery阶段 在Leader选举成功后,Leader和Peon都 ...

  2. C++ exe调用dll文件

    生成dll程序 extern "C"_declspec(dllexport) void maopao(int *p,int count);void maopao(int *p,in ...

  3. CSS里常见的块级元素和行内元素

    根据CSS规范的规定,每一个网页元素都有一个display属性,用于确定该元素的类型,每一个元素都有默认的display属性值,比如div元素,它的默认display属性值为“block”,成为“块级 ...

  4. php二维数组按照键值排序的方法

    //按照传入数组中的num倒序 public function numdesc($array,$key="num",$order="desc"){ $arr_n ...

  5. mysql galera cluster 集群的分裂与仲裁机制

    集群的分裂 当集群由于网络原因分裂为几个单独的组时(一组可能是单节点,也可能是几个互联的节点),数据出现不一致,此时可能产生脑裂及数据不一致.这种情况 下,只有一组节点能够继续提供服务,这组节点的状态 ...

  6. 【Mail】telnet收发邮件过程

    telnet发送邮件 关于电子邮件的基础知识请参照:[Mail]邮件的基础知识和原理 smtp协议是一个简单的邮件传输协议,利用它我们可以将邮件发送给别人,这里将通过telnet这个程序利用smtp协 ...

  7. 今天工作中遇到的问题!echart.js

    echart.js 引用的时候, 配置文件和引用的echart.js  应该放在main.js的后面,带有window.onload的js后面.这样的话,不会阻止echar.js的渲染.

  8. WCF 套接字连接已中止。这可能是由于处理消息时出错或远程主机超过接收超时或者潜在的网络资源问题导致的

    一个项目需要用到推送的功能,就是服务器主动推送数据给多台客户机.于是采用了WCF的双工通讯netTcpBinding 写好的项目,在本机测试都没有问题. 如果放在局域网内测试,问题出来了:先是安全性问 ...

  9. Html5应用程序缓存ApplicationCache

    应用缓存机制可以参考http://www.w3school.com.cn/html5/html_5_app_cache.asp,不再赘述.利用此机制,html5游戏可以实现和native app类似的 ...

  10. STM32 GPIO外部中断总结

    一.STM32中断分组: STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处.STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB ...