2014-11-04 58 views
1

的第一個字符場寬度我需要導入這種格式的文件:固定寬度的進口具有取決於線

PParent line  has some fields   with fixed width 
CChild line of Parent  Has fixed width with different widths than Parent 
CAnother Child   Fixed width consistent with Child-lines but not Parent 
PSecond Parent has more fields   again fixed width like other Parents 
CThird Child    This time belong to 2nd Parent as that's the preceding P-line 

因此,與被固定的列是依賴於第一字符的寬度作爲P對C.我沒有想出這個文件格式,但我需要處理它的吸盤...我目前正在讀它,像這樣(簡化):

create table #fixed (
    line varchar(max) 
) 
create table #link (
    id int identity, 
    parent int, 
    linetype char, 
    line varchar(max) 
) 

bulk insert #fixed from '\\unc\path\to\file.txt' 
with (
    fieldterminator = '' 
) 

insert into #link(linetype, line) 
select substring(line, 1, 1), line 
from #fixed 

update c set 
    c.parent = p.id 
from #link c 
cross apply (
    select top 1 id from #link 
    where linetype = 'P' and id < c.id 
    order by id desc 
) p 
where c.linetype = 'C' 

這可行,但我不喜歡它,我特別關心SQL Server插入到#link以任意順序排列,因此在update中丟失了正確的親子關係,特別是對於比這5行更大的文件。

但我沒有看到在這裏強制執行order的方法,或者使用使用格式文件的bulk insert導入此固定寬度與變化寬度格式。

編輯:一種方式我看到的是讀取該文件與openrowset(bulk '\\unc\file.txt', single_clob)和手動提取的線條。主要是我現在的問題是,我是否應該擔心insert into #link的這個順序,以保證轉換爲single_clob

+0

您是否能夠使用像SSIS這樣的技術?您可以讀取您的平面文件,並在讀取每行時爲其分配一個連續的行號。 – Greenspark 2014-11-04 16:57:11

+0

我僅限於這樣做,它是一塊T-SQL,可以在文件存儲和運行時進行存儲和運行通過另一個進程在文件夾中檢測到。 – funkwurm 2014-11-05 00:48:02

回答

1

您最初的做法是命中的機率問題,因爲

insert into #link(linetype, line) 
select substring(line, 1, 1), line 
from #fixed 

沒有ORDER BY條款;不能保證行將被插入#link的順序將反映它們在源文件中的順序。

一種方法是將一個標識列添加到#fixed

CREATE TABLE #fixed (
    id INT IDENTITY, 
    line VARCHAR(MAX) 
) 

因爲BULK INSERT將在它們出現在源文件中的命令行添加到目標表中。

這意味着您需要使用格式文件來啓用BULK INSERT以跳過IDENTITY列。

格式文件需要有內容類似:

9.0 
1 
1 SQLCHAR 0 99999 "\r\n" 2 line SQL_Latin1_General_CP1_CI_AS 

然後它可以與像

BULK INSERT #fixed FROM '\\unc\path\to\file.txt' 
WITH (
    FIELDTERMINATOR = '', 
    FORMATFILE = 'c:\temp\test.fmt' 
) 

(假設您保存格式文件到c命令使用: \ temp \ test.fmt)

然後,您可以使用已有的代碼進行小修改以使用來自#fixed的編號:

create table #link (
    id int , 
    parent int, 
    linetype char, 
    line varchar(max) 
) 

insert into #link(id, linetype, line) 
select id, substring(line, 1, 1), line 
from #fixed 
order by id 
+0

啊,我可以用格式文件告訴'bulk insert'跳過列,太棒了!我實際上調整了你的格式文件,讓它直接插入'#link'並跳過'id'和'parent'。這樣我就可以馬上得到我的'linetype'值。非常感謝。 – funkwurm 2014-11-05 16:28:55