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

原文:使用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' 

时间: 2024-10-27 04:43:18

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

SQL Server中如何动态行转列

SQL Server 动态行转列(参数化表名.分组列.行转列字段.字段值) 一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 实现代码(SQL Codes) 方法一:使用拼接SQL,静态列字段: 方法二:使用拼接SQL,动态列字段: 方法三:使用PIVOT关系运算符,静态列字段: 方法四:使用PIVOT关系运算符,动态列字段: 扩展阅读一:参数化表名.分组列.行转列字段.字段值: 扩展阅读二:在前面的基础上加入条件过滤: 参考文献(Refe

通过非动态SQL语句在SQL Server中执行动态查询

问题: 我尝试在一个存储过程中传递一系列以逗号划定界限的值,以限制结果集.但是无论什么时候,我在 IN子句中使用变量,都会得到错误信息.是否存在一种不执行动态SQL语句也能完成查询的方式呢? 专家解答: 这里存在一种不执行动态SQL语句也能完成查询的方式,但是首先让我们来探究这个问题.我将在以下 例子中运用AdventureWorks数据库. 在你只有一个值的时候,执行将不会有什么问题. Declare @ManagerIDs Varchar(100) Set @ManagerIDs = '3'

请教SQL Server 2000下动态SQL中的赋值问题

问题描述 目前在写一个存储过程,希望能动态传入数据表名@seedTable然后操作对应数据表:create procedure deleteSeed(@seedTable varchar(255),@url varchar(255))asdeclare @deleteSql varchar(255);declare @updateSql varchar(255);declare @selectSql varchar(255);declare @length int;beginset @delet

InfoPath开发实战(3):获取SQL Server中的数据

本节的内容: 如何在InfoPath中使用数据连接来从SQL Server数据库中获取数据 如何通过代码来修改数据连接中的SQL查询 在开始设计InfoPath表单之前,先准备一个数据库,InfoPath支持两种数据库连接: Microsoft Office Access数据库(.mdb文件或.accdb文件) Microsoft SQL Server数据库 需要注意的是,InfoPath虽然支持SQL Server Express数据库,但却不支持以文件的形式连接SQL Server Expr

【mybatis深度历险系列】mybatis中的动态sql

最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下.在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输出映射,今天这篇博文,小编主要来简单的介绍一下mybatis中的动态sql,有的小伙伴会问,既然有动态sql,那是不是也应该存在静态sql,答案是肯定的.那么什么是静态sql呢,静态sql语句一般用于嵌入式sql应用中,在程序运行之前,sql语句必须是确定的,例如sql语句中涉及的列名和表名必须是存

sql server中如何将相同货物的两条数据的数量相加合成一条替代原始数据

问题描述 sql server中如何将相同货物的两条数据的数量相加合成一条替代原始数据 表中如图所示两条数据,按照mh,有相同的,则将两条数据的数量相加合并为一条,没有相同则不变,表中mh相同最多只有2条.怎么样得到 mh sl dw ck A2 100 A A 解决方案 select mh,dw,ck,sum(sl) from xxx group by mh,dw,ck 这样汇总出一个新的数据,用这个数据替换你原有的就好了 还可以将这些数据 select into 到一个新表,然后删除旧表,再

SQL Server中XML与JSON应用比较

title: SQLServer · 特性分析 · SQL Server中XML与JSON应用比较 author: 石沫 背景 SQL Server是一种强大的数据库引擎,不仅性能卓越,稳定,功能还很强大,SQL Server 2016中已经支持JSON.这让我想到以前工作中经常使用的SQL XML,也对比一下他们几个关键领域的应用方法.这两种SQL特性,在实际的工作中也是常用的功能,特别是JSON在最近发展非常火爆,SQL Server也不落后,很快就在SQL Server2016支持. 广义

SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题

用户定义函数(UDF)分类       SQL SERVER中的用户定义函数(User Defined Functions 简称UDF)分为标量函数(Scalar-Valued Function)和表值函数(Table-Valued Function).其中表值函数又分为Inline table-valued functions和Multistatement table-valued functions.     用户定义函数(UDF)在 SQL Server 中发挥重要的作用.用户定义函数可以

SQLServer · 特性分析 · SQL Server中XML与JSON应用比较

title: SQLServer · 特性分析 · SQL Server中XML与JSON应用比较 author: 石沫 背景 SQL Server是一种强大的数据库引擎,不仅性能卓越,稳定,功能还很强大,SQL Server 2016中已经支持JSON.这让我想到以前工作中经常使用的SQL XML,也对比一下他们几个关键领域的应用方法.这两种SQL特性,在实际的工作中也是常用的功能,特别是JSON在最近发展非常火爆,SQL Server也不落后,很快就在SQL Server2016支持. 广义