繁体   English   中英

F#将列表插入SQL Server

[英]F# insert a list into SQL Server

我暂时试图找出一种从F#插入SQL Server的方法。

我有一个F#函数,它按照用户定义的模式迭代文件夹中的所有文件。 然后我可以使用返回的数据放入列表或(理想情况下)插入数据库。

我已经有一个正常工作的insert-to-sql函数:

let execNonQuery conn s =
let comm = 
    new SqlCeCommand(s, conn)
try 
    comm.ExecuteNonQuery() |> ignore
with e ->
    printf "Error : %A\n" e

let string = "insert into MyTable (MyColumn) values ('test .. again')"
execNonQuery conn string; // works

我正在尝试使此方法正常工作:

let rec getAllFiles dir pattern =
    seq { yield! Directory.EnumerateFiles(dir, pattern)
          for d in Directory.EnumerateDirectories(dir) do
              yield! getAllFiles d pattern }

let getApplications (dir : string) (extension : string) = 
    getAllFiles  dir extension
    //|> Seq.toList // If I need to create a list of returned values
    |> Seq.iter (fun s -> SQLInsertString s) // This does not work as it complains about the function not being of type unit

如果我只使用Seq.toList下面的方式调用该函数,它的工作原理如下:

getApplications "C:\Admin" "*.txt" // works

我不明白的另一件事是你如何创建一个工作插入命令,它接受Value的字符串。 例如:

let SQLInsertString s = "insert into MyTable (MyColumn) values (%s)" //does not work

你快到了。 问题是sqlInsertString返回的stringSeq.iter使用是不合法的。

你使用sqlInsertString做的是使用字符串格式创建一个字符串。 它非常适合sprintf函数:

let sqlInsertString s = 
    sprintf "insert into MyTable (MyColumn) values (%s)" s

现在,您可以在execNonQuery的结果上使用sqlInsertString来实际将数据插入到数据库中。 由于execNonQuery返回unit ,因此可以在Seq.iter轻松使用:

// Assuming conn is a global and already defined variable.
let getApplications (dir : string) (extension : string) = 
    getAllFiles  dir extension
    |> Seq.iter (fun s -> execNonQuery conn (sqlInsertString s))

由于类型注释是多余的,因此可以用更惯用的方式重写代码:

let getApplications dir extension conn = 
    getAllFiles dir extension
    |> Seq.iter (sqlInsertString >> execNonQuery conn)

将参数传递给查询的最佳方法是使用SqlCeParameter 这比编写字符串更容易(因为您不需要编码字符串和转义引号),它也更安全,因为您可以避免SQL注入攻击 这是一个基本的例子:

let sqlInsertString value = 
  // Create and open connection ('use' makes sure it gets closed at the end)
  use conn = new SqlCeConnection("...");
  conn.Open()
  // Create a command with a parameter named '@str'
  let cmd = new SqlCeCommand("INSERT INTO MyTable (MyColumn) values (@str)", conn)
  // Create parameter '@str' with string value 'value' and add it to the command
  let param = new SqlCeParameter("@str", SqlDbType.NVarChar, value)
  cmd.Parameters.Add(param)
  // Now run the command (exception handling omitted)
  cmd.ExecuteNonQuery() |> ignore

使用此功能,您现在应该可以使用Seq.iter 该函数接受一个string插入并返回unit (无值),因此可以传递给Seq.iter

let getApplications (dir : string) (extension : string) =  
  getAllFiles  dir extension 
  |> Seq.iter (fun s -> sqlInsertString s)

或者,您可以将最后一行写为|> Seq.iter sqlInsertString 如果你这样做,你基本上是说参数s应该直接传递给sqlInsertString函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM