使用 SqlBulkCopy 和 F# 在 SQL 中导出矩阵

发布于 2024-12-28 05:11:38 字数 462 浏览 0 评论 0 原文

我想将大量数据从 F# 传输到 SQL 表。基本上,我的 F# 代码创建了一个由三列(UserID、ProductID 和 Price)和 N 行组成的矩阵。我想将其“复制/粘贴”到数据库中 我尝试了多种选择,但最终,从 F# 传输数据非常慢(10000 行大约需要 1 小时)。

感谢上一个问题的回答 如何包含存储的在 F# 中,解决此问题的一个有趣方法是使用 SqlBulkCopy

SqlBulkCopyWritetoServer 方法需要数据库类型,但我没有找到任何现有代码或将矩阵转换为数据库的简单方法。 您有什么建议或想法吗?

I want to transfer a large amount of data from F# to an SQL table. Basically my F# code creates a matrix of three columns (UserID, ProductID and price) and N lines. I would like to "copy/pate it" into a database
I tried several options but at the end, the transfer of data from F# is really slow (around one hour for 10000 lines).

Thanks to answers of a previous question How to include a stored procedure in F#, an interesting way to resolve this problem is to use SqlBulkCopy.

SqlBulkCopy requires a database type for its WritetoServer method but I didn't find any existing code or simple way to convert a matrix into a database.
Do you have any suggestions or ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

征棹 2025-01-04 05:11:38

这应该可以帮助您开始(并参考文档 有关 SqlBulkCopy 的更多信息):

//you must reference System.Data and System.Xml
open System.Data
open System.Data.SqlClient

let bulkLoadUserPurchases (conn:SqlConnection) (userPurchases: list<int * int * float>) =
    use sbc = new SqlBulkCopy(conn, SqlBulkCopyOptions.TableLock, null, BatchSize=500, BulkCopyTimeout=1200, DestinationTableName="YOUR_TABLE_NAME_HERE")
    sbc.WriteToServer(
        let dt = new DataTable()
        ["UserID", typeof<int>
         "ProductID", typeof<int>
         "Price", typeof<float>]
        |> List.iter (dt.Columns.Add>>ignore)

        for userPurchase in userPurchases do
            let userId, productId, price = userPurchase
            let dr = dt.NewRow()
            dr.["UserID"] <- userId
            dr.["ProductID"] <- productId
            dr.["Price"] <- price
            dt.Rows.Add(dr)

        dt)

This should get you started (and reference the documentation for more information about SqlBulkCopy):

//you must reference System.Data and System.Xml
open System.Data
open System.Data.SqlClient

let bulkLoadUserPurchases (conn:SqlConnection) (userPurchases: list<int * int * float>) =
    use sbc = new SqlBulkCopy(conn, SqlBulkCopyOptions.TableLock, null, BatchSize=500, BulkCopyTimeout=1200, DestinationTableName="YOUR_TABLE_NAME_HERE")
    sbc.WriteToServer(
        let dt = new DataTable()
        ["UserID", typeof<int>
         "ProductID", typeof<int>
         "Price", typeof<float>]
        |> List.iter (dt.Columns.Add>>ignore)

        for userPurchase in userPurchases do
            let userId, productId, price = userPurchase
            let dr = dt.NewRow()
            dr.["UserID"] <- userId
            dr.["ProductID"] <- productId
            dr.["Price"] <- price
            dt.Rows.Add(dr)

        dt)
沒落の蓅哖 2025-01-04 05:11:38

如果您同意第三方库,fastmember 在这里真的很有用。

module DB =
    open System.Data
    open System.Data.SqlClient
    open FastMember

    // val bulk : conn:SqlConnection -> table:string -> columns:seq<string*string> -> items:seq<a'>
    let bulk conn table columns items =        
        use bcp = new SqlBulkCopy(connection = conn)
        bcp.EnableStreaming <- true
        bcp.DestinationTableName <- table
        for n,v in columns do   
            bcp.ColumnMappings.Add(new SqlBulkCopyColumnMapping(sourceColumn = n, destinationColumn = v))               
            |> ignore
        bcp.WriteToServer(items |> ObjectReader.Create)

这给您留下了一个通用方法,您可以将任何 seq 汇集到其中。还有一些配置参数,您当然可以根据需要进行配置。

If you're okay with third party libraries, fastmember can be really useful here.

module DB =
    open System.Data
    open System.Data.SqlClient
    open FastMember

    // val bulk : conn:SqlConnection -> table:string -> columns:seq<string*string> -> items:seq<a'>
    let bulk conn table columns items =        
        use bcp = new SqlBulkCopy(connection = conn)
        bcp.EnableStreaming <- true
        bcp.DestinationTableName <- table
        for n,v in columns do   
            bcp.ColumnMappings.Add(new SqlBulkCopyColumnMapping(sourceColumn = n, destinationColumn = v))               
            |> ignore
        bcp.WriteToServer(items |> ObjectReader.Create)

This leaves you with a generic method that you can just funnel any seq<a'> into. Along with some config parameters, which you can of course configure to your needs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文