是的,有這個工作的方式。將數據字段加載到MySQL用戶變量中,然後將表達式分配給實際列。
例如,代替:
(subject,predicate,object,provenance
做這樣的事情:
(subject, predicate, @field3, @field4)
SET object = CASE WHEN @field3 LIKE '"%"_%' THEN ... ELSE @field3 END
, provenance = CONCAT(CASE WHEN @field3 LIKE '"%"%_"' THEN ... ELSE '' END,@field4)
這只是一個大綱。很顯然,那些...
需要替換爲返回你想要分配到列字段值的部分適當的表達。 (這將是SUBSTRING,SUBSTRING_INDEX,INSTR,LOCATE,REPLACE等字符串函數的一些組合,並且您可能需要額外的WHEN結構來處理變體。檢查)。
如果在Unix或Linux運行,另一個選擇是使用一個命名管道和外部程序讀取該文件,執行需要的操作,並寫入命名管,在後臺運行。
例如
> mkfifo /tmp/mydata.pipe
> myprogram <myfile >/tmp/mydata.pipe 2>/tmp/mydata.err &
mysql> LOAD DATA LOCAL INFILE /tmp/mydata.pipe ...
隨訪
隨着輸入線路是這樣的:
abc def "Hello"@en klm .
給出FIELDS TERMINATED BY ' ' OPTIONALLY ENCLOSED BY '"'
field1 = 'abc'
field2 = 'def'
field3 = '"Hello"@en'
field4 = 'klm'
爲了測試的情況下,當Field3包含雙引號,與作爲f的第一個雙引號在字符串中IRST字符,我們可以用這樣的:
LIKE '"%"%'
,說的第一個字符是一個雙引號,後面的零個一個或多個字符,緊接着又雙引號,由零隨後再次一個或多個字符。
到了第二個雙引號之前拿到場3部分:
SUBSTRING_INDEX(@field3,'"',2)
爲了擺脫從領先的雙引號,即返回場3雙引號之間有什麼,你能做些什麼像這樣:
SUBSTRING_INDEX(SUBSTRING_INDEX(@field3,'"',2),'"',-1)
要獲得繼上雙引號中的字段3部分:
SUBSTRING_INDEX(SUBSTRING_INDEX(@field3,'"',-1)
(這些表達式假設有在字段3至多兩個雙引號)。
要針對第三列獲得的價值:
CASE
-- when field starts with a double quote and is followed by another double quote
WHEN @field3 LIKE '"%"%"'
-- return whats between the double quotes in field3
THEN SUBSTRING_INDEX(SUBSTRING_INDEX(@field3,'"',2),'"',-1)
-- otherwise return the entirety of field3
ELSE @field3
END
來獲取值被前置到第四列,當Field3包含兩個雙引號:
CASE
-- when field starts with a double quote and is followed by another double quote
WHEN @field3 LIKE '"%"%"'
-- return whats after the last double quote in field3
THEN SUBSTRING_INDEX(@field3,'"',-1)
-- otherwise return an empty string
ELSE ''
END
要前置一個到field4中,使用CONCAT
功能用TE CASE表達上述和field4中。
而這些都是我們所期待已插入到表中的值:如果LOAD DATA是不承認的行分隔符,因爲
column1 = 'abc'
column2 = 'def'
column3 = 'Hello'
column4 = '@enklm'
ANOTHER隨訪
它不會識別字段分隔符,那麼您必須放棄字段分隔符,並自己進行解析。將整行加載到用戶變量中,並解析。
例如
LINES TERMINATED BY '.\n'
(@line)
SET subject
= SUBSTRING_INDEX(@line,' ',1)
, predicate
= SUBSTRING_INDEX(SUBSTRING_INDEX(@line,' ',2),' ',-1)
, object
= CASE
WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(@line,' ',3),' ',-1) LIKE '"%'
THEN SUBSTRING_INDEX(SUBSTRING_INDEX(@line,'"',2),'"',-1)
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(@line,' ',3),' ',-1)
END
, provenance
= CASE
WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(@line,' ',3),' ',-1) LIKE '"%'
THEN SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(@line,'"',-1),' ',2),' ',-1)
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(@line,' ',4),' ',-1)
END
這將在您的示例數據的所有線路,由單個空格分隔的領域工作,在第三場匹配雙引號除外。
注意:SQL中用於字符串操作的可用函數會導致笨拙和尷尬的語法; SQL不是專門爲簡單的字符串操作而設計的。
答案已經處理了你正在做的任何事情,我只是建議您在嘗試將數據帶入數據庫之前先考慮其他方式來清理/規範化數據。有幾個ETL工具(有些是免費的!),可以幫助這個 – Noah