2009-12-17 58 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 "")