首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >排得太大,不适合CursorWindow requiredPos=0,totalRows=1;

排得太大,不适合CursorWindow requiredPos=0,totalRows=1;
EN

Stack Overflow用户
提问于 2021-03-11 04:17:50
回答 1查看 4.2K关注 0票数 2

我老是听到这个恼人的消息!

当数据插入本地数据库时,我看到了这条消息。

代码语言:javascript
运行
复制
JNI critical lock held for 30.083ms on Thread[27,tid=23883,Runnable,Thread*=0xce150a00,peer=0x12cc0190,"Sqflite"]

如果我从表中选择数据,我将得到

代码语言:javascript
运行
复制
W/CursorWindow(23809): Window is full: requested allocation 3095146 bytes, free space 2096696 bytes, window size 2097152 bytes
E/SQLiteQuery(23809): exception: Row too big to fit into CursorWindow requiredPos=0, totalRows=1; query: SELECT * FROM description_table;
I/flutter (23809): DatabaseException(Row too big to fit into CursorWindow requiredPos=0, totalRows=1) sql 'SELECT * FROM defect_description_table;' args []}

我没有任何blob数据,都是字符串。那为什么会发生这种事?

在这里,json结构

代码语言:javascript
运行
复制
[{ "id": 1, "name": "Descriptions","data": [{..},{...} ... ]},{....},{....}]

我认为问题在数据列表上,因为它包含了大量的数据(它有10298)?

解决这个问题的办法是什么?

我的插入方法

代码语言:javascript
运行
复制
Future insertData(
      BuildContext context, String urls, String accessToken) async {
    CategoryTableData categoryData = CategoryTableData();
    try {
      var desc = List<Desc>();
      var headers = {
        'authorization': "Bearer" + " " + accessToken,
        "Accept": "application/json"
      };
      var url = xxx;
      var response = await http.get(url, headers: headers);
      var res = json.decode(response.body);
      for (var i in res) {
        if (i['name'] == "Descriptions") {
          desc.add(Desc(
              id: i['id'], name: i['name'], data: i['data']));
        }
      }
      await dao.batch((b) {
        b.insertAll(_dao.descTable, desc);
      });
      categoryData = await _dao.selectAllCategories();
      return categoryData;
    } catch (e) {
      print(e);
      categoryData = await _dao.selectAllCategories();
      return categoryData;
    }
  }

Desc

代码语言:javascript
运行
复制
class Desc extends Table {
  IntColumn get id => integer().nullable()();
  TextColumn get name => text().named("name").nullable()();
  TextColumn get data => text().map(const ListConverter()).nullable()();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-11 05:01:48

消息Window is full: requested allocation 3095146 bytes, free space 2096696 bytes, window size 2097152 bytes

告诉您,您正在尝试将一行(* =所有列)放入游标窗口(缓冲区)中,即3095146字节,该游标窗口(缓冲区)有2096696字节,没有2097152 (2Mb)可用字节。

简单地说,要提取的数据太多了。当您插入数据时,这不是问题,因为没有中间缓冲区和相对有限的缓冲区(游标窗口)。

当尝试检索商店映像时,您经常会看到这种情况。

有各种方法可以用来规避这个问题。

  • 有了这样大的行,按大小计算,您可以将实际数据存储为文件,并将文件路径存储在数据库中(这是推荐用于图像的)。
  • 通过减少提取的列,您可能会有一些运气。也就是说,不使用SELECT *,而是只指定所需的列。
  • 如果问题是列数据的累积大小,则可以使用多个部分提取多个部分。
代码语言:javascript
运行
复制
- You could select potions of data utilising the [length(column\_name) function](https://sqlite.org/lang_corefunc.html#length), perhaps using the [CASE WHEN THEN ELSE END](https://sqlite.org/lang_expr.html#the_case_expression) expression/construct and then build the full data when it has been retrieved.
代码语言:javascript
运行
复制
- It may be that you are inadvertently storing more data, e.g. accidentally concatenating data in a loop.

您需要了解所存储的数据,才能知道上述哪一项可能有用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66576412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档