l***@21cn.com
l***@21cn.com
  • 发布:2020-06-27 17:01
  • 更新:2020-07-01 23:04
  • 阅读:1606

【报Bug】sqlite的integer字段无法存储bigint类型的值

分类:HTML5+

产品分类: HTML5+

HBuilderX版本号: 2.7.14

手机系统: iOS

手机系统版本号: iOS 13.4

手机厂商: 苹果

手机机型: iphone 11

打包方式: 离线

示例代码:

var created, updated;
created = updated = (new Date()).getTime();
INSERT INTO article (title, created, updated) VALUES ('Hello world', created, updated); //仅是示例

操作步骤:

integer字段插入bigint类型值

预期结果:

入库后是bigint类型

实际结果:

变成了负数

bug描述:

sqlite的integer字段存储时间戳(毫秒)时,结果变成了负数,应该是不支持bigint!
在chrome中调试是支持bigint的,chrome自带的sqlite使用正常。

附带问题:
insert, update, delete操作为什么不能象chrome浏览器自带那样有个rowsAffected属性?所有insert、update、delete操作得到都是空对象“{}”,都搞不清究竟增删改了多少条数据。

2020-06-27 17:01 负责人:无 分享
已邀请:
l***@21cn.com

l***@21cn.com (作者)

着急,期待官方尽快回复。

  • CLP

    安卓有这个问题吗? 另外提供一个能复现问题的demo来

    2020-07-01 12:40

  • CLP

    完整demo

    2020-07-01 12:41

l***@21cn.com

l***@21cn.com (作者)

回复 DCloud_IOS_CLP:

重新测试一遍,这次bigint值没变负数,但13位时间戳变成了9位。
完整demo如下:

function createTable(dbname, table, success, error) {  
    if (window.localStorage.getItem('table_created')) {  
        success && success(dbname, table);  
        return;  
    }  

    var create_table_sql = [  
        'DROP TABLE IF EXISTS "' + table + '"',  
        'CREATE TABLE "' + table + '" ("id" integer NOT NULL, "content" text(100) NOT NULL DEFAULT \'\', "created" integer NOT NULL DEFAULT 0, "updated" integer NOT NULL DEFAULT 0, PRIMARY KEY ("id") )'  
    ];  
    plus.sqlite.executeSql({  
        name: dbname,  
        sql: create_table_sql,  
        success: function(e) {  
            console.log('create table success!');  
            success && success(dbname, table);  
            window.localStorage.setItem('table_created', (new Date()).getTime());  
        },  

        fail: function(e) {  
            console.log('create table failed: ' + JSON.stringify(e));  
            error && error(e);  
        }  
    });  
}  

function insertData(dbname, table, success, error) {  
    var time = (new Date()).getTime();  
    console.log('current time: ' + time);  
    var id = Math.floor(Math.random() * (2147483647 - 1)) + 1;  
    var content = 'hello world';  
    var created, updated;  
    created = time;  
    updated = time;  

    var curdata = {  
        'id': id,  
        'content': content,  
        'created': created,  
        'updated': updated  
    };  

    var insert_sql = 'insert into ' + table + ' values(' + id +', ' + '"' + content + '", ' + created + ', ' + updated + ')';  

    plus.sqlite.executeSql({  
        name: dbname,  
        sql: insert_sql,  
        success: function(e) {  
            console.log('insert data success: ' + insert_sql);  
            success && success(dbname, table, curdata);  
        },  

        fail: function(e) {  
            console.log('insert data failed: ' + JSON.stringify(e));  
            error && error(e);  
        }  
    });  
}  

function selectData(dbname, table, curdata) {  
    plus.sqlite.selectSql({  
        name: dbname,  
        sql: 'select * from ' + table,  
        success: function(data) {  
            console.log('curdata: ' + JSON.stringify(curdata));  

            console.log('selectSql success: ');  
            for(var i in data){  
                console.log(data[i]);  
            }  
        },  
        fail: function(e){  
            console.log('selectSql failed: ' + JSON.stringify(e));  
        }  
    });  
}  

function run(dbname, table) {  
    createTable(dbname, table, function(dbname, table) {  
        insertData(dbname, table, function(dbname, table, curdata) {  
            selectData(dbname, table, curdata);  
        })  
    });  
}  

function openDb(dbname, table, success, error) {  
    var path = '_doc/' + dbname + '.db';  
    if (plus.sqlite.isOpenDatabase({name: dbname, path: path})) {  
        success && success(dbname, table);  
    } else {  
       plus.sqlite.openDatabase({  
            name: dbname,  
            path: path,  
            success: function(e){  
                success && success(dbname, table);  
            },  
            fail: function(e){  
                console.log('openDatabase ' + dbname + ' failed: '+JSON.stringify(e));  
            }  
        });   
    }  
}  

openDb('test', 'test', run); //////////////

测试结果:
[Debug] current time: 1593613281578
[Debug] insert data success: insert into test values(1503241206, "hello world", 1593613281578, 1593613281578)
[Debug] curdata: {"id":1503241206,"content":"hello world","created":1593613281578,"updated":1593613281578}
[Debug] selectSql success:
[Debug] {content: "hello world", created: 180414762, id: 1503241206, updated: 180414762}

//created integer(19),设置created integer/bigint 都一样不支持bigint
[Debug] current time: 1593613645111
[Debug] insert data success: insert into test values(292336785, "hello world", 1593613645111, 1593613645111)
[Debug] curdata: {"id":292336785,"content":"hello world","created":1593613645111,"updated":1593613645111}
[Debug] selectSql success:
[Debug] {content: "hello world", created: 180778295, id: 292336785, updated: 180778295}

//created text(19) 设置created为text类型
[Debug] current time: 1593614355308
[Debug] insert data success: insert into test values(1676981135, "hello world", 1593614355308, 1593614355308)
[Debug] curdata: {"id":1676981135,"content":"hello world","created":1593614355308,"updated":1593614355308}
[Debug] selectSql success:
[Debug] {content: "hello world", created: "1593614355308", id: 1676981135, updated: 181488492}

测试总结:字段类型无论是integer,bigint都不支持bigint值。

为什么要用bigint?因为要可能牵涉比较大小,排序等操作。

再次吐槽:

  1. 官方的接口实在简陋,sql查询居然不支持占位符方式,还不如h5自带的那样方便;
  2. insert, update, delete操作为什么不能象chrome浏览器自带那样有个rowsAffected属性?所有insert、update、delete操作得到都是空对象“{}”,都搞不清究竟增删改了多少条数据。

该问题目前已经被锁定, 无法添加新回复