我们日常开发中,不管是表设计问题抑或是其他什么原因,或多或少都会遇到一张表中有一个字段存储的内容是用逗号隔开的列表。

  具体效果如下图:

  ------》

从左边图转换成右边图,像这种需求,我们难免会遇到。

今天我写了个存储过程来解决这种问题。主要方式是利用master..spt_values表。

具体存储过程如下:

-- Author:        LHM
-- Create date: 2015-01-10
-- Description: 把表中某一个列按照逗号拼接列表
--示例: EXEC [Sp_StringsToTable] 'AgentId','UserId','Bse_GeneralAgent',''
-- =============================================
CREATE PROCEDURE [dbo].[Sp_StringsToTable]
@ColumnId VARCHAR() ,
@ColumnName VARCHAR(2047) ,
@TableName NVARCHAR(100) ,
@Filter VARCHAR(1000)=''
AS
BEGIN
DECLARE @sql VARCHAR(500)
IF (@Filter<>'')
BEGIN
SET @Sql='
select '+@ColumnId+', RTRIM( LTRIM( substring('+@ColumnName+'+'','',a.number,charindex('','','+@ColumnName+'+'','',a.number+1)-a.number)) ) Id
from master..spt_values a,'+@TableName+' b
where '+@Filter+' and a.type=''p'' and substring('',''+'+@ColumnName+',a.number,1)='','' ' END
ELSE
BEGIN
SET @Sql='
select '+@ColumnId+', RTRIM( LTRIM( substring('+@ColumnName+'+'','',a.number,charindex('','','+@ColumnName+'+'','',a.number+1)-a.number)) ) Id
from master..spt_values a,'+@TableName+' b
where a.type=''p'' and substring('',''+'+@ColumnName+',a.number,1)='','' '
END
EXEC (@Sql)
END

这个存储过程有一个限制:就是@ColumnName的值不能超过2047个字节,也就是说,图中的UserId的字段里面的内容不能超过2047个字符。

原因就是因为master..spt_values表的限制。大家可以在数据库中执行 SELECT * FROM  master..spt_values type='p' 就可以知道限制的原因了。

有兴趣的朋友可以 试着建立如图的表

CREATE TABLE [dbo].[Bse_GeneralAgent](
[AgentId] [int] IDENTITY(1,1) NOT NULL,
[UserId] [varchar](max) NULL,
CONSTRAINT [PK_Bse_GeneralAgent] PRIMARY KEY CLUSTERED
(
[AgentId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO

随意添加一些测试数据进行测试 。只需执行存储过程

EXEC [Sp_StringsToTable] 'AgentId','UserId','Bse_GeneralAgent',''

希望给遇到此类需求的朋友带来帮助,谨此记录。

 如果觉得有用,可以推荐一下,谢谢。

------------------------------------------------------------以下是指尖流淌的思路,感谢---------------------------------------------------

-- Author:        LHM
-- Create date: 2015-01-10
-- Description: 把表中某一个列按照逗号拼接列表
--示例: EXEC Sp_StringsToTableExtend 'AgentId','UserId','Bse_GeneralAgent'
-- =============================================
CREATE PROCEDURE [dbo].Sp_StringsToTableExtend
@ColumnId VARCHAR(MAX) ,
@ColumnName VARCHAR(MAX) ,
@TableName NVARCHAR(100)
AS
BEGIN
DECLARE @sql VARCHAR(500)
SET @Sql='SELECT A.'+@ColumnId+' , B.StrColumn
FROM (SELECT StrXml = CONVERT(XML, ''<root><v>''+REPLACE('+@ColumnName+', '','', ''</v><v>'')+''</v></root>'') , '+@ColumnId+' , UserId FROM '
+@TableName+' ) A OUTER APPLY (SELECT StrColumn = N.v.value(''.'', ''nvarchar(40)'') FROM A.StrXml.nodes(''/root/v'') N (v) ) B '
EXEC (@Sql)
END
GO

[原创]SQL 把表中字段存储的逗号隔开内容转换成列表形式的更多相关文章

  1. SQL 把表中字段存储的逗号隔开内容转换成列表形式

    原文:[原创]SQL 把表中字段存储的逗号隔开内容转换成列表形式 我们日常开发中,不管是表设计问题抑或是其他什么原因,或多或少都会遇到一张表中有一个字段存储的内容是用逗号隔开的列表. 具体效果如下图: ...

  2. [原创]SQL 把表中某一个列按照逗号拼接成一行

    在我们开发的过程中,难免遇到一种场景,把某个表中的的某个列的值拼接成用逗号隔开的一行数据 如图:我们把UserId列拼接成一行数据 -------> 为此我写了一个存储过程来解决此类问题. -- ...

  3. SQL将表中某一类型的一列拼接成一行

    SELECT TypeName ,(SELECT ','+ UserName FROM [ContainerMembers] t WHERE TypeName= aa.TypeName FOR XML ...

  4. sql一个表中两个字段合并求和

    sql一个表中两个字段,合并求和 SELECT SUM(字段a+'.'+字段b) as total  from TABLE

  5. SQL批量更新数据库中所有用户数据表中字段类型为tinyint为int

    --SQL批量更新数据库中所有用户数据表中字段类型为tinyint为int --关键说明:--1.从系统表syscolumns中的查询所有xtype='48'的记录得到类型为[tinyint]的字段- ...

  6. 批量替换数据库中所有用户数据表中字段数据类型为char和varchar到nvarchar的脚本

    解决问题:字段类型为char的总是占用指定字节长度(末尾好多空白符号),varchar数据类型长度一个汉字占2个字节,内容存储为中文的字段个人建议全部使用nvarchar. 操作说明:打开SQL Se ...

  7. 在一个SQL Server表中的多个列找出最大值

    在一个SQL Server表中一行的多个列找出最大值 有时候我们需要从多个相同的列里(这些列的数据类型相同)找出最大的那个值,并显示 这里给出一个例子 IF (OBJECT_ID('tempdb..# ...

  8. SQL server 表中如何创建索引?

    SQL server 表中如何创建索引?看个示例,你就会了 use master goif db_id(N'zhangxu')is not nulldrop database zhangxugocre ...

  9. 关于数据库优化1——关于count(1),count(*),和count(列名)的区别,和关于表中字段顺序的问题

    1.关于count(1),count(*),和count(列名)的区别 相信大家总是在工作中,或者是学习中对于count()的到底怎么用更快.一直有很大的疑问,有的人说count(*)更快,也有的人说 ...

随机推荐

  1. 微软SaaS多租户解决方案

    微软SaaS多租户解决方案 docs.microsoft.com/en-us/azure/sql-database/saas-tenancy-app-design-patterns https://d ...

  2. Java中小数保留问题

    方式一: 四舍五入   double   f   =   111231.5585;   BigDecimal   b   =   new   BigDecimal(f);   double   f1  ...

  3. 【操作系统】总结五(I/O管理)

    输入输出管理本章主要内容: I/O管理概述(I/O控制方式.I/O软件层次结构)和I/O核心子系统(I/O调度概念.局速缓存与缓冲区.设备分配与回收.假脱机技术(SPOOLing)). 5.1 I/O ...

  4. Biology(湖南集训)

    题目大意:n个字符串,m个操作,可以插入字符串,也可以询问某T个字符串的最长后缀 题解:Trie+lca Trie树的插入与查询操作.把字符串反转就相当于求公共前缀. lca的深度就是公共前缀的长度. ...

  5. vscode: Visual Studio Code 常用快捷键【轉】

    主命令框 F1 或 Ctrl+Shift+P: 打开命令面板.在打开的输入框内,可以输入任何命令,例如: 按一下 Backspace 会进入到 Ctrl+P 模式 在 Ctrl+P 下输入 >  ...

  6. Fiddler的Java抓包

    代码处理 System.setProperty("http.proxySet", "true"); System.setProperty("http. ...

  7. loadsh学习

    由Underscore与Lodash的差异引发的思考:http://ju.outofmemory.cn/entry/106512 JavaScript工具库之Lodash Underscore和Lod ...

  8. Winform 自定义TabControl实现浏览器标签

    作者:Gavin(daisong.michelangelo@gmail.com) 时间: Nov, 2015 封面图片为Gavin原创,请勿未经允许私自引 最近因为工作需要,要做一个桌面浏览器,和大多 ...

  9. Python学习书籍推荐 中英对照

    Learn Python The Hard Way 笨办法学 python A Byte of Python 简明Python教程 初学者 英文版 Learning Python, 3rd Editi ...

  10. ror配置unicorn部署

    unicorn是目前在ror上比较流行的应用服务器,配合nginx用来直接部署rails程序,下面这种方式应该是共享socket,不断fork子进程,有点类似php-fpm的模式 安装unicorn ...