【问题标题】:How to create multiple tables in a database in sqflite?如何在 sqflite 的数据库中创建多个表?
【发布时间】:2019-06-16 09:17:56
【问题描述】:

我正在使用使用 SQLite 数据库的颤振构建和应用程序。我使用这段代码创建了第一个表:

 void _createDb(Database db, int newVersion) async {
    await db.execute('''CREATE TABLE cards (id_card INTEGER PRIMARY KEY, 
         color TEXT, type TEXT, rarity TEXT, name TEXT UNIQUE, goldCost INTEGER,
         manaCost INTEGER, armor INTEGER, attack INTEGER, health INTEGER, description TEXT)''');
}

表已创建,我可以毫无问题地访问它。

不幸的是,我不能包含超过 1 个我刚刚创建的表。我尝试在同一方法中添加另一个 SQL CREATE TABLE 子句,并在下一行使用不同的 SQL 子句重复方法 db.execute

我正在模仿本教程中的代码:https://www.youtube.com/watch?v=xke5_yGL0uk

如何在同一个数据库中添加另一个表?

【问题讨论】:

  • 如果您能承受丢失数据的后果,请卸载该应用程序并在您尝试时使用包含的额外表格运行。这将删除数据库,因此 createDB 将运行(它只在创建数据库时运行一次)。
  • 您收到什么错误信息?您是否为每个表传递不同的表名?
  • 我尝试卸载应用程序并清除本地存储和缓存。我现在无法访问 AS,但是 IIRC 我尝试执行CREATE TABLE IF EXISTS decks (id_deck INTEGER PRIMARY KEY, nameDeck TEXT),当我将数据插入其中时,它显示“表面板没有列‘nameDeck’”
  • 你应该使用CREATE TABLE IF NOT EXISTS decks (id_deck INTEGER PRIMARY KEY, nameDeck TEXT)(注意NOT添加)。再次,删除应用程序的数据/卸载应用程序,然后重试。

标签: database flutter sqlite dart sqflite


【解决方案1】:

openDatabase(path, onCreate, version) 使用另外一个可选参数"onUpgrade" 并定义删除并再次创建表脚本。并将参数版本升级(增加)一个。

-- 代码 sn-p ------

openDatabase(path, onCreate:_createDb, onUpgrade: onUpgrade,version:_DB_VERSION);
...
...

    _onUpgrade( Database db, int oldVersion, int newVersion ) async {

    Batch batch = db.batch();

    // drop first

    batch.execute("DROP TABLE IF EXISTS $_TABLE_3 ;");

    batch.execute("DROP TABLE IF EXISTS $_TABLE_2 ;");
    batch.execute("DROP TABLE IF EXISTS $_TABLE_1 ;");
    // then create again
    batch.execute("CREATE TABLE $TABLE_1 ...... ");
    batch.execute("CREATE TABLE $TABLE_2 ...... ");
    batch.execute("CREATE TABLE $TABLE_3 ...... ");
    List<dynamic> result = await batch.commit();

}

注意:每次创建或更改某些表的结构时,都必须在openDatabase() 方法中增加数据库版本。这样升级才会被调用,否则不会被调用。

【讨论】:

    【解决方案2】:

    您可以使用包含数据库脚本的 .sql 文件。

    首先,将脚本文件添加到资产中。

    然后,导入以下包:

    import 'package:path/path.dart';
    
    import 'package:sqflite/sqflite.dart';
    
    import 'package:flutter/services.dart' show rootBundle;
    

    最后,使用下面的代码

    void _createDb() async 
    {
          final database = openDatabase( join( await getDatabasesPath(), 'mydb.db'),
          onCreate: (db, version) async  
          {
              // call database script that is saved in a file in assets
              String script =  await rootBundle.loadString("assets\\db\\script.sql");
              List<String> scripts = script.split(";");
              scripts.forEach((v) 
              {
                  if(v.isNotEmpty ) 
                  {
                       print(v.trim());
                       db.execute(v.trim());
                  }
              });
           },
           version: 1,
           );
    }
    

    【讨论】:

      【解决方案3】:

      是的,你可以做到的

       void _createDb(Database db, int newVersion) async {
       await db.execute('''
         create table $carTable (
          $columnCarId integer primary key autoincrement,
          $columnCarTitle text not null
         )''');
       await db.execute('''
         create table $userTable(
          $userId integer primary key autoincrement,
          $name text not null
         )''');
        }
      

      但为了加快处理速度,假设我们有 10 个表,您可以这样使用批处理

      void _createDb(Database db, int newVersion) async {
      Batch batch = db.batch();
      batch.execute("Your query-> Create table if not exists");
      batch.execute("Your query->Create table if not exists");
      List<dynamic> res = await batch.commit();
      //Insert your controls
      }
      

      【讨论】:

      • 如果我们希望在同一时间创建多个表,这段代码很好,但是,如果我需要稍后在现有数据库中创建一个表,而不是我该怎么做,还是不可能?
      • 我不知道在运行时是否有可能我从未尝试过。但是你可以试着用这种方式告诉我。在您的 DB Helper 中确保返回数据库实例,使用我上面的代码创建表并尝试这种方式。
      【解决方案4】:

      更改DB 文件的名称。这将“重置”您的数据库并且创建将起作用。

      例如:

      final dabasesPath = await getDatabasesPath(); 
      final path = join(dabasesPath, "newName2.db");
      

      【讨论】:

        【解决方案5】:

        例如,您可以组合多个 db.execute 调用

        await db.execute('''
              create table $reminderTable (
                $columnReminderId integer primary key autoincrement,
                $columnReminderCarId integer not null,
                $columnReminderName text not null,
                $columnReminderNotifyMileage integer not null,
                $columnReminderEndMileage integer not null
               )''');
        await db.execute('''
               create table $carTable (
                $columnCarId integer primary key autoincrement,
                $columnCarTitle text not null
               )''');

        【讨论】:

          【解决方案6】:

          很难说没有看到您的openDatabase 电话以及数据库之前是否存在。我的猜测之一是您仍在使用相同的数据库版本。一旦onCreate 被调用,它将永远不会被再次调用。您应该尝试提升您的数据库版本并将新表添加到 onUpgrade

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-28
            • 2019-06-03
            • 2021-12-16
            • 2019-12-06
            • 1970-01-01
            相关资源
            最近更新 更多