Web SQL 是存在于浏览器端的数据库,但是它并没有成为浏览器的一种标准,不过 Web SQL 有属于自己独立的标准。因此,Web SQL 并不存在于所有的浏览器中。就现在而言,Web SQL 仅仅存在于 Google Chrome(谷歌浏览器),以及绝大部分基于 Chromium 内核的浏览器,新版的 Microsoft Edge。Firefox、IE、以及旧版的 Microsoft Edge 都不支持 Web SQL。

据了解,Web SQL 数据库最普遍而又单一实现的居然是 SQLite !

比较详细的解释可以看看知乎的这个疑问 “sqlite与websql的关系?”。既然如此,那么在使用 Web SQL 的时候岂不是就可以参照 SQLite 的语法创建数据库,创建表之类的?🧐🧐

或者使用标准的 SQL 语句来创建?

带着这个疑问,那就开始 Web SQL 的旅程吧。

狐妖小红娘

Web SQL 在哪里呢

如果经常打开 F12 去查看控制台的消息或者进行页面调试,那么你会熟悉的看到……

对,没错啦!就是打开 F12,找到 Application,然后有一个 Web SQL。这里面就有一个 Web SQL 的选项。这是搜狗浏览器的 Web SQL 所在的位置。谷歌浏览器也是一样的在这个位置。

WebSQLAtSogou

新版的 Microsoft Edge 它也是基于 Chromium 内核的,所以它也有一个 Web SQL。不过它的开发调试界面也全是中文的。

WebSQLEdge

开始使用 Web SQL

Web SQL 有三个核心的方法,使用起来不会很难,它们分别是。

  • openDatabase:该方法打开现有的数据库,如果没有,咱们就建立一个😄。它会返回一个数据库对象。
  • transaction:该方法可以控制一个事务,以及执行提交或者回滚。
  • executeSql:该方法是用于执行 SQL 语句的。

接下来就是开始使用这些方法的时候了。

创建数据库

创建数据库使用 openDatabase 进行创建,不过它有几个参数。

  • name:数据库名称
  • version:版本
  • displayName:数据库描述
  • estimatedSize:数据库的大小
  • creationCallback:创建数据库时的回调函数。

创建数据库

创建数据库的代码如下:

var database = openDatabase("xiaohehe233", "0.1", "测试用的数据库", 1 * 1024 * 1024, function(msg){
    console.log(msg);
});

创建成功之后,在 Web SQL 中可以看到我刚刚创建的数据库了。

xiaohehe233

不过很奇怪,这个回调函数中的参数,仅仅只返回一个版本,不知这是为何 ???暂时不管啦,能创建出来才是王道。

创建数据库

创建表

在 Web SQL 中,我们目前无法通过可视化的工具来创建表,需要通过 SQL 语句来创建表。创建表的标准一般都是 create table。

不过在创建之前,需要创建一个事务,才可以正常的对 SQL 语句进行操作。事务它有三个参数,这三个参数传递的都是函数。第一个传递的 callback 是需要执行 SQL 语句的,第二个传递的 callback 是建表时出现的错误是用来进行回调的,第三个传递的 callback 是需要执行正常建表会进行回调的函数。

transaction

由于第一个回调函数是用来执行事务的,所以我们在这里面调用 executeSql 方法来执行 SQL 语句

接下来,我们使用习惯的写法来看看 SQL 语句是否真正的有效。

db.transaction(function(tx){
    tx.executeSql(`
            create table phone_book (
            phone_number  int  primary key,
            name  varchar(20)  not null,
            age  int
        )
	`);
}, function(e) {
    console.log(e, "创建过程出现不可预知的异常");
}, function(e) {
    console.log(e, "创建成功!");
});

运行完成之后,发现数据库中的表也已经成功地建立了。不过表建立完成之后,里面肯定是没有数据的

phone_book

如果我们再创建一次会怎么样呢?当然是会执行错误的回调。错误的回调中输出时带有错误码和错误的原因,这个原因提示的是因为这张表在该数据库中已经存在。

err_callback

修改表结构

我有一个想法,我要把这张 phone_book 的表新增一个字段,我该怎么办?那就利用 alter table 来对 Web SQL 中的表来进行修改吧。

对表中的字段进行更新和删除,可以参照 “W3school 的 SQL 教程” 。

修改表结构的 SQL 语句如下

db.transaction(function(tx){
    tx.executeSql(`
		alter table phone_book add birthday date
	`);
}, function(e) {
    console.log(e, "创建过程出现不可预知的异常");
}, function(e) {
    console.log(e, "创建成功!");
});

运行结果如下,如果我在执行一次更新的操作,那么它便会提示 “重复列的错误”。(我这里的提示信息没改,忘记了,哈哈哈哈哈啊哈哈哈)

修改表

删除表

删除表也是非常简单的

db.transaction(function(tx){
      tx.executeSql(`drop table phone_book`);
  }, function(e) {
      console.log(e, "删表过程出现不可预知的异常");
  }, function(e) {
      console.log(e, "删表成功!");
});

执行结果如下,如果我们再次删除,那么就会继续给出报错提示“没有这张表”。

删除表

操作表中的数据

操作表中的数据无疑就是对表进行增删改查呗,增删改查也是可以使用标准的 SQL 语句来进行的

添加数据

接下来我要插入三条数据到表中

db.transaction(function(tx){
  tx.executeSql(`insert into phone_book values (13122223333, 'xiaohehe1')`);
  tx.executeSql(`insert into phone_book values (13122223344, 'xiaohehe2')`);
  tx.executeSql(`insert into phone_book values (13122223345, 'xiaohehe3')`);
}, function(e) {
  console.log(e, "插入数据的过程出现不可预知的异常");
}, function(e) {
  console.log(e, "插入数据成功!");
});

但是很可惜,我插入不进去,系统给了我这样的错误提示。但是错误的信息也非常的容易看出来,是因为三个值必须要全部插入才行。

添加数据

也就是说,所有的字段都不能够有空值(这个说法是错误的,正确的说法是,要插入的内容必须是缺一不可的,即使是插入空值也要写 null),所以,我们需要对以上的 SQL 语句进行一个改进。

db.transaction(function(tx){
  tx.executeSql(`insert into phone_book values (13122223333, 'xiaohehe1', null)`);
  tx.executeSql(`insert into phone_book values (13122223344, 'xiaohehe2', null)`);
  tx.executeSql(`insert into phone_book values (13122223345, 'xiaohehe3', null)`);
}, function(e) {
  console.log(e, "插入数据的过程出现不可预知的异常");
}, function(e) {
  console.log(e, "插入数据成功!");
});

这一次,插入数据成功啦。

插入成功

点击刷新按钮即可展示出该表中我们插入的数据啦。

数据展示

如果我们想达到这样的效果,也就是年龄那个字段是空的,那我们该怎么设置呢。请看下面的代码

db.transaction(function(tx){
  tx.executeSql(`insert into phone_book values (13122223333, 'xiaohehe1', null)`);
  tx.executeSql(`insert into phone_book values (13122223344, 'xiaohehe2', null)`);
  tx.executeSql(`insert into phone_book values (13122223345, 'xiaohehe3', null)`);
}, function(e) {
  console.log(e, "插入数据的过程出现不可预知的异常");
}, function(e) {
  console.log(e, "插入数据成功!");
});

运行的效果如下。看到 age 这个字段已经是没有任何的东西,只是我们输入的值是 null。

数据

指定字段插入数据

例子

db.transaction(function(tx){
  tx.executeSql(`insert into phone_book(phone_number, name) values (13122223333, 'xiaohehe1')`);
  tx.executeSql(`insert into phone_book(phone_number, name) values (13122223344, 'xiaohehe2')`);
  tx.executeSql(`insert into phone_book(phone_number, name) values (13122223345, 'xiaohehe3')`);
}, function(e) {
  console.log(e, "插入数据的过程出现不可预知的异常");
}, function(e) {
  console.log(e, "插入数据成功!");
});

执行结果和上图是一致的,插入的数据也是成功的。

如果我们只插入 phone_number ,是不是会报错呀,我们来验证一下。

db.transaction(function(tx){
  tx.executeSql(`insert into phone_book(phone_number) values (13122223334)`);
  tx.executeSql(`insert into phone_book(phone_number) values (13122223336)`);
}, function(e) {
  console.log(e, "插入数据的过程出现不可预知的异常");
}, function(e) {
  console.log(e, "插入数据成功!");
});

运行的结果如下,果然会报错,因为我们将姓名字段设置成了非空的值。也就是说这个值是必须要填写的。

错误

如果我插入重复的电话号码会怎么样呢?当然会报错,因为我将电话号码设置成为了主键,由于主键不能重复,所以才导致的报错。

错误

更新数据

示例:修改 “xiaohehe1” 的电话号码

db.transaction(function(tx){
    tx.executeSql(`update phone_book set phone_number = 1111111 where name = 'xiaohehe1'`);
}, function(e) {
    console.log(e, "更新数据的过程出现不可预知的异常");
}, function(e) {
    console.log(e, "更新数据成功!");
});

运行结果如下,发现 “xiaohehe1” 的电话号码已经发生了变化。数据更新成功

QQ截图20210612231208.png

查询数据

示例:查询 phone_book 中年龄大于 11 岁的信息。

我们来看看返回的结果是在哪里进行展示的。

不过在此之前,还需要再次介绍 executeQuery 这个方法的另外两个参数。一个是外部传参,用数组来表示的,另外一个是回调函数,回调函数有两个参数。一个是事务,另一个是返回的结果。

db.transaction(function(tx){
   tx.executeSql(`select * from phone_book where age > 11`, [], function(tx, results) {
     console.log(results);
   });
}, function(e) {
   console.log(e, "更新数据的过程出现不可预知的异常");
}, function(e) {
   console.log(e, "查询数据成功!");
});

运行的结果如下,查询出的数据有两条!

删除数据

示例:删除年龄为 11 岁的信息

db.transaction(function(tx){
  tx.executeSql(`select * from phone_book where age > 11`, [], function(tx, results) {
    console.log(results);
  });
}, function(e) {
      console.log(e, "更新数据的过程出现不可预知的异常");
}, function(e) {
      console.log(e, "查询数据成功!");
});

运行的结果如下,发现等于11岁的那条数据被删除了耶。

至此,基本的 SQL 语句的使用就到此结束啦。

传值的问题

后续我们在插入数据,修改数据或者更改查询条件的值时可能需要使用到外部的参数。比如拿上面的查询数据来举例。

其中的问号,代表着占位符。

// 假设该数值可能是从文本框获取到。
var age = 11;

db.transaction(function(tx){
  tx.executeSql(`select * from phone_book where age > ?`, [age], function(tx, results) {
    console.log(results);
  });
}, function(e) {
    console.log(e, "更新数据的过程出现不可预知的异常");
}, function(e) {
    console.log(e, "查询数据成功!");
});

运行效果如下,发现通过外部传值的方式也是可以拿到的,并且也是可以正常地查询出来。

删除数据库

很遗憾,在 Web SQL 中,我们无法做到直接在 F12 中将数据库进行删除。即使刷新,你感觉它消失了,其实并没有消失,因为在刷新的过程中,Web SQL 中的数据库其实是在关闭哒,再次调用 openDatabase 会将数据库进行打开,并且原有的表都存在。

它占用的空间其实不会太大的,删不删除其实都是没有什么太大的区别的。

我找了很久,也没有找到直接删除它的方法,不过这无所谓的啦。

完整示例

完整示例请戳这查看 👉 点我点我