用于根据其他字段填充表中字段的脚本

时间:2012-02-21 00:53:19

标签: sql-server

我有一个名为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

显然它工作正常,但如果我想在同一个表中进行更新,如何调用该函数或必须是存储过程呢? 谢谢你的帮助!

2 个答案:

答案 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

结果:

enter image description here