2009-12-17 98 views
2

我最近一直在學習F#和函數式編程。我發現一個非常有用的應用程序是使用一些關聯的ID爲CSV(或Excel表)生成數據加載的SQL插入。F#從CSV生成SQL

下面的代碼是我的結果,我相信我會發現在未來非常方便。我想其他人也可以從中受益,我歡迎建議,人們對收藏已經找到寶貴的其它腳本:

// Returns some dataload SQL for area mapping. 
open System 
open System.IO 

// Read and split CSV into lists 
let map_ngo_area = File.ReadAllLines(@"P:\MY_TABLE.csv") 
         |> Array.to_list 
         |> List.map(fun x -> (x.Split([|','|]) 
               |> Array.map(fun y -> y.Trim())) 
               |> Array.to_list) 

// Output Formatting function 
let format_sql_record = "INSERT INTO MyTable 
    (ID, REF1_ID, REF2_ID, CreatedUser, CreatedDateTime, LastModifiedUser, LastModifiedDateTime) 
    VALUES 
    ({0}, {1}, {2}, 'system', getDate(), 'system', getDate())" 

// Generate the SQL for the given list. 
let generate_sql list = list |> List.mapi(fun index row -> 
              match row with 
               | [ngo_id; area_id] -> String.Format(format_sql_record, ((int index)+1), ngo_id, area_id) |> printfn "%s" 
               | _ -> printfn "") 

// Main Execution 
map_ngo_area |> generate_sql |> ignore 

// End of program, pause to view console output. 
System.Console.ReadKey() |> ignore 

對提高我的F#代碼或程序有什麼建議?評論也很受歡迎,因爲我在這個範例中是相當新的,轉變的想法並不如我預期的那樣。

謝謝:)

回答

6

這裏有幾個建議:

  • 不要使用List.mapi與返回unit功能,因爲沒有太多可以用得到的unit list做。您應該使用List.iteri,這將允許您在主執行部分末尾省略|> ignore
  • 進一步,而不是讓generate_sql一次打印一個生成的行,最好生成一個字符串列表來代替。請注意,在這種情況下,您將返回使用List.mapi,因爲您應用的函數將返回每行的結果。
  • 使用F#的打印格式而不是String.Format。例如,而不是format_sql_record是一個字符串,擁有它是int->string->string->string類型的函數:let format_sql_record = sprintf "INSERT INTO ... VALUES (%i, %s, %s, ...)"
  • 取決於您使用F#的版本,你或許應該使用,而不是Array.to_list重命名功能Array.toList,因爲這是這個名字將在F#的最終版本中使用。
+0

真棒,謝謝KVB他們是一些偉大的祕訣! :) – Russell 2009-12-17 05:24:19

4

您可以在陣列中使用模式匹配太:

let map_ngo_area = File.ReadAllLines(@"P:\MY_TABLE.csv") 
        |> Array.to_list 
        |> List.map(fun x -> (x.Split([|','|]) 
              |> Array.map(fun y -> y.Trim())) 

let generate_sql list = list |> List.mapi(fun index row -> 
              match row with 
              | [| ngo_id; area_id |] -> printfn ... 
              | _ -> printfn "")