2012-02-21 132 views
-1

我有一個名爲Spool的表,並且有一個名爲「NAME」的字段。該字段有一個由破折號分隔的7個值的字符串。基於另一個字段填充表中的字段的腳本

我必須在SQL Server中執行一個腳本,用短劃線分隔字符串「NAME」並記錄7個不同列中的7個值。

例如 名稱:ABCD-0123-ASD 在COLUMN1必須記錄ABCD,在列2:0123和欄3 ASD ..等 我希望我已經解釋=)

謝謝!

我正在使用SQL 2008,也是在我真正的問題中,我的字符串「NAME」中有7段,我必須將該字段的每個段放在7列中。

此外,我有表中的記錄n個至極適用該腳本=) 感謝您幫助


HI杜威我有這樣的:

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

請寫明您使用的SQL Server版本。 – 2012-02-21 01:34:57

+0

我正在使用SQL 2008 – user1222295 2012-02-21 16:09:42

回答

0

這並不嚴格需要一個CTE,但它保持SUBSTRING/CHARINDEX/etc的數量。計算降到最低。

;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 
+0

這項工作很好用2破折號,但如果有更多的破折號?我有6破折號作爲最大值,我有7列在同一個表中,我必須填寫此列,如果有字段名稱段。也可能是不是所有的列都可以填充的可能性 非常感謝您的幫助! =) – user1222295 2012-02-21 16:12:17

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

+0

將它們作爲行返回,但用戶希望它們插入到三個單獨的列中。你也不應該聲明'NCHAR'沒有長度 - 是NCHAR(1)'還是'NCHAR(30)'?另外,用於分割字符串的while循環方法在進入值的高端時是一種性能問題 - 請參閱http://sqlblog.com/blogs/aaron_bertrand/archive/2010/07/07/splitting-a -list-of-integers-another-roundup.aspx – 2012-02-21 02:12:05

+0

@AaronBertrand Thx,我想我誤讀了列定義;更正的解決方案已發佈。 – 2012-02-21 02:35:50

+0

這就是爲什麼沒有長度的'NCHAR'是一個壞主意:http:// sqlblog。com/blogs/aaron_bertrand/archive/2009/10/09/bad-habits-to-kick-declaring-varchar-without-length.aspx – 2012-02-21 02:42:11

相關問題