【问题标题】:What is wrong with this Javascript code to insert data into a Web SQL database?这段将数据插入 Web SQL 数据库的 Javascript 代码有什么问题?
【发布时间】:2012-11-07 09:55:32
【问题描述】:

我正在尝试创建一个简单的页面,该页面采用二进制文件并将值插入 Web SQL 数据库。 这是我用来插入数据的函数:

function bin2dbfunc()
{
    var result, n, aByte, byteStr;
    var i=0;
    var sql = new Array();

    result = fr.result;  //Input file

    for (n = 0; n < result.length; ++n) 
    {
        aByte = result.charCodeAt(n);
        byteStr = aByte.toString(16);
        if (byteStr.length < 2)
        {
            byteStr = "0" + byteStr;
        } //Format to add leading 0 for hex values

        //Looping through taking each byte read from file and adding to array

        //sql[i] = aByte;   //Value
        sql[i] = byteStr;   //String


        //When completed one row of database run single SQL insert statement with array contents
        if(i==15)
        {
            i=0;  //Clear counter for next row
            db.transaction(function (tx)
            {
                tx.executeSql('INSERT INTO binary_data VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [sql[0], sql[1], sql[2], sql[3], sql[4], sql[5], sql[6], sql[7], sql[8], sql[9], sql[10], sql[11], sql[12], sql[13], sql[14], sql[15]]);
            }, function (tx, err) {
                document.getElementById("result3").innerHTML += 'ERROR ';  //Display error message if SQL not run successfully
            });
        }
        else
        {
            i++;  //Otherwise increment counter
        }
    }
}

我已经剥离了代码以删除我的所有调试消息,但基本上代码似乎可以运行。我正在使用一个包含 6 行数据的二进制文件,但是代码将最后一行数据插入数据库 6 次。 谁能发现我哪里出错了?

【问题讨论】:

  • 听起来像是范围界定问题 - db.transaction() 是异步函数吗?
  • 如果tx.executeSql 抛出错误,变量i 不会增加。会这样吗?

标签: javascript html web-sql


【解决方案1】:

在 JavaScript 闭包中,变量是通过引用而不是值来捕获的(这对于数组等对象是正确的,但对于原始值也是如此);这意味着传递给db.transaction 的函数在运行时将使用sql 的当前值。在您的情况下,它们似乎是异步运行的,因此在返回 bin2dbfunc 后使用 sql 的值(这解释了为什么您最终得到最后一行数据)。

您必须复制sql 的值以确保使用正确的值:

function transactionCallback(sql_) {
  var sql = sql_.slice(0); // copy
  return function(tx) {
    tx.executeSql(…, sql);
  };
}

db.transaction(transactionCallback(sql), …);

function transactionCallback(sql) {
  return function(tx) {
    tx.executeSql(…, sql);
  };
}

db.transaction(transactionCallback(sql), …);
sql = [];

因为您在 bin2dbfunc 之后不需要 sql 的值;第二个解决方案还可以让您摆脱i 并使用基于pushlength 的更优雅的解决方案。

【讨论】:

  • 谢谢,解决了这个问题。在尝试更多的 javascript 之前,我将不得不做更多的阅读,这只是一个混合的例子来尝试一个想法。
猜你喜欢
  • 2016-02-21
  • 1970-01-01
  • 2018-01-08
  • 1970-01-01
  • 2020-01-14
  • 1970-01-01
  • 2016-11-14
  • 2011-06-01
相关资源
最近更新 更多