Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android设备上的批量插入_Android_Sqlite_Bulkinsert - Fatal编程技术网

Android设备上的批量插入

Android设备上的批量插入,android,sqlite,bulkinsert,Android,Sqlite,Bulkinsert,我想在下次升级时将大约700条记录批量插入Android数据库。最有效的方法是什么?从各种帖子中,我知道如果我使用Insert语句,我应该将它们包装在事务中。还有一个关于使用你自己的数据库的问题,但我需要这些数据进入我的应用程序的标准Android数据库。请注意,每个设备只能执行一次 一些想法: 将一组SQL语句放在一个文件中,一次读取一行,然后执行SQL 将数据放在CSV文件、JSON、YAML、XML或其他文件中。一次读一行,然后执行db.insert() 了解如何导入和单个导入整个文件 创

我想在下次升级时将大约700条记录批量插入Android数据库。最有效的方法是什么?从各种帖子中,我知道如果我使用
Insert
语句,我应该将它们包装在事务中。还有一个关于使用你自己的数据库的问题,但我需要这些数据进入我的应用程序的标准Android数据库。请注意,每个设备只能执行一次

一些想法:

  • 将一组SQL语句放在一个文件中,一次读取一行,然后执行SQL

  • 将数据放在CSV文件、JSON、YAML、XML或其他文件中。一次读一行,然后执行
    db.insert()

  • 了解如何导入和单个导入整个文件

  • 创建一个包含所有记录的sqlite数据库,将其复制到Android设备上,然后以某种方式合并这两个数据库

  • [编辑]将所有SQL语句以res/values格式放在一个文件中,作为一个大字符串。然后一次读一行并执行SQL


  • 最好的办法是什么?是否有其他加载数据的方法?3和4都有可能吗?

    我认为没有任何可行的方法来完成你名单上的3或4

    在其他解决方案中,您列出了两个数据文件包含直接SQL的解决方案,另一个解决方案的数据格式为非SQL格式

    这三种方法都可以很好地工作,但后一种建议是从格式化文件中获取数据并自己构建SQL,这似乎是最干净的。如果在以后添加了真正的批处理更新功能,那么您的数据文件仍然可用,或者至少可以轻松地处理成可用的形式。此外,数据文件的创建更简单,更不容易出错。最后,拥有“原始”数据将允许导入其他数据存储格式


    在任何情况下,您都应该(如您所提到的)将插入组包装到事务中,以避免创建每行事务日志。

    我发现,对于批量插入,类(显然很少使用)比使用
    SQLiteDatabase.insert快几倍

    另外两种优化也有助于提高我的应用程序的性能,尽管它们可能并不适用于所有情况:

    • 不要
      bind
      空值或
      null
    • 如果您可以确定这样做是安全的,那么暂时关闭数据库的内部锁定也有助于提高性能

    通常,每次使用
    db.insert()
    时,SQLite都会创建一个事务(并在文件系统中生成日志文件),这会降低速度

    如果使用
    db.beginTransaction()
    db.endTransaction()
    SQLite只在文件系统上创建一个日志文件,然后同时提交所有插入,大大加快了速度

    下面是来自以下站点的一些伪代码:

    如果由于意外错误或其他原因希望中止事务,只需
    db.endTransaction()
    ,而不首先将事务设置为成功(
    db.setTransactionSuccessful()

    另一个有用的方法是使用<代码> dB.InTraceNo.(/)代码>(返回<代码> Trase< /Cord>或<代码> false <代码>),以确定当前是否处于事务的中间。


    嗯,我的解决方案有点奇怪,但效果很好。。。 我编译了大量数据并一次性插入(批量插入?)

    我使用
    db.execSQL(Query)
    命令,用以下语句构建“Query”

    INSERT INTO yourtable SELECT * FROM (
        SELECT 'data1','data2'.... UNION
        SELECT 'data1','data2'.... UNION
        SELECT 'data1','data2'.... UNION
        .
        .
        .
        SELECT 'data1','data2'....
    )
    
    唯一的问题是查询的构建可能有点混乱。
    我希望它能有所帮助

    下面的示例将非常有效

     String sql = "INSERT INTO " + DatabaseHelper.TABLE_PRODUCT_LIST
                    + " VALUES (?,?,?,?,?,?,?,?,?);";
    
            SQLiteDatabase db = this.getWritableDatabase();
            SQLiteStatement statement = db.compileStatement(sql);
            db.beginTransaction();
            for(int idx=0; idx < Produc_List.size(); idx++) {
                statement.clearBindings();
                statement.bindLong(1, Produc_List.get(idx).getProduct_id());
                statement.bindLong(2,  Produc_List.get(idx).getCategory_id());
                statement.bindString(3, Produc_List.get(idx).getName());
    //            statement.bindString(4, Produc_List.get(idx).getBrand());
                statement.bindString(5, Produc_List.get(idx).getPrice());
                //statement.bindString(6, Produc_List.get(idx).getDiscPrice());
                statement.bindString(7, Produc_List.get(idx).getImage());
                statement.bindLong(8, Produc_List.get(idx).getLanguage_id());
                statement.bindLong(9, Produc_List.get(idx).getPl_rank());
                statement.execute();
    
            }
            db.setTransactionSuccessful();
            db.endTransaction();
    
    String sql=“插入”+DatabaseHelper.TABLE\u产品列表
    +“值(?,,,,,,,,,,,,,,;”;
    SQLiteDatabase db=this.getWritableDatabase();
    SQLiteStatement=db.compileStatement(sql);
    db.beginTransaction();
    对于(int idx=0;idx
    很酷。多么有创意的解决方案啊。听起来会很快。是吗?使用StringBuilder类速度会很快。@Andrew Prat。。。工会的最高限额是多少。对于我来说,通过这个联合操作,我可以在一个insert语句中插入500条记录。如果我想在一条语句中插入5000条记录。有可能吗?如果是,那么怎么做?更多代码参考:试图修复db.endTransaction()中的打字错误,但它太小了。这正是我要找的。我导入了大约50个包含数千条记录的csv文件,当从csv中读取一行并将其插入数据库时,需要几个小时才能完成。使用db.beginTransaction()只需几秒钟!谢谢回滚到r4。r5和r6是不必要的-打字错误已经修复。@AndrewMedico是的,根据链接的示例和文档,必须调用
    db.setTransactionSuccessful()
    db.endTransaction()
    已在finally块中调用。谢谢!这一优化增加了大量的
     String sql = "INSERT INTO " + DatabaseHelper.TABLE_PRODUCT_LIST
                    + " VALUES (?,?,?,?,?,?,?,?,?);";
    
            SQLiteDatabase db = this.getWritableDatabase();
            SQLiteStatement statement = db.compileStatement(sql);
            db.beginTransaction();
            for(int idx=0; idx < Produc_List.size(); idx++) {
                statement.clearBindings();
                statement.bindLong(1, Produc_List.get(idx).getProduct_id());
                statement.bindLong(2,  Produc_List.get(idx).getCategory_id());
                statement.bindString(3, Produc_List.get(idx).getName());
    //            statement.bindString(4, Produc_List.get(idx).getBrand());
                statement.bindString(5, Produc_List.get(idx).getPrice());
                //statement.bindString(6, Produc_List.get(idx).getDiscPrice());
                statement.bindString(7, Produc_List.get(idx).getImage());
                statement.bindLong(8, Produc_List.get(idx).getLanguage_id());
                statement.bindLong(9, Produc_List.get(idx).getPl_rank());
                statement.execute();
    
            }
            db.setTransactionSuccessful();
            db.endTransaction();