2014-06-23 137 views
2

增加值我有一個表數據的幾行是這樣的:從Col1分割字符串和

16 W:\2-Work\ALBO\00_Proposal\ALxO_Amendement #1_20091022_signed.pdf 
17 W:\2-Work\ALBO\00_Proposal\Level1\ALBO_Amendment #1_20110418.docx 
18 W:\2-Work\ALBO\00_Proposal\A\BR\T\X_#1_20110418_final.docx 
19 W:\2-Work\ALBO\MyOptionl\AO_Amendment_2 August 2013.docx 

我創建列Col10

我想每個值分開與分隔符'\'

的想法是對每列:

Col1 | Col2 | Col3 | Col4 | Col5 |etc... 

W: 2-Work ALBO 00_Proposal ALxO_Amendement #1_20091022_signed.pdf 

我知道如何使用charindexsubstring,但'\'的數量在每行(8500行)上不同。

你能幫我嗎?

我使用Microsoft SQL Server 2012

非常感謝您

編輯2014年6月24日

我的目標是生成的完整路徑和分離路徑的XML。

其實,這裏是我的想法:

1 - 識別所有的ID在一個臨時表做循環

- 評申報表UNE節奏 申報表@IdTable( ID INT, SRC爲nvarchar(MAX))

- 談injecte TOUS LES ID existant德拉表 INSERT INTO @IdTable(ID,SRC) 選擇ID,從樺林

SRC

--on聲明L'ID德首張烯commencant帕樂加微型 聲明@id INT =(從選擇分鐘ALBO(ID))

--Tnat qu'il reste DES ID上繼續拉仿羔皮呢 而@id不是null 從@IdTable開始

打印@Id 選擇@id =分鐘(ID),其中ID> @id 端 --Fin德拉仿羔皮呢DES ID

2 - 分割每行和更新列(Colx => Clolumns之前已經創建) This code shoul d放入我之前的循環中。

聲明@products varchar(max)='W:\ 2-Work \ ALBO \ 13_WP Reporting \ 13_07_Monthly reports \ 13_07_01 Archives \ 2012 \ 201211 \ Draft \ ALBO-MR-201211 \ gp_scripts \ v1 \ Top10_duree_final。TXT」 聲明@individual VARCHAR(最大)= NULL

WHILE LEN(@products)> 0 BEGIN IF PATINDEX( '%\%',@產品)> 0 BEGIN SET = @individual SUBSTRING( @products,0,PATINDEX( '%\%',@品)) 選擇@individual - 我必須做出和更新與ID

SET @products = SUBSTRING(@products, LEN(@individual + '\') + 1, 
               LEN(@products)) 
END 
ELSE 
BEGIN 
    SET @individual = @products 
    SET @products = NULL 
    print @individual 
END 

END

+6

這是不一個好的桌子設計。你想做什麼? –

+0

您可以通過「\」創建一個函數來分割數據,併爲每一行返回一個表格,然後使用分割函數中的插入語句將col1中的表格插入到col10中。嘗試編寫代碼來實現上述內容,以免遇到我們在這裏的問題! :) – Murtaza

+0

你是不是隻是用''替換'\'? –

回答

0

正如其他人所說,這可能不是做事情的最好方法,如果你解釋什麼你會做的結果它可能會幫助我們提供更好的選擇

[此外,由於某些原因下面的代碼的顏色顯示奇怪,所以複製並粘貼到您的Sql服務器,以便更好地看到它]

drop table #Path 

create table #Path (item bigint,location varchar(1000)) 

insert into #Path 
select 16 ,'W:\2-Work\ALBO\00_Proposal\ALxO_Amendement #1_20091022_signed.pdf' union 
select 17 ,'W:\2-Work\ALBO\00_Proposal\Level1\ALBO_Amendment #1_20110418.docx' union 
select 18 ,'W:\2-Work\ALBO\00_Proposal\A\BR\T\X_#1_20110418_final.docx' union 
select 19 ,'W:\2-Work\ALBO\MyOptionl\AO_Amendment_2 August 2013.docx' 


select * from #Path; 


with Path_Expanded(item,subitem,location, start, ending, split) 
as(
select item 
    , 1 --subitem begins at 1 
    , location -- full location path 
    , 0 --start searching the file from the 0 position 
    , charindex('\',location) -- find the 1st '\' charactor 
    , substring(location,0,charindex('\',location)) --return the string from the start position, 0, to the 1st '\' charactor 

from #Path 
union all 
select item 
    , subitem+1 --add 1 to subitem 
    , location -- full location path 
    , ending+1 -- start searching the file from the position after the last '\' charactor 
    , charindex('\',location,ending+1)-- find the 1st '\' charactor that occurs after the last '\' charactor found 
    , case when charindex('\',location,ending+1) = 0 then substring(location,ending+1,1000) --if you cant find anymore '\', return everything else after the last '\' 
      else substring(location,ending+1, case when charindex('\',location,ending+1)-(ending+1) <= 0 then 0 
      else charindex('\',location,ending+1)-(ending+1) end)--returns the string between the last '\' charactor and the next '\' charactor 
      end 

from Path_Expanded 
where ending > 0 --stop once you can't find anymore '\' charactors 
) 


--pivots the results 
select item 
    , max(case when subitem = 1 then split else '' end) as col1 
    , max(case when subitem = 2 then split else '' end) as col2 
    , max(case when subitem = 3 then split else '' end) as col3 
    , max(case when subitem = 4 then split else '' end) as col4 
    , max(case when subitem = 5 then split else '' end) as col5 
    , max(case when subitem = 6 then split else '' end) as col6 
    , max(case when subitem = 7 then split else '' end) as col7 
    , max(case when subitem = 8 then split else '' end) as col8 
    , max(case when subitem = 9 then split else '' end) as col9 
    , max(case when subitem = 10 then split else '' end) as col10 

from Path_Expanded 
group by item 

你可能更喜歡有自己的行上的每個文件夾,如果是用下面的查詢代替樞紐部以上,而不是

select item 
     , subitem 
     , location 
     , split from Path_Expanded where item = 16 
+0

我的目標是創建一個XML寬度的所有'爆炸'信息並保持原始路徑。 – Chris

+0

非常感謝你! – Chris

0

下面的查詢會得到什麼你正在尋找;正如其他人所指出的那樣,這不是一個特別好的設計。例如,當您正在查找文件名並且每次都在不同的列中時會發生什麼?

無論如何,這會做你要求什麼(甚至是你想要的):

-- Test Data 
CREATE TABLE #FilePath (FileNumber INT IDENTITY(1,1), FilePath VARCHAR(1000)) 
INSERT INTO #FilePath (FilePath) 
SELECT 'W:\2-Work\ALBO\00_Proposal\ALxO_Amendement #1_20091022_signed.pdf' UNION 
SELECT 'W:\2-Work\ALBO\00_Proposal\Level1\ALBO_Amendment #1_20110418.docx' UNION 
SELECT 'W:\2-Work\ALBO\00_Proposal\A\BR\T\X_#1_20110418_final.docx' UNION 
SELECT 'W:\2-Work\ALBO\MyOptionl\AO_Amendment_2 August 2013.docx' 
GO 

-- Numbers CTE 
WITH Numbers AS 
(
    SELECT n = 1 
    UNION ALL 
    SELECT n + 1 
    FROM Numbers 
    WHERE n+1 <= 1000 -- set this to the maximum length of your file path 
) 

SELECT 
    FilePath, 
    [1] AS Col1, 
    [2] AS Col2, 
    [3] AS Col3, 
    [4] AS Col4, 
    [5] AS Col5, 
    [6] AS Col6, 
    [7] AS Col7, 
    [8] AS Col8, 
    [9] AS Col9, 
    [10] AS Col10 
FROM 
    (
    SELECT 
     FilePath, 
     ROW_NUMBER() OVER (PARTITION BY FilePath ORDER BY n) RowNum, 
     CAST(LTRIM(RTRIM(NULLIF(SUBSTRING('\' + FilePath + '\' , n , CHARINDEX('\' ,  '\' + FilePath + '\' , n) - n) , ''))) AS VARCHAR(1000)) FolderName 
    FROM Numbers, #FilePath 
    WHERE 
     n <= Len('\' + FilePath + '\') AND SubString('\' + FilePath + '\' , n - 1, 1) = '\' AND 
     CharIndex('\' , '\' + FilePath+ '\' , n) - n > 0 
)P 
PIVOT 
    (MAX(FolderName) FOR RowNum IN 
    ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10]) 
    ) UP 
OPTION (MAXRECURSION 1000)-- set this to the maximum length of your file path 


-- Clean up 
DROP TABLE #FilePath 
0

一種方法(去愚弄):

;with T(ordinal, path, starts, pos) as (
    select 1, path, 1, charindex('\', path) from #tbl 
    union all 
    select ordinal + 1, path, pos + 1, charindex('\', path, pos + 1) 
    from t where pos > 0 
) 
select [1],[2],[3],[4],[5],[6],[7],[8],[9],[10] from (
    select 
     ordinal, path, substring(path, starts, case when pos > 0 then pos - starts else len(path) end) token 
    from T 
) T2 
pivot (max(token) for ordinal in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) T3