我有一个名为Spool的表,并且有一个名为“NAME”的字段。该字段有一个字符串,其中7个值由破折号分隔。
我必须在SQL Server中执行一个脚本,用破折号分割字符串“NAME”并记录7个不同列中的七个值。
例如 姓名:abcd-0123-asd 在column1中必须记录abcd,在column2:0123和column3 asd ..等 我希望我已经解释了=)
谢谢!
我正在使用SQL 2008,在我的实际问题中,我的字符串“NAME”中有7个段,我必须将该字段的每个段放在7列中。
此外,我在表格中有n条记录,适用于该脚本=) 谢谢你的帮助
HI John Dewey我做到了:
Create FUNCTION [dbo].[SPReturnThreeFields] ( @str NVARCHAR(max), @delimiter NCHAR(1) )
AS
BEGIN
declare @strOriginal NVARCHAR(max), @f1 varchar(max), @f2 varchar(max), @f3 varchar(max), @f4 varchar(max),@f5 varchar(max),@f6 varchar(max),@f7 varchar(max), @bool int = 0;
-- Field 1
set @f1=(left(@str,CHARINDEX(@delimiter,@str,1)-1));
SET @str=RIGHT(@str,LEN(@str)-CHARINDEX(@delimiter,@str,1));
-- Field 2
set @f2=(left(@str,CHARINDEX(@delimiter,@str,1)-1));
SET @str=RIGHT(@str,LEN(@str)-CHARINDEX(@delimiter,@str,1));
-- Field 3
set @f3 = (left(@str,CHARINDEX(@delimiter,@str,1)-1));
SET @str=RIGHT(@str,LEN(@str)-CHARINDEX(@delimiter,@str,1));
set @f4 = (left(@str,CHARINDEX(@delimiter,@str,1)-1));
SET @str=RIGHT(@str,LEN(@str)-CHARINDEX(@delimiter,@str,1));
set @f5 = (left(@str,CHARINDEX(@delimiter,@str,1)-1));
set @bool = case when patindex('%' + @delimiter + '%' , @str) <> 0 then 0 else 1 end;
SET @str= case when @bool = 0 then RIGHT(@str,LEN(@str)-CHARINDEX(@delimiter,@str,1)) else @str end;
set @f6 = case when patindex('%' + @delimiter + '%' , @str) < 1 then case when @bool = 0 then @str else '' end else (left(@str,CHARINDEX(@delimiter,@str,1)-1)) end;
set @bool = case when patindex('%' + @delimiter + '%' , @str) <> 0 then 0 else 1 end;
SET @str= case when @bool = 0 then RIGHT(@str,LEN(@str)-CHARINDEX(@delimiter,@str,1)) else @str end;
set @f7 = case when patindex('%' + @delimiter + '%' , @str) < 1 then case when @bool = 0 then @str else '' end else (left(@str,CHARINDEX(@delimiter,@str,1)-1)) end;
--update dbo.Spool SET Segmento1 = @f1,Segmento2 = @f2,Segmento3 = @f3,Segmento4 = @f4, Segmento5 = @f5, Segmento6 = @f6, Segmento7 = @f7 where Nombre = @strOriginal;
END
GO
显然它工作正常,但如果我想在同一个表中进行更新,如何调用该函数或必须是存储过程呢? 谢谢你的帮助!
答案 0 :(得分:0)
这并不严格需要CTE,但它保留了SUBSTRING / CHARINDEX /等的数量。计算到最低限度。
;WITH x AS
(
SELECT
Name,
fdash = CHARINDEX('-', Name),
ldash = CHARINDEX('-', REVERSE(Name)),
slen = LEN(Name)
FROM dbo.Spool
-- WHERE clause goes here
)
INSERT dbo.OtherTable(Column1, Column2, Column3)
SELECT
Column1 = LEFT(Name, fdash - 1),
Column2 = SUBSTRING(Name, fdash + 1, slen - fdash - ldash),
Column3 = RIGHT(Name, ldash - 1)
FROM x;
这假设每个值都有两个破折号。如果你不能保证(例如它没有强制执行约束),你应该在上面放置一个where子句,或者如果有0,1或者>,则定义你想要做的事情。 2个破折号。 where子句将是:
WHERE LEN(Name) - LEN(REPLACE(Name, '-', '')) = 2
答案 1 :(得分:0)
这个表值函数将允许各种分隔符。
兼容性是SQL 2005 +
----------------------------------------
-- Define function
CREATE FUNCTION dbo.fnReturnThreeFields ( @str NVARCHAR(max), @delimiter NCHAR(1) )
RETURNS @retval TABLE(Field1 NVARCHAR(max), Field2 NVARCHAR(max), Field3 NVARCHAR(max))
AS
BEGIN
declare @f1 varchar(max), @f2 varchar(max), @f3 varchar(max);
-- Field 1
set @f1=(left(@str,CHARINDEX(@delimiter,@str,1)-1));
SET @str=RIGHT(@str,LEN(@str)-CHARINDEX(@delimiter,@str,1));
-- Field 2
set @f2=(left(@str,CHARINDEX(@delimiter,@str,1)-1));
-- Field 3
SET @f3=RIGHT(@str,LEN(@str)-CHARINDEX(@delimiter,@str,1));
insert into @retval values (@f1,@f2,@f3);
RETURN;
END
GO
----------------------------------------
-- define test tables
declare @table1 table(Name NVARCHAR(max));
declare @table2 table(Field1 NVARCHAR(max), Field2 NVARCHAR(max), Field3 NVARCHAR(max));
insert into @table1 values ('one-two-three')
, ('four-five-six')
, ('seven-eight-nine');
----------------------------------------
-- load parsed values into @table2, from @table1
insert into @table2
select p.*
from @table1 t
cross apply dbo.fnReturnThreeFields(t.Name,'-') p
----------------------------------------
-- see the results
select * from @table2;
GO
结果: