【问题标题】:F# store data in ms access tableF#将数据存储在ms访问表中
【发布时间】:2015-08-09 13:21:02
【问题描述】:

如何使用 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()

【问题讨论】:

  • 也许您应该包括您遇到的所有问题 - 另外:您知道如何插入单行吗?我会考虑在这里使用Array.iter 而不是多个maps(使用INSERT inside iter
  • 我必须使用array.iter吗?是否可以使用单个insert 插入整个数组?如果我执行迭代,代码运行速度会慢得多
  • 还有其他有效的方法可以将数据插入到 ms access 中吗?
  • 老实说,我不知道你是否可以在 MS-Access 中进行某种批量插入 - 但正如你肯定看到的那样,你所做的根本行不通 - 你必须映射你的东西到某种 sql 字符串(是的,我想我不得不提一下:由于 SQL 注入攻击,您可能不想这样做)或参数 - 但这不完全是 F# 问题 - 它实际上是一个 ODBC/ MS-Access 的东西
  • 你是绝对正确的,它不工作。如果我采用Array.iter 方法并逐行存储数据,是否可以使用某种并行功能更快地迭代它。否则有ms访问的SqlDataproviders吗?

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


【解决方案1】:

为了插入多行,您需要发出多个命令。 Access 不允许使用一个插入语句插入多个值,请参阅此问题了解更多信息: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 Server 的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 注入攻击。您必须非常小心地清理您的数组值以防止它发生。我不建议这样做只是为了获得额外的几秒钟的性能。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 2012-08-09
    相关资源
    最近更新 更多