Problem

首先什么是动态列表?举个示例,假设你想输出以逗号分隔的IDs,如:

1,45,67,199,298

Solution

生成动态列表数据在我们生活场景中很常见,比如在 Dynamic PIVOT中,解决方案也有许多种,小陈知道的大体有:

  • Cursor-Based

  • XML-Based

  • Set-Based  

这三种方式,性能从低到高,有兴趣的看官可以自己看一下执行计划,分析数据。这里主要演示代码和思路为主。

Cursor-Based Approach

USE AdventureWorks2014;
GO DECLARE @nextid INT;
DECLARE @myIDs NVARCHAR(MAX) = '';
DECLARE idcursor CURSOR LOCAL FAST_FORWARD
FOR
SELECT TOP 10
SalesOrderID
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC; OPEN idcursor;
FETCH NEXT FROM idcursor INTO @nextid;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @myIDs = @myIDs + CAST(@nextid AS NVARCHAR) + N',';
FETCH NEXT FROM idcursor INTO @nextid;
END --SET @myIDs = SUBSTRING(@myIDs, 1, LEN(@myIDs) -1)
SET @myIDs = STUFF(@myIDs,LEN(@myIDs), 1, '')
SELECT @myIDs AS comma_separated_output;

分析:Cursor-Based 的思路是迭代想要的结果集,一次一次加上,最后去掉最后一个逗号。关于去掉最后一个逗号,或者刚开始的,小陈推荐使用 STUFF() 函数.

PS: 小陈觉得应该在T-SQL私房菜中加一道常见有用函数的菜谱。

XML-Based Approach

USE AdventureWorks2014;
GO DECLARE @myIDs NVARCHAR(MAX) = ''; SET @myIDs = STUFF(
(SELECT TOP 10
N',' + CAST(SalesOrderID AS NVARCHAR) AS [text()]
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC
FOR XML PATH('')), 1, 1, '');
/*
SET @myIDs = STUFF(
(SELECT TOP 10
',' + CAST(SalesOrderID AS NVARCHAR)
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC
FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
*/ SELECT @myIDs AS comma_separated_output;

分析:XML-Based 方式,初看之下觉得很复杂,不管怎么样,可读性上真的很差。对于看似复杂的T-SQL,小陈建议一步一步的分解,比如不了解XML AUTO PATH,可以移步MSDN查询一下。

PS:XML Reader不是免费的,在数据量大的情况下性能等同于迭代;这种方式易让别人觉得人你有奇技淫巧,一下下逼格就提高了。

Set-Based Approach

USE AdventureWorks2014;
GO DECLARE @myIDs NVARCHAR(MAX) = ''; SELECT TOP 10
@myIDs = @myIDs + N',' + CAST(SalesOrderID AS NVARCHAR)
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC SET @myIDs = STUFF(@myIDs, 1, 1, ''); SELECT @myIDs AS comma_separated_output;

分析:Set-Based 方式,不管是从性能上,还是从可读性上,都有很大的提升,也是小陈推荐的。

彩蛋

三种方式大体可以解决我们在T-SQL常见的问题,但有时候也会掉进坑里,有些也是动态列表不能解决的。

比如我们在写SP的时候,常把IDs作为参数传进去,然后在动态SQL中:orderid in @myIDs, 现实却是很骨感的……

T-SQL Recipes之生成动态列表数据的更多相关文章

  1. ajax获取动态列表数据后的分页问题

    ajax获取动态列表数据后的分页问题 这是我在写前台网站时遇到的一个分页问题,由于数据是通过ajax的方式来请求得到的,如果引入相应的js文件来做分页,假如只是静态的填放数据到列表各项内容中(列表条数 ...

  2. 开源 免费 java CMS - FreeCMS1.9 移动APP生成网站列表数据

    项目地址:http://www.freeteam.cn/ 生成网站列表数据 提取同意移动APP訪问的网站列表,生成json数据到/mobile/index.html页面. 从左側管理菜单点击生成网站列 ...

  3. 开源 免费 java CMS - FreeCMS1.9 移动APP生成栏目列表数据

    项目地址:http://www.freeteam.cn/ 生成栏目列表数据 提取当前管理网站下同意移动APP訪问的栏目列表,生成json数据到/site/网站文件夹/mobile/channels.h ...

  4. DB2存储过程实现查询表数据,生成动态SQL,并执行

    一.动态执行SQL PREPARE S1 FROM 'delete from test'; EXECUTE S1; 二.使用游标 DECLARE V_CURSOR CURSOR FOR SELECT ...

  5. Excel 数据导入SQL XML 自动生成表头

    去出差的时候应客户要求要要将Excel 文件内的数据批量导入到数据库中,而且有各种不同种类的表格,如果每一个表格多对应一个数据表的话, 按照正常的方法应该是创建数据表,创建数据库中映射的数据模型,然后 ...

  6. 【转】Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句

    原文链接:http://www.cnblogs.com/quanyongan/p/3152290.html 最近在使用Hibernate4中,发现两个很有奥秘的注解 @DynamicInsert 和  ...

  7. Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句

    最近在使用Hibernate4中,发现两个很有奥秘的注解 @DynamicInsert 和 @DynamicUpdate 如果是在配置文件的话那就是dynamic -insert 和 dynamic- ...

  8. ASP.NET实现二维码 ASP.Net上传文件 SQL基础语法 C# 动态创建数据库三(MySQL) Net Core 实现谷歌翻译ApI 免费版 C#发布和调试WebService ajax调用WebService实现数据库操作 C# 实体类转json数据过滤掉字段为null的字段

    ASP.NET实现二维码 using System;using System.Collections.Generic;using System.Drawing;using System.Linq;us ...

  9. 在论坛中出现的比较难的sql问题:15(生成动态删除列语句 分组内多行转为多列)

    原文:在论坛中出现的比较难的sql问题:15(生成动态删除列语句 分组内多行转为多列) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路. 1.如果去掉这个临时表中合计为0 ...

随机推荐

  1. 初识Docker和Windows Server容器

    概览 伴随着Windows Server 2016 Technical Preview 3 (TP3)版本的发布,微软首次提供了Windows平台下地原生容器.它集成了Docker对Windows S ...

  2. 安卓log4k问题解决

    1.直接上代码 //log4k问题 public static void log(String tag, String str) { int index = 0; // 当前位置 int max = ...

  3. [Unity] Shader(着色器)之纹理贴图

    在Shader中,我们除了可以设定各种光线处理外,还可以增加纹理贴图. 使用 settexture 命令可以为着色器指定纹理. 示例代码: Shader "Sbin/ff2" { ...

  4. centos7安装activemq

    activemq下载地址,http://activemq.apache.org/download.html,下载后解压,进入bin,直接运行 activemq start bin/activemq s ...

  5. windows7下修改hosts文件无效解决办法(转)

    通常会为了开发方便.或者屏蔽掉一些恶意网站,我们会在hosts(c:\windows\system32\drivers\etc\hosts)文件中进行相应的域名指向,例:

  6. 【PHP开发篇】一个统计客户端商机提交的获取IP地址

    1.对客服提交数据的ip地址记录. 获取ip地址的方法: public function getIP() { global $ip; if (getenv("HTTP_X_REAL_IP&q ...

  7. Node.js Stream - 实战篇

    邹斌 ·2016-07-22 11:04 背景 前面两篇(基础篇和进阶篇)主要介绍流的基本用法和原理,本篇从应用的角度,介绍如何使用管道进行程序设计,主要内容包括: 管道的概念 Browserify的 ...

  8. 【Alpha版本】冲刺总结随笔

    项目预期计划 确定代码规范与编码原则. 根据原型设计,界面设计,搭建应用大致框架,完善控件,背景等的界面设计. 根据体系结构设计,完善界面跳转逻辑,确定功能模块,实现1.0版本功能. 重点完善需求说明 ...

  9. Effective C++ 33 避免遮掩继承而来的名称

    首先介绍一个原则LSP(Liskov Substitution Principle),如果Class D以Public方式继承Class B,则所有B对象可以派上用场的任何地方,D对象一样可以派上用场 ...

  10. Hadoop家族的各个成员

    官方定义:hadoop是一个开发和运行处理大规模数据的软件平台.核心词语是平台,也就是说我们有大量的数据,又有好几个电脑,我们知道应该把处理数据的任务分解到各个电脑上,但是不知道怎样分配任务,怎样回收 ...