F#将数据存储在ms访问表中

时间:2015-08-09 13:21:03

标签: f# f#-interactive f#-3.0 f#-data

如何使用OleDbConnection将数组导出到ms访问表。以下是我到目前为止的代码。

  let A=y|>Array.map (fun x->x.a) 
  let B=y|>Array.map (fun x->x.b) 
  let C=y|>Array.map (fun x->x.c) 
  let D=y|>Array.map (fun x->x.d) 

  let cnn = @"Provider=Microsoft.ACE.OLEDB.12.0;
    Data Source=U:\test.accdb;
    Persist Security Info=False;" 
  let conn = new OleDbConnection(cnn) 
  conn.Open() 
  use com = conn.CreateCommand()
  com.CommandText <- "INSERT INTO Test values" {A,B,C,D}
  com.ExecuteNonQuery() |> ignore
  conn.Close()

1 个答案:

答案 0 :(得分:0)

要插入多行,您需要发出多个命令。 Access不允许使用一个insert语句插入多个值,请参阅此问题以获取更多信息:Insert multiple rows using one insert statement in Access 2010

只要你使用多个语句就可以了,你必须正确地准备命令 - 也就是说,包括VALUES部分之后的实际值。如果您不喜欢SQL注入,那么在使用它时,您也应该使用参数。像这样:

use com = conn.CreateCommand()
com.CommandText <- "INSERT INTO Test values( ?, ?, ?, ? )"

let param name = 
    let p = com.CreateParameter()
    p.ParameterName <- name
    com.Parameters.Add p
    p
let pA, pB, pC, pD = param "@a", param "@b", param "@c", param "@d"

y |> Array.iter (fun x ->
    pA.Value <- x.a
    pB.Value <- x.b
    pC.Value <- x.c
    pD.Value <- x.d
    com.ExecuteNonQuery() )

conn.Close()

如果你真的想加快速度,你必须找到一种方法将记录批量插入Access,类似于SQL服务器的SqlBulkInsert。如果它存在,我不知道这样的方式。

或者,你可以创建一个由N个插入语句组成的命令(其中N = y.Length),但是那个语句将有4N参数,我相信Access对参数的数量有限制。

或者 - 您也可以执行上述操作,但不使用参数,将值插入SQL命令的文本中:

let commandText = 
    y 
    |> Seq.map (fun x -> 
        // assuming all four parameters are strings
        sprintf "INSERT INTO Test values( '%s', '%s', '%s', '%s' )" x.a x.b x.c x.d 
    |> String.concat " "

use com = conn.CreateCommand()
com.CommandText <- commandText
com.ExecuteNonQuery()
conn.Close()

但是在这种情况下,你会打开SQL注入攻击。您必须非常小心地清理数组值 以防止它。我不建议这样做只是为了获得额外的几秒钟性能。

说到性能:你是否完全确定多个插入语句对于你的目的来说太慢了?为什么?你测量过吗?怎么样?
记住性能调优的黄金法则:先测量,然后优化。