原文:使用CASE表达式替代SQL Server中的动态SQL

翻译自:

http://www.mssqltips.com/sqlservertip/1455/using-the-case-expression-instead-of-dynamic-sql-in-sql-server/?utm_source=dailynewsletter&utm_medium=email&utm_content=headline&utm_campaign=2012620

问题:

在决定IF/ELSE时,会有很多UPDATE查询,某些情况下我使用游标,但循环几千行数据的UPDATE时,会花费非常多的事件。我也使用一些动态SQL来处理一些查询参数。除此之外,还有更好的选择吗?

解决方案:

CASE表达式是在解决SQLServer查询问题上的一个强大的工具。你可能感觉到它在SELECT语句中的用法类似于IF/ELSE的处理。但是,相对与IF/ELSE,CASE表达式却没有那么多限制。

在以下代码中将展示CASE表达式的用处:

l  消除在UPDATE行时的游标循环。

l  在使用聚集函数时,执行特殊处理。

l  不使用动态SQL的动态ORDER BY 和WHERE子句

让我们看看以下例子:

首先,先创建一个名为Customer的表并插入数据:

CREATE TABLE
dbo.Customer

(

customerid
INT IDENTITY PRIMARY
KEY,

firstname
VARCHAR(40)
NOT NULL,

lastname
VARCHAR(40)
NOT NULL,

statecode
VARCHAR(2)
NOT NULL,

totalsales
money NOT NULL
DEFAULT 0.00

)

INSERT INTO
dbo.Customer(firstname,
lastname,
statecode, totalsales)

SELECT 'Thomas',
'Jefferson',
'VA', 100.00

INSERT INTO
dbo.Customer(firstname,
lastname,
statecode, totalsales)

SELECT 'John',
'Adams',
'MA', 200.00

INSERT INTO
dbo.Customer(firstname,
lastname,
statecode, totalsales)

SELECT 'Paul',
'Revere',
'MA', 300.00

INSERT INTO
dbo.Customer(firstname,
lastname,
statecode, totalsales)

SELECT 'Ben',
'Franklin',
'PA', 400.00

GO

示例1:

由于报表展示的需要,在一个非范式化的表中增加一个所在州描述列。现在,你可以使用游标和来循环更新每一行。但是游标往往是性能杀手。你也可以使用大量UPDATE语句,但是这将导致程序非常臃肿。

对此,可以在一个UDPATE语句的SET 子句中使用带有CASE关键字来实现更有效的操作:

ALTER TABLE dbo.Customer ADD statedescription VARCHAR(50) NULL 

GO 

UPDATE dbo.Customer 

SET stateDescription = CASE WHEN statecode = 'MA' THEN 'Massachusetts' 

WHEN statecode = 'VA' THEN 'Virginia' 

WHEN statecode = 'PA' THEN 'Pennsylvania' 

ELSE NULL 

END

示例2:

当我们需要统计所有来自Massachusetts州用户的数量及他们的平均总消费时。我们能限制查询在仅仅是Massachusetts的客户。但这将使得在得到用户总数时语句变得臃肿,为此,可以在聚集函数中使用CASE表达式来得到特定信息:

SELECT COUNT(*) AS TotalCustomers,  

SUM(CASE WHEN statecode = 'MA' THEN 1 ELSE NULL END) AS TotalMassCustomers,  

AVG(CASE WHEN statecode = 'MA' THEN totalsales ELSE NULL END) AS TotalMassSales  

FROM dbo.Customer

因为在聚集函数中,NULL值不参与计算,所以可以通过这个特性来获得我们想要的数据。

示例3:

第三个案例来自于我们的桌面,我们需要一个存储过程来被应用程序调用,但用户想根据第一个名字或者第二个名字排序。其中一个方法是使用动态SQL来解决这个问题,但是我们可以使用CASE来等价实现:

CREATE PROCEDURE
dbo.getCustomerData
@sortbyVARCHAR(9),
@sortdirection CHAR(4)

AS

SET nocount
ON

SELECT customerid,
firstname,
lastname, statecode,
statedescription,
totalsales

FROM dbo.Customer

ORDER BY

CASE @sortdirection

WHEN
'asc' THEN

CASE
@sortby

WHEN
'firstname' THEN
firstname

WHEN
'lastname' THEN lastname

END

END

ASC,

CASE @sortdirection

WHEN
'desc' THEN

CASE
@sortby

WHEN
'firstname' THEN
firstname

WHEN
'lastname' THEN lastname

END

END

DESC

GO

EXEC dbo.getCustomerData'lastname',
'desc'

示例4:

最后一个例子中与示例3相似,我们需要改动存储过程去查找特定州的客户,如果该参数被忽略,则返回所有客户的所在州。

ALTER PROCEDURE dbo.getCustomerData @sortby VARCHAR(9), @sortdirection CHAR(4), @statecode VARCHAR(2) = NULL 

AS 

SET nocount ON 



SELECT customerid, firstname, lastname, statecode, statedescription, totalsales 

FROM dbo.Customer 

WHERE statecode = CASE WHEN @statecode IS NOT NULL THEN @statecode  

ELSE statecode 

END 

ORDER BY  

CASE @sortdirection 

     WHEN 'asc' THEN 

      CASE @sortby  

       WHEN 'firstname' THEN firstname  

       WHEN 'lastname' THEN lastname  

       END 

END  

ASC, 

CASE @sortdirection 

      WHEN 'desc' THEN 

       CASE @sortby  

       WHEN 'firstname' THEN firstname  

       WHEN 'lastname' THEN lastname  

       END 

END 

DESC 

GO 



EXEC dbo.getCustomerData 'lastname', 'desc', 'MA'

使用CASE表达式替代SQL Server中的动态SQL的更多相关文章

  1. SQL Server中常用的SQL语句(转):

    SQL Server中常用的SQL语句 转自:http://www.cnblogs.com/rainman/archive/2013/05/04/3060428.html 1.概述 名词 笛卡尔积.主 ...

  2. SQL Server中常用的SQL语句

    1.概述 名词 笛卡尔积.主键.外键 数据完整性 实体完整性:主属性不能为空值,例如选课表中学号和课程号不能为空 参照完整性:表中的外键取值为空或参照表中的主键 用户定义完整性:取值范围或非空限制,例 ...

  3. Sql server中 如何用sql语句创建视图

    1.视图的作用 视图的作用: 第一点:使用视图,可以定制用户数据,聚焦特定的数据. 解释: 在实际过程中,公司有不同角色的工作人员,我们以销售公司为例的话, 采购人员,可以需要一些与其有关的数据,而与 ...

  4. (转)Sql server中 如何用sql语句创建视图

    1.视图的作用 视图的作用: 第一点:使用视图,可以定制用户数据,聚焦特定的数据. 解释:     在实际过程中,公司有不同角色的工作人员,我们以销售公司为例的话,     采购人员,可以需要一些与其 ...

  5. SQL Server中如何让SQL语句对字符串大小写敏感

    在SQL Server中默认对大小写是不敏感的,例如fname='peter'和fname='PETER'结果是一样的.但有时候用户会要求区分大小写,如验证密码等.这种情况下的处理办法就是在字段后加上 ...

  6. 怎样SQL存储过程中执行动态SQL语句

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...

  7. 理解性能的奥秘——应用程序中慢,SSMS中快(6)——SQL Server如何编译动态SQL

    本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(5)--案例:如何应对参数嗅探 我们抛开参数嗅探的话题,回到了本系列的最 ...

  8. SQL Server创建存储过程——动态SQL

    简介: 存储过程(stored procedure)是一组为了完成特定功能的SQL语句集合,经编译后存储在服务器端的数据库中,利用存储过程可以加速SQL语句的执行. 自定义存储过程,由用户创建并能完成 ...

  9. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

随机推荐

  1. linq 中执行方法

    Database1Entities db = new Database1Entities(); protected void Page_Load(object sender, EventArgs e) ...

  2. 《JavaScript设计模式与开发实践》读书笔记之代理模式

    1.代理模式 代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问 1.1 一般的图片加载 var myImage=(function () { var imgNode=document.c ...

  3. WIFI实时监控追踪小车演示视频——安卓端、小车

    文章由@超人爱因斯坦出品,转载请注明出处.         文章链接:          http://hpw123.net/a/qingsongyike/yingyinqu/2014/1019/59 ...

  4. ZooKeeper集群安装

    ZooKeeper是Apache提供的.分布式服务协调系统,应用比較广泛. 由于项目中使用Kafka MQ,而Kafka全然使用ZooKeeper实现Kafka各组件的服务协调,包含Broker.Co ...

  5. 黄聪:Microsoft Enterprise Library 5.0 系列教程(十) Configuration Application Block

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(十) Configuration Application Block 到目前为止,我们使用的模块都是在同一个配置 ...

  6. C语言获取文件SHA1哈希

    安全散列算法(Secure Hash Algorithm)主要适用于数字签名标准 (Digital Signature Standard DSS)它定义了数字签名算法(Digital Signatur ...

  7. Android开发中验证码的生成

    近期在做电商金融类的项目,验证码的生成方法不可缺少.先学习了一种.经过測试好用.从别处学习的代码,稍修改了一下可选择是否支持识别大写和小写.直接上代码. import android.app.Acti ...

  8. java Socket使用详细解释

    客户/server通信模式, client需要主动创造和server Socket(套接字), server端收到了client的连接请求, 也会创建与客户连接的 Socket. Socket可看做是 ...

  9. 令人无限遐想的各种PCIe加速板卡

    声明 本文不涉及不论什么特定API,也不针对不论什么特定的厂商,可是仍然值得透露一点的是,某些加速板卡厂商的成功点和失败点恰恰都是在于其通用性,在这个人们依旧依赖专业板卡的时代,依旧将板卡视为解决专业 ...

  10. iOS相机去黑框

    自己定义相机的时候,调用系统的相机,因为相机的分辨率,会出现短小的矩形框,总会出现黑色边框,例如以下图: 假设想实现全屏相机的话,这样做就能够了: CALayer *viewLayer = self. ...