字符串和关系格式的转化

在数据库开发过程中,字符串和关系表的转化是一项基本技能。当字符串中存在分隔符时,有时将其转换成关系表数据,和其他数据表进行join查询,出现这种情况,是因为没有遵守关系数据库的设计范式,没有把字符串拆分成原子项存储,也有可能是数据传参数;有时会遇到相反的情况,需要将关系表的相关数据拼接成一个字符串显示,或传参。

把格式化的字符串转化成关系格式,基本思路分为两种:

  • 利用TSQL的循环语句:每一次循环都插入到关系表变量或临时表中,这种思路是面向过程的编程;
  • 使用XML查询:先把字符串转化成XML格式,再利用XML的nodes()函数,把XML数据转化成关系数据;这种思路是面向集合的编程,建议采用XML查询实现;

把关系格式转化成字符串,基本思路分为两种:

  • 利用TSQL的游标,对字符串执行累加连接,这种思路是面向过程的编程;
  • 利用XML查询的for xml path子句,把关系格式转化成字符串;这种思路是面向集合的编程,建议采用XML查询实现;

一,将字符串转换成表

先把字符串转换成XML格式,再利用XML的nodes()函数,把XML数据转化成关系数据,这种实现方式性能快,代码简洁,

declare @separator varchar(10)
declare @str varchar(max)

set @separator=‘,‘
set @str=‘54,57,55,56,59‘

1,把字符串转化成节点值

每个子串都是节点值,只需要取出节点值,就可以把节点值转化成关系格式的列值

declare @xml xml
set @xml=convert(xml,‘<v>‘ + REPLACE(@str, @separator, ‘</v><v>‘) + ‘</v>‘)

SELECT ids=N.v.value(‘.‘, ‘int‘)
FROM @xml.nodes(‘/v‘) N(v)

2,把字符串转化成节点属性

每个子串都是节点的属性值,只需要取出节点的属性值,就可以把属性值转化成关系格式的列值

declare @xml xml
set @xml=convert(xml,‘<Item v=‘‘‘ + REPLACE(@str, @separator, ‘‘‘></Item><Item v=‘‘‘) + ‘‘‘></Item>‘)

SELECT ids=N.v.value(‘@v‘, ‘int‘)
FROM @xml.nodes(‘/Item‘) N(v)

3,内置表值函数(string_split)

SQL Server 2016 新增一个表值函数string_split,用于按照分隔符将字符串分割成表值数据,返回的字段名是Value

STRING_SPLIT ( string , separator )  

二,将表数据拼接成字符串

有以下数据表,有两列:ID和txt,ID值有重复,而txt是文本数据;

create table dbo.test
(
ID int,
txt varchar(10)
)

把ID字段相同的txt字段的值拼接成字符串显示

select ID
    ,(select a.txt+‘‘ from dbo.test a where a.ID=t.ID for xml path(‘‘)) as descr
from dbo.test t
group by ID

三,奇巧淫技

在master数据库中,存在一个系统视图:master.dbo.spt_values,该视图包含从0到2047的所有数字,利用这个特性,可以把特定长度的字符串转化成关系格式,实现的代码如下:

;with cte_numbers as
(
    select number
    from master.dbo.spt_values
    where type=‘p‘
        and number>0
)
select
    cast(substring(@str, n.number, charindex(@separator ,@str [email protected] ,n.number )-n.number)  as  nvarchar(4000)) as item
    --,n.number
 from cte_numbers n
 where n.number<=len(@str)+1
    and charindex(@separator,@[email protected],n.number)=n.number

对于该方法,要体会其代码的思路,通过数据序列,从数字1开始,逐个检测分隔符,对字符串进行分割操作,截取子字符串,从而把字符串转化成关系表;由于master.dbo.spt_values只有0到2047个顺序数字,在必要时,可以替换该系统视图,而使用自定义的数据序列表,以增加能够拆分的字符串长度。

在数据库开发中,实现字符串和关系格式的相互转化,我倾向于使用面向集合的查询,通过面向过程的编程思想来实现,思路直接,比较简单,在此就不再赘述了。

参考文档:

Why (and how) to split column using master..spt_values?

时间: 2024-10-13 22:47:28

字符串和关系格式的转化的相关文章

java,时间转时间戳的转换以及各种date格式的转化

package com.henry.test; import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map; import org.apache.commons.lang.StringUtils; import com.shopin.core.util.HttpClientUtil; public class test { /** * 说明: * @pa

黑马程序员-C语言基础:指针类型与指针和数组、字符串的关系

//指针变量就是用来存储地址的,只能存储地址 格式:  int  *p;  这个p为指针变量:指针变量占8个字节 类型是用来说明这个指针指向的类型: 比如上边的int代表这个指针变量会指向int类型的存储空间: int *p = &a;//这样一句可以写,此时的*只是一个标志,表示这个*只是表示p是个指针: *p = &a;//这样写就错了:此时*p表示取p指向的空间的值: 指针疑问:指针既然都占据8个字节,那么为什么要划分类型, 是因为当用*p指针取值或者赋值的时候,知道该取几个字节,比

android时间格式的转化,String,Date,long

long time=System.currentTimeMillis(); System.out.println(time); SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); java.util.Date d1=new Date(time); String now=format.format(d1); System.out.println(now); long t = 0; try { java.

js数字、字符串、数组之间的转化

1.数组转字符串 var a, b; a = new Array(0,1,2,3,4); b = a.join("-"); 2.字符串转数组 var s = "abc,abcd,aaa"; ss = s.split(","); 3.数字转字符串toString var i = 10; var s = i.toString(); 4.字符串转数字 parseInt(字符串) parseInt("ssss999"); //错误 输

iOS中ASCII字符串转UTF8格式

iOS中ASCII字符串转UTF8格式,可调用下面这个方法: -(NSString *)gb2312toutf8:(NSData *) data { NSStringEncoding enc =             CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); NSString *retStr = [[NSString alloc] initWithData:data encoding:e

浅谈:字符串、时间格式的转换

字符串与时间格式的转换 -----常用的方法:1.拼接字符串的格式[String类型的一些常用的方法]: 2.simpledateformat格式 3.Date格式 1.SimpleDateFormat的用法: 1.1常用的方法: format(Date);将给定Date格式化为日期/时间字符串,并将结果添加到给定的StringBuffer parse(String);解析字符串文本,生成Date类型 2.Date的用法: 3.String的用法: 3.输出当前的时间: Date d = new

java中各种时间格式的转化

http://www.chinaitpower.com/A/2005-01-14/104881.html 使用java.util.Calendar返回间隔天数   static int getDaysBetween (java.util.Calendar d1, java.util.Calendar d2) { if (d1.after(d2)) {  // swap dates so that d1 is start and d2 is end java.util.Calendar swap

如何识别一个字符串是否Json格式

前言: 距离上一篇文章,又过去一个多月了,近些时间,工作依旧很忙碌,除了管理方面的事,代码方面主要折腾三个事: 1:开发框架(一整套基于配置型的开发体系框架) 2:CYQ.Data 数据层框架(持续的更新,最近也加入了Sybase的支持) 3:工作流流程图设计器. 由于这三个方面都涉及到Json,所以就谈谈这些天在Json上花下的心思. 关于造轮子: 很多人对于造轮子都会有自己的看法,这里提一下个人的观点: 个人认为: 1:首要是要具备造轮子的能力,然后再讨论造不造与浪不浪.轮子与时间的问题.

js字符串转为日期格式

1. <script type="text/javascript"> //字符串转日期格式,strDate要转为日期格式的字符串 function getDate(strDate){ var date = eval('new Date(' + strDate.replace(/\d+(?=-[^-]+$)/, function (a) { return parseInt(a, 10) - 1; }).match(/\d+/g) + ')'); return date; }