各位达人,考你们一下字符串分割的问题

时间:2021-10-07 10:54:18
我想实现这样一个任务。有100个表,表名分别是a1,a2,a3…

…a100。有这样的一个字符串str_SQL= '1,2,3,4,5,6……

100'.现在想把这条字符串以","分成100 份,然后其中的一份,

按表名的循序写到a1,a2……a100中。例如,"1"写入表a1中,"2"

写入表a2中等等。我现在能把字符串分开,但是如何用一个函数

写到每个表中呢?以上操作想在700ms内完成。

附:字符串切割函数如下
/****** Object:  UserDefinedFunction [dbo].[f_Split]    

Script Date: 02/06/2009 19:43:44 ******/
SET QUOTED_IDENTIFIER ON
GO
-- 自定义字符串拆分函数 类似c#的string.split()方法
CREATE Function [dbo].[f_Split] 

@content varchar(8000), 
@seperator varchar(20) 

RETURNS @temp table 

Id int identity(1,1), 
Value varchar(8000) 

BEGIN 
declare @CurrIndex int, @NextIndex int 
select @CurrIndex = 1 
select @NextIndex = 1 
select @NextIndex=charindex(@seperator, @content) 
while (@NextIndex > 0) 
begin 
if (@NextIndex >= @CurrIndex+1) 
begin 
insert into @temp (Value) values (substring(@content, 

@CurrIndex, @NextIndex-@CurrIndex)) 
end 
select @CurrIndex = @NextIndex + 1 
select @NextIndex=charindex(@seperator, @content, 

@CurrIndex) 
end 
if @CurrIndex <= datalength(@content) 
insert into @temp (Value) values (substring(@content, 

@CurrIndex, datalength(@content)-@CurrIndex+1)) 
return 
END
调用的方式:select * from dbo.f_Split

('a,b,c,d,e,f,123',',')  

15 个解决方案

#1


动态拼接字符???

#2


构造一条动态sql语句

#3


未在下面的列表中列出的语句不能用在函数主体中。     
    
  赋值语句。   
    
    
  控制流语句。   
    
    
  DECLARE   语句,该语句定义函数局部的数据变量和游标。   
    
    
  SELECT   语句,该语句包含带有表达式的选择列表,其中的表达式将值赋予函数的局部变量。   
    
    
  游标操作,该操作引用在函数中声明、打开、关闭和释放的局部游标。只允许使用以   INTO   子句向局部变量赋值的   FETCH   语句;不允许使用将数据返回到客户端的   FETCH   语句。   
    
    
  INSERT、UPDATE   和   DELETE   语句,这些语句修改函数的局部   table   变量。   
    
    
  EXECUTE   语句调用扩展存储过程。

#4


用程序去做.不要直接用SQL语句.

#5


用动态语句。

#6


引用 4 楼 dawugui 的回复:
用程序去做.不要直接用SQL语句.
支持,sql不擅长处理逻辑问题。

#7


难吗?
IF OBJECT_ID('A1') IS NOT NULL DROP TABLE A1
IF OBJECT_ID('A2') IS NOT NULL DROP TABLE A2
IF OBJECT_ID('A3') IS NOT NULL DROP TABLE A3
GO
CREATE TABLE A1(COL1 VARCHAR(10))
CREATE TABLE A2(COL1 VARCHAR(10))
CREATE TABLE A3(COL1 VARCHAR(10))
GO
DECLARE @STR VARCHAR(8000),@TBNAME VARCHAR(50)
SELECT @STR='1,2,3'
--BEGIN INSERT
SELECT @STR=RTRIM(@STR)+','
WHILE CHARINDEX(',',@STR)>0
BEGIN
SELECT @TBNAME=LEFT(@STR,CHARINDEX(',',@STR)-1),@STR=STUFF(@STR,1,CHARINDEX(',',@STR),'')
EXEC('INSERT INTO A'+@TBNAME+'(COL1) SELECT '''+@TBNAME+'''')
END
SELECT * FROM A1
UNION ALL
SELECT * FROM A2
UNION ALL
SELECT * FROM A3
--END INSERT
/*
1
2
3
*/

#8


改成存储过程,指定规定格式字符串,表前缀,插入列名,未加入字符串格式、表前缀、列名验证
IF OBJECT_ID('A1') IS NOT NULL DROP TABLE A1
IF OBJECT_ID('A2') IS NOT NULL DROP TABLE A2
IF OBJECT_ID('A3') IS NOT NULL DROP TABLE A3
IF OBJECT_ID('PROC_MU') IS NOT NULL DROP PROCEDURE PROC_MU
GO
CREATE TABLE A1(COL1 VARCHAR(10))
CREATE TABLE A2(COL1 VARCHAR(10))
CREATE TABLE A3(COL1 VARCHAR(10))
GO
CREATE PROCEDURE PROC_MU
(@STR VARCHAR(8000),@FIRSTNAME VARCHAR(50),@COLNAME VARCHAR(50))
AS
BEGIN
DECLARE @TBNAME VARCHAR(50)
--SELECT @STR='1,2,3',@FIRSTNAME='A',@COLNAME='COL1'
--BEGIN INSERT
SELECT @STR=RTRIM(@STR)+','
WHILE CHARINDEX(',',@STR)>0
BEGIN
SELECT @TBNAME=LEFT(@STR,CHARINDEX(',',@STR)-1),@STR=STUFF(@STR,1,CHARINDEX(',',@STR),'')
EXEC('INSERT INTO '+@FIRSTNAME+@TBNAME+'('+@COLNAME+') SELECT '''+@TBNAME+'''')
END
END
GO
EXEC PROC_MU '1,2,3','A','COL1'
SELECT * FROM A1
UNION ALL
SELECT * FROM A2
UNION ALL
SELECT * FROM A3
--END INSERT
/*
1
2
3
*/

#9


declare @str varchar(8000)
declare @sql varchar(8000)
declare @i int
select @str = '1,2,3,4,5,6',@i= 1

select @str = @str+','

while charindex(',',@str) > 0 
begin
select @sql = 'insert into a'+ltrim(@i) + ' select '+substring(@str,1,charindex(',',@str)-1)
print @sql
--exec(@sql)

select @i = @i + 1
select @str = stuff(@str,1,charindex(',',@str),'')
end

#10


declare @i int,@var varchar(500)
set @var='q,w,e,r'
set @i=0
while 1=1
begin
declare @sql varchar(200)
set @sql='insert a'+ltrim(@i+1)+ ' select  '''+substring(@var+',',1,charindex(',',@var+',')-1)+''''
--print @sql
exec @sql

if @i=3 break; ---100个表就改成99

set @i=@i+1
set @var=right(@var,len(@var)- charindex(',',@var+','))
end

#11


guguda2008的方法挺好用的,基本上达到了我的效果,能不能再进一步细化一下呢,比如说我要以这个字符串str_SQL分出来的份数建立表,然后在向这些表内写入相对应的数据。这个存储过程怎么写呢?

#12


引用 10 楼 ldslove 的回复:
SQL code
declare @i int,@var varchar(500)
set @var='q,w,e,r'
set @i=0
while 1=1
begin
    declare @sql varchar(200)
    set @sql='insert a'+ltrim(@i+1)+ ' select  '''+substring(@var+',',1,charindex(……

  报了以下这些错误

服务器: 消息 2812,级别 16,状态 62,行 9
未能找到存储过程 'insert a1 select  'q''。
服务器: 消息 2812,级别 16,状态 62,行 9
未能找到存储过程 'insert a2 select  'w''。
服务器: 消息 2812,级别 16,状态 62,行 9
未能找到存储过程 'insert a3 select  'e''。
服务器: 消息 2812,级别 16,状态 62,行 9
未能找到存储过程 'insert a4 select  'r''。

#13


引用 11 楼 tulipcaicai 的回复:
guguda2008的方法挺好用的,基本上达到了我的效果,能不能再进一步细化一下呢,比如说我要以这个字符串str_SQL分出来的份数建立表,然后在向这些表内写入相对应的数据。这个存储过程怎么写呢?


我觉得你还是自己研究一下代码自己写的好,这样有变动自己好调

IF OBJECT_ID('A1') IS NOT NULL DROP TABLE A1
IF OBJECT_ID('A2') IS NOT NULL DROP TABLE A2
IF OBJECT_ID('A3') IS NOT NULL DROP TABLE A3
IF OBJECT_ID('PROC_MU') IS NOT NULL DROP PROCEDURE PROC_MU
GO
--CREATE TABLE A1(COL1 VARCHAR(10))
--CREATE TABLE A2(COL1 VARCHAR(10))
--CREATE TABLE A3(COL1 VARCHAR(10))
--GO
CREATE PROCEDURE PROC_MU
(@STR VARCHAR(8000),@FIRSTNAME VARCHAR(50),@COLNAME VARCHAR(50))
AS
BEGIN
DECLARE @TBNAME VARCHAR(50)
--SELECT @STR='1,2,3',@FIRSTNAME='A',@COLNAME='COL1'
--BEGIN INSERT
SELECT @STR=RTRIM(@STR)+','
WHILE CHARINDEX(',',@STR)>0
BEGIN
SELECT @TBNAME=LEFT(@STR,CHARINDEX(',',@STR)-1),@STR=STUFF(@STR,1,CHARINDEX(',',@STR),'')
EXEC('CREATE TABLE '+@FIRSTNAME+@TBNAME+'('+@COLNAME+' VARCHAR(10))
INSERT INTO '+@FIRSTNAME+@TBNAME+'('+@COLNAME+') SELECT '''+@TBNAME+'''')
END
END
GO
EXEC PROC_MU '1,2,3','A','COL1'
SELECT * FROM A1
UNION ALL
SELECT * FROM A2
UNION ALL
SELECT * FROM A3
--END INSERT
/*
1
2
3
*/

#14


引用 6 楼 ai_li7758521 的回复:
引用 4 楼 dawugui 的回复:
用程序去做.不要直接用SQL语句.
支持,sql不擅长处理逻辑问题。


我之所以要在mssql里处理这些就是想给前台分压,我的数据量有1000“份”,1 秒中写入一次,换句话说1秒中要数据库自己分割1000份再写入自己的表里。前台做这项工作太耗资源。不知道你有没有什么好办法,你说的我不大明白,或者你能说的更细一点么?

#15


问题解决了,哈哈

#1


动态拼接字符???

#2


构造一条动态sql语句

#3


未在下面的列表中列出的语句不能用在函数主体中。     
    
  赋值语句。   
    
    
  控制流语句。   
    
    
  DECLARE   语句,该语句定义函数局部的数据变量和游标。   
    
    
  SELECT   语句,该语句包含带有表达式的选择列表,其中的表达式将值赋予函数的局部变量。   
    
    
  游标操作,该操作引用在函数中声明、打开、关闭和释放的局部游标。只允许使用以   INTO   子句向局部变量赋值的   FETCH   语句;不允许使用将数据返回到客户端的   FETCH   语句。   
    
    
  INSERT、UPDATE   和   DELETE   语句,这些语句修改函数的局部   table   变量。   
    
    
  EXECUTE   语句调用扩展存储过程。

#4


用程序去做.不要直接用SQL语句.

#5


用动态语句。

#6


引用 4 楼 dawugui 的回复:
用程序去做.不要直接用SQL语句.
支持,sql不擅长处理逻辑问题。

#7


难吗?
IF OBJECT_ID('A1') IS NOT NULL DROP TABLE A1
IF OBJECT_ID('A2') IS NOT NULL DROP TABLE A2
IF OBJECT_ID('A3') IS NOT NULL DROP TABLE A3
GO
CREATE TABLE A1(COL1 VARCHAR(10))
CREATE TABLE A2(COL1 VARCHAR(10))
CREATE TABLE A3(COL1 VARCHAR(10))
GO
DECLARE @STR VARCHAR(8000),@TBNAME VARCHAR(50)
SELECT @STR='1,2,3'
--BEGIN INSERT
SELECT @STR=RTRIM(@STR)+','
WHILE CHARINDEX(',',@STR)>0
BEGIN
SELECT @TBNAME=LEFT(@STR,CHARINDEX(',',@STR)-1),@STR=STUFF(@STR,1,CHARINDEX(',',@STR),'')
EXEC('INSERT INTO A'+@TBNAME+'(COL1) SELECT '''+@TBNAME+'''')
END
SELECT * FROM A1
UNION ALL
SELECT * FROM A2
UNION ALL
SELECT * FROM A3
--END INSERT
/*
1
2
3
*/

#8


改成存储过程,指定规定格式字符串,表前缀,插入列名,未加入字符串格式、表前缀、列名验证
IF OBJECT_ID('A1') IS NOT NULL DROP TABLE A1
IF OBJECT_ID('A2') IS NOT NULL DROP TABLE A2
IF OBJECT_ID('A3') IS NOT NULL DROP TABLE A3
IF OBJECT_ID('PROC_MU') IS NOT NULL DROP PROCEDURE PROC_MU
GO
CREATE TABLE A1(COL1 VARCHAR(10))
CREATE TABLE A2(COL1 VARCHAR(10))
CREATE TABLE A3(COL1 VARCHAR(10))
GO
CREATE PROCEDURE PROC_MU
(@STR VARCHAR(8000),@FIRSTNAME VARCHAR(50),@COLNAME VARCHAR(50))
AS
BEGIN
DECLARE @TBNAME VARCHAR(50)
--SELECT @STR='1,2,3',@FIRSTNAME='A',@COLNAME='COL1'
--BEGIN INSERT
SELECT @STR=RTRIM(@STR)+','
WHILE CHARINDEX(',',@STR)>0
BEGIN
SELECT @TBNAME=LEFT(@STR,CHARINDEX(',',@STR)-1),@STR=STUFF(@STR,1,CHARINDEX(',',@STR),'')
EXEC('INSERT INTO '+@FIRSTNAME+@TBNAME+'('+@COLNAME+') SELECT '''+@TBNAME+'''')
END
END
GO
EXEC PROC_MU '1,2,3','A','COL1'
SELECT * FROM A1
UNION ALL
SELECT * FROM A2
UNION ALL
SELECT * FROM A3
--END INSERT
/*
1
2
3
*/

#9


declare @str varchar(8000)
declare @sql varchar(8000)
declare @i int
select @str = '1,2,3,4,5,6',@i= 1

select @str = @str+','

while charindex(',',@str) > 0 
begin
select @sql = 'insert into a'+ltrim(@i) + ' select '+substring(@str,1,charindex(',',@str)-1)
print @sql
--exec(@sql)

select @i = @i + 1
select @str = stuff(@str,1,charindex(',',@str),'')
end

#10


declare @i int,@var varchar(500)
set @var='q,w,e,r'
set @i=0
while 1=1
begin
declare @sql varchar(200)
set @sql='insert a'+ltrim(@i+1)+ ' select  '''+substring(@var+',',1,charindex(',',@var+',')-1)+''''
--print @sql
exec @sql

if @i=3 break; ---100个表就改成99

set @i=@i+1
set @var=right(@var,len(@var)- charindex(',',@var+','))
end

#11


guguda2008的方法挺好用的,基本上达到了我的效果,能不能再进一步细化一下呢,比如说我要以这个字符串str_SQL分出来的份数建立表,然后在向这些表内写入相对应的数据。这个存储过程怎么写呢?

#12


引用 10 楼 ldslove 的回复:
SQL code
declare @i int,@var varchar(500)
set @var='q,w,e,r'
set @i=0
while 1=1
begin
    declare @sql varchar(200)
    set @sql='insert a'+ltrim(@i+1)+ ' select  '''+substring(@var+',',1,charindex(……

  报了以下这些错误

服务器: 消息 2812,级别 16,状态 62,行 9
未能找到存储过程 'insert a1 select  'q''。
服务器: 消息 2812,级别 16,状态 62,行 9
未能找到存储过程 'insert a2 select  'w''。
服务器: 消息 2812,级别 16,状态 62,行 9
未能找到存储过程 'insert a3 select  'e''。
服务器: 消息 2812,级别 16,状态 62,行 9
未能找到存储过程 'insert a4 select  'r''。

#13


引用 11 楼 tulipcaicai 的回复:
guguda2008的方法挺好用的,基本上达到了我的效果,能不能再进一步细化一下呢,比如说我要以这个字符串str_SQL分出来的份数建立表,然后在向这些表内写入相对应的数据。这个存储过程怎么写呢?


我觉得你还是自己研究一下代码自己写的好,这样有变动自己好调

IF OBJECT_ID('A1') IS NOT NULL DROP TABLE A1
IF OBJECT_ID('A2') IS NOT NULL DROP TABLE A2
IF OBJECT_ID('A3') IS NOT NULL DROP TABLE A3
IF OBJECT_ID('PROC_MU') IS NOT NULL DROP PROCEDURE PROC_MU
GO
--CREATE TABLE A1(COL1 VARCHAR(10))
--CREATE TABLE A2(COL1 VARCHAR(10))
--CREATE TABLE A3(COL1 VARCHAR(10))
--GO
CREATE PROCEDURE PROC_MU
(@STR VARCHAR(8000),@FIRSTNAME VARCHAR(50),@COLNAME VARCHAR(50))
AS
BEGIN
DECLARE @TBNAME VARCHAR(50)
--SELECT @STR='1,2,3',@FIRSTNAME='A',@COLNAME='COL1'
--BEGIN INSERT
SELECT @STR=RTRIM(@STR)+','
WHILE CHARINDEX(',',@STR)>0
BEGIN
SELECT @TBNAME=LEFT(@STR,CHARINDEX(',',@STR)-1),@STR=STUFF(@STR,1,CHARINDEX(',',@STR),'')
EXEC('CREATE TABLE '+@FIRSTNAME+@TBNAME+'('+@COLNAME+' VARCHAR(10))
INSERT INTO '+@FIRSTNAME+@TBNAME+'('+@COLNAME+') SELECT '''+@TBNAME+'''')
END
END
GO
EXEC PROC_MU '1,2,3','A','COL1'
SELECT * FROM A1
UNION ALL
SELECT * FROM A2
UNION ALL
SELECT * FROM A3
--END INSERT
/*
1
2
3
*/

#14


引用 6 楼 ai_li7758521 的回复:
引用 4 楼 dawugui 的回复:
用程序去做.不要直接用SQL语句.
支持,sql不擅长处理逻辑问题。


我之所以要在mssql里处理这些就是想给前台分压,我的数据量有1000“份”,1 秒中写入一次,换句话说1秒中要数据库自己分割1000份再写入自己的表里。前台做这项工作太耗资源。不知道你有没有什么好办法,你说的我不大明白,或者你能说的更细一点么?

#15


问题解决了,哈哈