Haskell 的简洁和优雅让我印象深刻。但是我在 .Net 公司工作,所以当我可以摆脱它时我会使用 F#——我可能是全国数百个使用它的唯一一个。
ADO.NET 或 F# 是否提供了与 HDBC 一样简洁和优雅的东西executeMany
?我正在通过Real World Haskell。在第 21 章中,它提供了这个例子:
ghci> conn <- connectSqlite3 "test1.db"
ghci> stmt <- prepare conn "INSERT INTO test VALUES (?, ?)"
ghci> executeMany stmt [[toSql 5, toSql "five's nice"], [toSql 6, SqlNull]]
ghci> commit conn
ghci> disconnect conn
我想在我的 F# 中获得这种优雅和简洁。我已经看到很多关于使用参数化查询来避免 SQL 注入攻击的炒作。在这种情况下,我不使用它们有以下三个原因:
- 我发现 .Net 中的参数化查询丑陋而繁琐。
- 我的数据来自公司办公室,所以它(大部分)是干净的。
- 我的表有 34 列。我鄙视用 34 列参数化查询的想法。
这是我的 F# 代码:
module Data
open System
open System.Data
open System.Data.OleDb
open System.Text.RegularExpressions
type Period = Prior | Current
let Import period records db =
use conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + db + ";Persist Security Info=False;")
let execNonQuery s =
let comm = new OleDbCommand(s, conn) in
comm.ExecuteNonQuery() |> ignore
let enquote = sprintf "\"%s\""
let escapeQuotes s = Regex.Replace(s, "\"", "\"\"")
let join (ss:string[]) = String.Join(",", ss)
let table = match period with
| Prior -> "tblPrior"
| Current -> "tblCurrent"
let statements =
[| for r in records do
let vs = r |> Array.map (escapeQuotes >> enquote) |> join
let vs' = vs + sprintf ",\"14\",#%s#" (DateTime.Now.ToString "yyyy-MM-dd") in
yield sprintf "INSERT INTO %s ( [Field01], [Field02], [Field03] [Field04], [Field05], [Field06], [Field07], [Field08], [Field09], [Field10], [Field11], [Field12], [Field13], [Field14], [Field15], [Field16], [Field17], [Field18], [Field19], [Field20], [Field21], [Field22], [Field23], [Field24], [Field25], [Field26], [Field27], [Field28], [Field29], [Field30], [Field31], [Field32], [Field33], [Field34] ) VALUES (%s)" table vs' |] in
do conn.Open()
execNonQuery (sprintf "DELETE FROM %s" table)
statements |> Array.iter execNonQuery
出于安全原因,我已重命名表的字段。
因为表格上的所有字段都是文本,所以我可以轻松地将它们 Array.map 以转义和引用值。
每天有 9,000 到 10,000 条记录要导入到这两个表中的每一个,我希望尽可能高效地执行此操作。因此我对executeMany
Haskell 感兴趣。不过,我也喜欢参数化查询背后的想法,也喜欢 Hasekll 实现它们的方式。在 F# 中是否存在与简洁和优雅相当的东西?