F# - open System.Data.SQLite

Fsharp SQLite

System.Data.SQLite.dll可以从sqlite.phxsoftware.com得到. 冷门的语言+冷门的应用. 不多解释了, 直接上代码:

#!fsharp
#light
open System
open System.Data
open System.IO
#r "System.Data.SQLite.DLL"
open System.Data.SQLite
// 输出调试结果到命名行
let debug x =
    x |> print_any
    Console.WriteLine()
let space = [|for i in 1 .. 50 -> "*"|] |> string.Concat
// 数据库文件名
let dbFileName = "HelloSQLite.sqlite"
// 连接字符串
let connString =
    let builder = SQLiteConnectionStringBuilder()
    builder.DataSource <- dbFileName
    builder.ConnectionStringspace |> debug
    "连接字符串: " + connString |> debug
// 创建数据库文件
space |> debug
"创建数据库..." |> debug
try
    dbFileName |> File.Delete
    SQLiteConnection.CreateFile dbFileNamewith e ->
        e |> debug
    let test _ =
        use conn = new SQLiteConnection(connString)
        use cmd = conn.CreateCommand()
        conn.Open()
        // 开始计时
        let watch = new System.Diagnostics.Stopwatch()
        watch.Start()
        space |> debug
        "创建表..." |> debug
        try
            (* SQLite 官方文档提及的数据类型只有5种: NULL INTEGER NUMERIC TEXT BLOB           你可能觉得太少了, 事实上 SQLite 是弱类型, 建表时定义的数据类型只是个标识, 对数据列的类型并没有实质性的作用.           你也可以把 TEXT 类型定义成更复杂的 NVARCHAR(50) 之类的, 这只是为了未来数据迁移的方便. *)
            cmd.CommandText <- "CREATE TABLE [Test] ( " +
                               "[Int32] INTEGER NOT NULL, " +
                               "[String] TEXT NOT NULL)"
            cmd.ExecuteNonQuery() |> ignore
        with e ->
            conn.Close()
            e |> debug
            watch.Elapsed |> debug
            watch.Reset()
            watch.Start()
    space |> debug
    "乱入数据十万行..." |> debug
    use trans = conn.BeginTransaction()
    cmd.Transaction <- trans
    try
        // 注意: Int32这个列名有些误导, 封装的作者提及 INTEGER 对应 ADO.net 2.0 的 Int64 类型
        cmd.CommandText <- "INSERT INTO [Test](Int32, String) " +
                           "VALUES(?, ?)"
        // 下面这种生成参数的方式 在参数较多时会有方便 但不能用seq
        [for i in 0 .. 1 -> cmd.CreateParameter()]
        |> List.to_array
        |> cmd.Parameters.AddRange
        |> ignore
        // 参数化插入 这是官方推荐的方式 性能最好
        for i in 0 .. 99999 do
            let vl = [box i; box ((i * 1000).ToString())]
            for j = 0 to (cmd.Parameters.Count - 1) do
                cmd.Parameters.[j].Value <- List.nth vl j
                cmd.ExecuteNonQuery() |> ignore
                trans.Commit()
    with e ->
        trans.Rollback()
        conn.Close()
        e |> debug
        watch.Elapsed |> debug
        watch.Reset()
        watch.Start()
        space |> debug
    "查询前3行..." |> debug
    try
        cmd.CommandText <- "SELECT * FROM [Test] " +
                           "WHERE [Int32]<3"
        use reader = cmd.ExecuteReader()
        while reader.Read() do
            reader.GetInt32 0 |> debug
            reader.GetString 1 |> debug
    with e ->
        e |> debug
        watch.Elapsed |> debug
        watch.Stop()
        conn.Close()
    test()
    Console.ReadKey()