我想把这张表1(表1是分割字符串的来的)中的列分割后,再插到表2中,
请大家帮个忙想个方法,如果有范例更好
(再解释一次:我需要的是将一个字符串: ‘5,abc,aaa;6,cde,eee;7,gbf,ggg';这样的字符串分割后插到表里面,先分割";"号,在分割","),谢谢大家了
可不可以通过程序来做?
谢谢,不过我需要在sql中实现
@Mr.XHK: '5,abc,aaa;6,cde,eee;7,gbf,ggg' 固定吧?
@chenping2008: 嗯,字符串长度不固定,但分号之间的逗号是固定的
@Mr.XHK:
DECLARE @str VARCHAR(100) ; SET @str = '5,abc,aaa;6,cde,eee;7,gbf,ggg' ; DECLARE @s VARCHAR(100) ; DECLARE @sql VARCHAR(1000) ; SET @sql = '' ; DECLARE @sIndex INT ; DECLARE @eIndex INT ; SET @sIndex = 1 ; DECLARE @b BIT ; SET @b = 0 ; WHILE ( 1 = 1 ) BEGIN SET @eIndex = CHARINDEX(';', @str, @sIndex) ; IF ( @eIndex = 0 ) BEGIN SET @eIndex = LEN(@str) + 1 ; SET @b = 1 ; END SET @s = SUBSTRING(@str, @sIndex, @eIndex - @sIndex) ; SET @sIndex = @eIndex + 1 ; --PRINT @s ; DECLARE @sI INT ; DECLARE @eI INT ; DECLARE @ss VARCHAR(100) ; DECLARE @break BIT ; SET @break = 0 ; SET @sI = 1 ; SET @sql = @sql + 'insert into t values(' WHILE ( 1 = 1 ) BEGIN SET @eI = CHARINDEX(',', @s, @sI) ; IF ( @eI = 0 ) BEGIN SET @eI = LEN(@s) + 1 ; SET @break = 1 ; END SET @ss = SUBSTRING(@s, @sI, @eI - @sI) ; SET @sql = @sql + @ss + ',' SET @sI = @eI + 1 ; --PRINT @ss ; IF ( @break = 1 ) BREAK ; END SET @sql = SUBSTRING(@sql, 1, LEN(@sql) - 1) + ');' --PRINT @sql ; IF ( @b = 1 ) BEGIN BREAK END END PRINT @sql ;
@chenping2008: 3Q
写一个字符串分割函数,分割两次就行了
谢谢,割倒是好割啊,就是插不好插啊,我不知道怎么插啊,(汗!割...插...)
@Mr.XHK:
declare @s nvarchar(100),@str nvarchar(100) set @s='5,abc,aaa;6,cde,eee;7,gbf,ggg'
DECLARE CusCursor CURSOR FOR select col from dbo.f_splitStr(@s,';')
OPEN CusCursor
FETCH NEXT FROM CusCursor INTO @str
WHILE (@@FETCH_STATUS = 0)
BEGIN
declare @start1 int,@start2 int
declare @col1 nvarchar(100),@col2 nvarchar(100),@col3 nvarchar(100)
set @start1=charindex(',',@str)
set @col1=substring(@str,1,@start1-1)
set @start2=charindex(',',@str,@start1+1)
set @col2=substring(@str,@start1+1,@start2-@start1-1)
set @col3=substring(@str,@start2+1,LEN(@str)-@start2)
insert 表(列1,列2,列3) values(@col1,@col2,@col3)
--select @col1,@col2,@col3
FETCH NEXT FROM CusCursor INTO @str
END
CLOSE CusCursor
DEALLOCATE CusCursor
@chenping2008: 3Q
楼主这么快结贴了,下面这个方法开拓下使用SQL008的XML字段实现你的要求,
CREATE TABLE #tb ( id INT , culomns VARCHAR(MAX) , culomnsxml XML DEFAULT NULL ) CREATE TABLE #temp ( id INT , culomns VARCHAR(MAX) , culomnsxml XML DEFAULT NULL ) CREATE TABLE #result ( ID INT , NAME VARCHAR(50) , NOTE VARCHAR(50) ) INSERT INTO #tb ( id , culomns ) SELECT 1 , '5,abc,aaa;6,cde,eee;7,gbf,ggg' UNION SELECT 2 , '15,abc,aaa;16,cde,eee;17,gbf,ggg' UNION SELECT 3 , '25,abc,aaa;26,cde,eee;27,gbf,ggg' UNION SELECT 4 , '35,abc,aaa;36,cde,eee;37,gbf,ggg' UPDATE #tb SET culomnsxml = CONVERT(XML , '<root><v>' + REPLACE(a.culomns , ';' , '</v><v>') + '</v></root>') FROM #tb a SELECT id , culomns FROM #tb INSERT INTO #temp ( id , culomns ) SELECT id , cx FROM #tb a CROSS APPLY ( SELECT C.v.value ('.' , 'nvarchar(100)') cx FROM a.culomnsxml.nodes ('/root/v') C( v) ) b UPDATE #temp SET culomnsxml = CONVERT(XML , '<root><v>' + REPLACE(culomns , ',' , '</v><v>') + '</v></root>') FROM #temp a INSERT INTO #result ( ID , NAME , NOTE ) SELECT culomnsxml.value('(/root/v)[1]' , 'varchar(40)') , culomnsxml.value('(/root/v)[2]' , 'varchar(40)') , culomnsxml.value('(/root/v)[3]' , 'varchar(40)') FROM #temp SELECT * FROM #result DROP TABLE #tb DROP TABLE #temp DROP TABLE #result
执行结果如下:
ID NAME NOTE
5 abc aaa
6 cde eee
7 gbf ggg
15 abc aaa
16 cde eee
17 gbf ggg
25 abc aaa
26 cde eee
27 gbf ggg
35 abc aaa
36 cde eee
37 gbf ggg
呵呵,牛逼啊,往后还有很多sql的问题请教;以前太浅薄,太依赖程序处理,导致程序卡的要死,这几天才发现数据库处理数据能力的强大