【HTML5】Web SQL Database【已废弃】(可能是最全详解,含各种参数介绍,以及一些SQL语句)

在阅读本篇文章之前,请先注意以下几点声明:

1. 原文:
 Beware. This specification is no longer in active maintenance and the Web Applications Working Group does not intend to maintain it further.
 译文:
   注意。此规范不再处于主动维护中,Web应用程序工作组不打算进一步维护它。

2. 原文:
 This document was on the W3C Recommendation track but specification work has stopped. The specification reached an impasse: all interested implementors have used the same SQL backend (Sqlite), but we need multiple independent implementations to proceed along a standardisation path.
 译文:
   这个文档是W3C推荐的,但是规范工作已经停止了。规范陷入了僵局:所有感兴趣的实现者都使用相同的SQL后端(Sqlite),但是我们需要多个独立的实现来沿着标准化的道路前进。

3. 原文:
 Each origin has an associated set of databases. Each database has a name and a current version. There is no way to enumerate or delete the databases available for an origin from this API.
 译文:
   每个起源都有一组相关联的数据库。每个数据库都有一个名称和当前版本。无法从此API枚举或删除源可用的数据库。


一、简介

1. HTML5 Web SQL 数据库是什么?

  • Web SQL Database API 并不是 HTML5 规范的一部分,但它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs;
  • Web SQL Database 使用 SQL 来操纵客户端数据库的 API,这些 API 是异步的,规范中使用的是 SQLlite(SQL后端);
  • Web SQL Database 可以在最新版的 Safari、Chrome 和 Opera 浏览器中工作;
  • Web SQL Database 目前还没有删除数据库的 API,不支持删库;
  • 曾被 W3C 推荐标准,现已被废弃,应避免使用…

2. 对应浏览器版本兼容表

在这里插入图片描述

3. 所拥有的属性及方法(API)

  PS:红色为核心方法,绿色的三个是通过原型对象找到的(关于用法,后面会讲)。

  • openDatabase() - 打开或新建一个数据库;
  • transaction() - 读写数据库事务并提交或者回滚执行(rollback 函数);
  • executeSql() - 执行实际的 SQL 查询语句;
  • version - 返回数据库版本号;
  • changeVersion() - 更改数据库版本号;
  • readTransaction() - 只读数据库事务(rollback 函数);


二、操作数据库

1. 如何检测浏览器是否支持?

  • 通过访问对象属性返回的布尔值检测:
if (window.openDatabase) {
	// 浏览器支持执行的代码
} else {
	alert('您的浏览器不支持 Web SQL Database。');
}
  • 使用 key in obj 语法检测:
if ('openDatabase' in window) {
	// 浏览器支持执行的代码
} else {
	alert('您的浏览器不支持 Web SQL Database。');
}
  • 使用 typeof 运算符检测:(localStorage 与 sessionStorage 使用 typeof(Storage) !== ‘undefined’ 检测)
// 检测 window 对象中是否存在 openDatabase 属性/方法(勿加引号成字符串)
if (typeof(openDatabase) !== 'undefined') {
	// 浏览器支持执行的代码
} else {
	alert('您的浏览器不支持 Web SQL Database。');
}
  • 使用 try…catch(err)… 语句(最简洁方便):
try {
	// 浏览器支持执行的代码
} catch (err) {
	// 浏览器不支持或其它报错内容
	alert(err);
}

2. 如何创建或打开数据库?

  通过 openDatabase() 方法来创建或打开数据库(存在则打开,不存在则新建);

// 新建/打开数据库
var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

console.log(db);	// Database 对象

对应的参数:

  • “userdata” - 参数1,需要创建或打开的数据库;
  • “1.0” - 参数2,数据库版本号,可修改,可为空,可为非数字,建议浮点数;
  • “user-data” - 参数3,数据库描述,可为空;
  • “2 * 1024 * 1024” - 参数4,数据库大小,此处为 2M(兆)【最大限制根据电脑硬盘情况而定】;
    • 我用 Edge 显示的可用大小为 50G 左右,其中还含有其它页、其它浏览器、等等之类的缓存功能共用大小…
      在这里插入图片描述
    • 打开另一个页面,各类缓存同样使用该内存空间:
      在这里插入图片描述
  • 参数5 - 创建回滚(在创建数据库后被调用);

使用调试 console.log(db) 获取 Database 对象:(这些便是所拥有的 API)
在这里插入图片描述

3. 如何获取与修改版本号?

  通过 version 属性来获取版本号;
  通过 changeVersion() 方法来修改版本号(无法删除,除非使用空值替换);

// 修改版本号
db.changeVersion('1.0', '新版本号');

console.log(db.version);	// 获取版本号

对应的参数:

  • “1.0” - 原有的,旧版本号;
  • “新版本号” - 新的,想要设置的版本号,可设置为任意字符串,但建议浮点数;

修改后需要修改对应的版号本才能打开数据库:
在这里插入图片描述

使用 console.log(db.version) 来获取版本号:(需打开数据库)
在这里插入图片描述

通过报错来获取版本号:(无需打开数据库,版本号不对自然报错提醒)在这里插入图片描述

4. 如何创建与删除数据表?

  通过 executeSql() 方法来执行 SQL查询语句,创建与删除数据表等操作;

a. 【创建数据表】
// 数据库事务操作(读写)
db.transaction(function(tx) {
		// 创建数据表并设置唯一
		tx.executeSql('create table if not exists login (id unique, username, userpassword)');

		console.log(tx);	// SQLTransaction 对象
});

对应的参数:

  • “function() {}” - 数据库事务(transaction)的回滚(rollback)函数;
  • “tx” - 回滚函数的形参,指向 SQL 事务(SQLTransaction)对象;
  • sql 参数:
    • “if not exists” - 如果该数据表不存在,则执行创建语句;
    • “login” - 需创建的数据表名;
    • “id unique” - 设置 “id” 字段,并设为唯一(类似主键用于约束);
    • 也可使用 “主键” 约束 “id” 字段:“id primary key”

使用 console.log(tx) 来获取版本号:(可以从返回的 SQLTransaction 对象中找到 executeSql() 方法)
在这里插入图片描述

对比 PHP 链接 MySQL 的语法:
<?php
	$dbhost = 'localhost';	// mysql服务器主机地址
	$dbuser = 'admin1';		// mysql用户名
	$dbpass = 'admin1';		// mysql用户名密码
	$dbdata = 'admin1';		// mysql数据库库名
	$conn = mysqli_connect($dbhost, $dbuser, $dbpass, $dbdata);

	// 关闭自动提交
	mysqli_autocommit($conn, false);

	// 插入数据
	$sql = 'insert into login'.
			'(user,password)'.
			'values'.
			'("'.$name.'","'.md5($password).'")';
	$retval = mysqli_query($conn, $sql);

	mysqli_commit($conn);	// 提交事务

	mysqli_rollback($conn);	// 回滚事务

	mysqli_close($conn);	// 关闭数据库
?>
  • executeSql() 相当于 mysqli_query() 用于执行 sql 语句;
  • transaction(),相当于 PHP 中的 mysqli_rollback() 用于回滚执行;

在这里插入图片描述

b. 【删除数据表】
db.transaction(function(tx) {
	// 删除数据表
	tx.executeSql('drop table login');
});


三、操作数据

1. 增

a. 【单条插入】
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(读写)
			db.transaction(function(tx) {

				// 静态插入
				tx.executeSql('insert into login (id, username, userpassword) values (1, "demo", "demo")');

				// 动态插入(参数式)【推荐】
				tx.executeSql('insert into login (id, username, userpassword) values (?, ?, ?)', [2, 'admin', 'admin']);

				// 动态插入(字符串 '+' 拼接)
				var id_a = 3;
				var uname_a = '"abcd"';
				var upw_a = '"abcd"';
				tx.executeSql('insert into login (id, username, userpassword) values (' + id_a + ', ' + uname_a + ', ' + upw_a + ')');

				// 动态插入(JSON 字符串式)
				var id_b = 4;
				var uname_b = JSON.stringify('aaaaaa');
				var upw_b = JSON.stringify('bbbbbb');
				tx.executeSql('insert into login (id, username, userpassword) values (' + id_b + ', ' + uname_b + ', ' + upw_b + ')');

				// 动态插入(字符串 concat() 方法拼接)
				var id_c = 5;
				var uname_c = '"test"';
				var upw_c = '"abc123"';
				var str = 'insert into login (id, username, userpassword) values';
				var sql = str.concat('(', id_c, ',', uname_c, ',', upw_c, ')');
				tx.executeSql(sql);
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>

需要注意的地方:

  • 1)关于 sql 语句:sql = ‘insert into login (id, username, userpassword) values (1, “demo”, “demo”)’;
    • “insert into login” - 表示 “在 login 数据表中插入数据”;
    • 其中,橙色为字段名绿色为对应字段插入的值,即 id = 1, username = demo, userpassword = demo
    • 在 sql 中,字符串必须加引号(注意,并不是在 js 中加了引号,去到 sql 语句就是字符串)
    • 错误格式:
      在这里插入图片描述
    • 正确格式1:(再加双引号)
      在这里插入图片描述
    • 正确格式2:(JSON 字符串格式)
      在这里插入图片描述
    • 为何 executeSql(sql, [1, ‘demo’, ‘demo’]) 没有问题,而上面的情况需要再次双引号?
      (因为经过处理,你看不见而已…这只是个例子,并表示官方如此处理)
      在这里插入图片描述
  • 2)关于 executeSql(sql, arr, function(){}) 参数
    • sql - 数据库查询语句,用于对数据库进行操作;
    • arr - 数组参数,存储用于匹配的 字段值 集合(仅能输入字段值,无法设置为字段名或其它);
      • 其中,arr 参数,当没有涉及到函数参数(即三个参数)时,可不写;当需要执行函数时,数组参数必须写,可以为 [] 空数组;
      • 即:executeSql(sql)
      • 即:executeSql(sql, [value1, value2, …], function(){})
      • 即:executeSql(sql, [], function(){})
      • 错误写法:executeSql(sql, function(){})
        在这里插入图片描述
      • Uncaught TypeError: Failed to execute ‘executeSql’ on ‘SQLTransaction’: The object must have a callable @@iterator property.
      • 未捕获类型错误:未能在’SQLTransaction’上执行’executeSql’:该对象必须具有可调用的@@iterator属性。
    • function(){} - 回滚(rollback)函数,用于 js 控制(读取、输出、等 js 操作);
      • 其中,function(){} 有两个参数:
        • tx - 上面说过了,指向 SQL 事务对象(SQLTransaction);
        • retval - 为 SQL 的返回值(数据);
tx.executeSql('(?, ?, ?)', [对应第一个?, 对应第二个?, 对应第三个?], function(tx, retval) {
	console.log('SQL的返回值:' + retval)
});
b. 【通过遍历逐条插入】

在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 创建年月日时分秒实例,自动补 '0'
		var g_year = (new Date()).getFullYear();
		var g_month = ((new Date()).getMonth()+1).toString().padStart(2,'0');
		var g_date = ((new Date()).getDate()).toString().padStart(2,'0');
		var g_hours = ((new Date()).getHours()).toString().padStart(2,'0');;
		var g_minutes = ((new Date()).getMinutes()).toString().padStart(2,'0');;
		var g_seconds = ((new Date()).getSeconds()).toString().padStart(2,'0');;

		var data = [
			{
				id : 1,
				username : '张三',
				userpassword : 'demo123',
				gettime : g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds
			},
			{
				id : 2,
				username : '李四',
				userpassword : 'hao666',
				gettime : g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds
			},
			{
				id : 3,
				username : '王五',
				userpassword : '123456',
				gettime : g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds
			},
			{
				id : 4,
				username : '赵六',
				userpassword : 'ssssfff',
				gettime : g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds
			},
			{
				id : 5,
				username : '田七',
				userpassword : 'admin223399',
				gettime : g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds
			},
		]

		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(读写)
			db.transaction(function(tx) {

				// 通过遍历数据长度,逐条插入
				for (var i = 0; i < data.length; i++) {

					// 参数式
					tx.executeSql('insert into login (id, username, userpassword, gettime) values (?, ?, ?, ?)', [data[i].id, data[i].username, data[i].userpassword, data[i].gettime]);
				}				
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>
c. 【插入多条数据】

在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 创建年月日时分秒实例,自动补 '0'
		var g_year = (new Date()).getFullYear();
		var g_month = ((new Date()).getMonth()+1).toString().padStart(2,'0');
		var g_date = ((new Date()).getDate()).toString().padStart(2,'0');
		var g_hours = ((new Date()).getHours()).toString().padStart(2,'0');;
		var g_minutes = ((new Date()).getMinutes()).toString().padStart(2,'0');;
		var g_seconds = ((new Date()).getSeconds()).toString().padStart(2,'0');;

		var data = [
			{
				id : 1,
				username : '张三',
				userpassword : 'demo123',
				gettime : g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds
			},
			{
				id : 2,
				username : '李四',
				userpassword : 'hao666',
				gettime : g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds
			},
			{
				id : 3,
				username : '王五',
				userpassword : '123456',
				gettime : g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds
			},
			{
				id : 4,
				username : '赵六',
				userpassword : 'ssssfff',
				gettime : g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds
			},
			{
				id : 5,
				username : '田七',
				userpassword : 'admin223399',
				gettime : g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds
			},
		]

		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(读写)
			db.transaction(function(tx) {		

				// 参数式
				tx.executeSql('insert into login (id, username, userpassword, gettime) values' +
					'(?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?)',
					[
						data[0].id, data[0].username, data[0].userpassword, data[0].gettime,
						data[1].id, data[1].username, data[1].userpassword, data[1].gettime,
						data[2].id, data[2].username, data[2].userpassword, data[2].gettime,
						data[3].id, data[3].username, data[3].userpassword, data[3].gettime,
						data[4].id, data[4].username, data[4].userpassword, data[4].gettime
					]);			
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>


2. 查

a. 【静态查询所有列】

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(只读)
			db.readTransaction(function(tx) {

				// 静态查询(所有列)
				tx.executeSql('select * from login', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(查询所有列表数据)');
					console.log('//列出所有数据')
					console.table(retval.rows);
				});

				// 静态查询(所有列)
				tx.executeSql('select * from login where id=1', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(匹配单字段查询所有数据)');
					console.log('//列出符合 id = 1 的所有数据');
					console.table(retval.rows);
				});

				// 静态查询(所有列)
				tx.executeSql('select * from login where id=2 and username="admin" and userpassword="admin"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(匹配多字段查询所有数据)');
					console.log('//列出符合 id = 2, username = admin 的所有数据');
					console.table(retval.rows);
				});

				// 静态查询(所有列)
				tx.executeSql('select * from login where username like "d%"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(半模糊匹配单字段查询所有数据)');
					console.log('//列出符合 username 字段值开头包含 "d" 的所有数据');
					console.table(retval.rows);
				});

				// 静态查询(所有列)
				tx.executeSql('select * from login where username like "%d"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(半模糊匹配单字段查询所有数据)');
					console.log('//列出符合 username 字段值尾部包含 "d" 的所有数据');
					console.table(retval.rows);
				});

				// 静态查询(所有列)
				tx.executeSql('select * from login where username like "%d%"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(全模糊匹配单字段查询所有数据)');
					console.log('//列出符合 username 字段值包含 "d" 的所有数据');
					console.table(retval.rows);
				});
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>
b. 【静态查询单列】

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(只读)
			db.readTransaction(function(tx) {

				// 静态查询(单列)
				tx.executeSql('select userpassword from login', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(查询单字段/单列数据)');
					console.log('//列出 userpassword 字段的所有数据')
					console.table(retval.rows);
				});

				// 静态查询(单列)
				tx.executeSql('select userpassword from login where id=1', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(匹配单字段查询单列数据)');
					console.log('//列出符合 id = 1 的 userpassword 字段的所有数据');
					console.table(retval.rows);
				});

				// 静态查询(单列)
				tx.executeSql('select userpassword from login where id=2 and username="admin"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(匹配多字段查询单列数据)');
					console.log('//列出符合 id = 2, username = admin 的 userpassword 字段的所有数据');
					console.table(retval.rows);
				});

				// 静态查询(单列)
				tx.executeSql('select userpassword from login where userpassword like "d%"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(半模糊匹配单字段查询单列数据)');
					console.log('//列出符合 userpassword 字段值开头包含 "d" 的 userpassword 字段的所有数据');
					console.table(retval.rows);
				});

				// 静态查询(单列)
				tx.executeSql('select userpassword from login where userpassword like "%d"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(半模糊匹配单字段查询单列数据)');
					console.log('//列出符合 userpassword 字段值尾部包含 "d" 的 userpassword 字段的所有数据');
					console.table(retval.rows);
				});

				// 静态查询(单列)
				tx.executeSql('select userpassword from login where userpassword like "%d%"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(全模糊匹配单字段查询所有数据)');
					console.log('//列出符合 userpassword 字段值包含 "d" 的 userpassword 字段的所有数据');
					console.table(retval.rows);
				});
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>
c. 【静态查询双列】

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(只读)
			db.readTransaction(function(tx) {

				// 静态查询(双列)
				tx.executeSql('select username, userpassword from login', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(查询两列数据)');
					console.log('//列出 username, userpassword 字段所有数据')
					console.table(retval.rows);
				});

				// 静态查询(双列)
				tx.executeSql('select username, userpassword from login where id=1', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(匹配单字段查询两列数据)');
					console.log('//列出符合 id = 1 的 username, userpassword 字段所有数据');
					console.table(retval.rows);
				});

				// 静态查询(双列)
				tx.executeSql('select username, userpassword from login where id=2 and username="admin" and userpassword="admin"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(匹配多字段查询两列数据)');
					console.log('//列出符合 id = 2, username = admin 的 username, userpassword 字段所有数据');
					console.table(retval.rows);
				});

				// 静态查询(双列)
				tx.executeSql('select username, userpassword from login where username like "d%"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(半模糊匹配单字段查询两列数据)');
					console.log('//列出符合 username 字段值开头包含 "d" 的 username, userpassword 字段所有数据');
					console.table(retval.rows);
				});

				// 静态查询(双列)
				tx.executeSql('select username, userpassword from login where username like "%d"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(半模糊匹配单字段查询两列数据)');
					console.log('//列出符合 username 字段值尾部包含 "d" 的 username, userpassword 字段所有数据');
					console.table(retval.rows);
				});

				// 静态查询(双列)
				tx.executeSql('select username, userpassword from login where username like "%d%"', [], function(tx, retval) {
					// 控制台 table 输出
					console.warn('静态查询(全模糊匹配单字段查询两列数据)');
					console.log('//列出符合 username 字段值包含 "d" 的 username, userpassword 字段所有数据');
					console.table(retval.rows);
				});
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>
d. 【动态查询】

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(只读)
			db.readTransaction(function(tx) {

				// 动态查询(双列)
				tx.executeSql('select username, userpassword from login where id=?', [1], function(tx, retval) {
					// 控制台 table 输出
					console.warn('动态查询(匹配单字段查询两列数据)');
					console.log('//列出符合 id = 1 的 username, userpassword 字段所有数据');
					console.table(retval.rows);
				});

				// 动态查询(所有列)
				tx.executeSql('select * from login where id=? and username=? and userpassword=?', [2, 'admin', 'admin'], function(tx, retval) {
					// 控制台 table 输出
					console.warn('动态查询(匹配多字段查询所有数据)');
					console.log('//列出符合 id = 2, username = admin 的所有数据');
					console.table(retval.rows);
				});

				// 动态查询(双列)
				tx.executeSql('select id, userpassword from login where username like ?', ['d%'], function(tx, retval) {
					// 控制台 table 输出
					console.warn('动态查询(半模糊匹配单字段查询两列数据)');
					console.log('//列出符合 username 字段值开头包含 "d" 的 id, userpassword 字段所有数据');
					console.table(retval.rows);
				});

				// 动态查询(单列)
				tx.executeSql('select id from login where username like ?', ['%d'], function(tx, retval) {
					// 控制台 table 输出
					console.warn('动态查询(半模糊匹配单字段查询单数据)');
					console.log('//列出符合 username 字段值尾部包含 "d" 的 id 字段的数据');
					console.table(retval.rows);
				});

				// 动态查询(所有列)
				tx.executeSql('select * from login where username like ?', ['%d%'], function(tx, retval) {
					// 控制台 table 输出
					console.warn('动态查询(全模糊匹配单字段查询所有数据)');
					console.log('//列出符合 username 字段值包含 "d" 的所有数据');
					console.table(retval.rows);
				});
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>
e. 更多的 SQL 查询...

  太多了,就不写了,无非就是使用 sql 语句查询,知道怎么用 js 传递改变参数就行了…

需要注意的地方:

  • 在查询数据中,我使用了 readTransaction() 方法,此方法为 只读 的 SQL 事务,无法进行修改删除等操作;当然你也可以使用 transaction()(可读可写),这在对数据进行读取中,并不影响,但 readTransaction() 无法用于其它数据操作中(由于回滚原因不会报错,但值会无反应);
  • 关于 sql 中的参数:
    • 模糊查询:
      • 模糊查询并不是使用 ‘=’ 来匹配,而是 ‘like’:sql = ‘select * from login where username like “%d%”’;
      • ‘d%’ - 开头匹配 d,并对右边进行模糊查询;
      • ‘%d’ - 尾部匹配 d,并对左边进行模糊查询;
      • ‘%d%’ - 左右模糊查询,需匹配至少一个 d;
    • “select” ~ “from” 之间的参数,表示需要查询的字段,即想要查询哪几列;
      • “select * from” - 查询所有字段,所有列的数据;
      • “select id from” - 仅查询 id 字段,这一列的数据;
      • “select username, userpassword from” - 仅查询 username, userpassword 字段,这两列的数据(注意,是逗号,不是 and)
      • 正确写法:select username, userpassword from login;
      • 错误写法:select username and userpassword from login;
      • 同样的,所有 SQL 查询语句中,多个字段名匹配用逗号连接,而字段值则采用 and 连接:
        在这里插入图片描述
      • 如修改数据亦如此(下面会说);

3. 改

在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(读写)
			db.transaction(function(tx) {

				// 静态修改
				tx.executeSql('update login set userpassword="change" where id=1');

				// 动态修改(参数式)【推荐】
				tx.executeSql('update login set username=? , userpassword=? where id=?', ['id2', 'change', 2]);	// 改双值

				// 动态修改(字符串 '+' 拼接)
				var id_a = 3;
				var uname_a = '"id3"';	// 需要修改的值
				var upw_a = '"change"';	// 需要修改的值
				tx.executeSql('update login set username=' + uname_a + ', userpassword=' + upw_a + ' where id=' + id_a);	// 改双值

				// 动态修改(JSON 字符串式)
				var uname_b = JSON.stringify('aaaaaa');
				var upw_b = JSON.stringify('change');	// 需要修改的值
				tx.executeSql('update login set userpassword=' + upw_b + ' where username=' + uname_b);

				// 动态修改(字符串 concat() 方法拼接)
				var id_c = 5;
				var uname_c = '"test"';
				var upw_c = '"change"';
				var str1 = 'update login set userpassword=';
				var str2 = ' where username=';
				var str3 = ' and id='
				var sql = str1.concat(upw_c, str2, uname_c, str3, id_c);
				tx.executeSql(sql);
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>

需要注意的地方:

  • 在查询数据中写需注意的地方也有提到,所有 SQL 查询语句中,多个字段名匹配用逗号连接,而字段值则采用 and 连接:
    在这里插入图片描述

4. 删

a. 【单条删除】
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(读写)
			db.transaction(function(tx) {

				// 静态删除
				tx.executeSql('delete from login where id=1');

				// 动态删除(参数式)【推荐】
				// tx.executeSql('delete from login where id=?', [2]);	// 单字段匹配
				tx.executeSql('delete from login where id=? and userpassword=?', [2, 'change']);	// 多字段匹配

				// 动态删除(字符串 '+' 拼接)
				var uname_a = '"id3"';
				var upw_a = '"change"';
				// tx.executeSql('delete from login where username=' + uname_a);	// 不推荐单查询非唯一字段
				tx.executeSql('delete from login where username=' + uname_a + ' and userpassword=' + upw_a);	// 多字段匹配

				// 动态删除(JSON 字符串式)
				var uname_b = JSON.stringify('aaaaaa');
				var upw_b = JSON.stringify('change');
				tx.executeSql('delete from login where username=' + uname_b + ' and userpassword=' + upw_b);	// 多字段匹配

				// 动态删除(字符串 concat() 方法拼接)
				var id_c = 5;
				var uname_c = '"test"';
				var upw_c = '"change"';
				var str1 = 'delete from login where id=';
				var str2 = ' and username=';
				var str3 = ' and userpassword='
				// var sql = str1.concat(id_c);	// 单字段匹配
				var sql = str1.concat(id_c, str2, uname_c, str3, upw_c);	//	多字段匹配
				tx.executeSql(sql);
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>
b. 【通过遍历逐条删除】
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(读写)
			db.transaction(function(tx) {

				// 获取所有 id 值,再遍历,当然,也可以用 * 通配符,能获取到所有数据行数即可
				tx.executeSql('select id from login', [], function(tx, retval) {

					// 获取返回结果的行数
					var len = retval.rows.length;

					// 通过遍历,进行逐行 id 匹配删除数据
					for (var i = 0; i < len; i++) {
						var ids = retval.rows[i].id;

						// 拼接式
						// tx.executeSql('delete from login where id=' + ids);
						
						// 参数式
						tx.executeSql('delete from login where id=?', [ids]);
					}

				});
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>
c. 【删除所有数据】
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>
	<div id="retval"></div>
	<script type="text/javascript">
		// 检测浏览器是否支持或报错
		try {
			// 创建/打开 userdata 数据库
			var db = openDatabase('userdata', '1.0', 'users data', 2 * 1024 * 1024);

			// 数据库事务操作(读写)
			db.transaction(function(tx) {

				// 清空数据表数据
				tx.executeSql('delete from login');
			});
		} catch (err) {
			alert(err);
		}
	</script>
</body>
</html>

需要注意的地方:

  • 遍历删除数据,需要先获取得到数据,才能进行匹配删除,而只有 select 字段名 from 表名 语句才会返回 sql 的值。
  • sql = ‘delete from login’ 清空数据表,保留表;
  • sql = ‘drop table login’ 则删除表;


四、一些适用于 Web SQL 的 SQL 查询语句

SQL 运算符、操作符、通配符速查表

SQL 运算符
AND 和 OR 可在 WHERE 子语句中把两个或多个条件结合起来
运算符描述
AND(并且)如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。
OR(或者)如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录。
NOT(非)用于否定条件,取反。
, (逗号) 用于 "UPDATE、SELECT" 主句,"ORDER BY" 子句,用于拼接多项列。
SQL 操作符
操作符描述
=等于
<> 或 !=不等于
>大于
<小于
>=大于等于
<=小于等于
BETWEEN 在某个范围内
IN在规定单或多个值内
LIKE搜索某种模式(大小写不敏感)
GLOB搜索某种模式(大小写敏感)
SQL 通配符
通配符描述
%(LINK 使用)替代零个、一个或多个字符或数字
_(LINK 使用)仅替代一个字符或数字
[charlist](LINK 使用)字符列中的任何单一字符或数字
[^charlist] 或 [!charlist](LINK 使用)不在字符列中的任何单一字符或数字
*(GLOB 使用)替代零个、一个或多个字符或数字
?(GLOB 使用)仅替代一个字符或数字

前提:如何使用浏览器输入 SQL 语句操作 Web SQL Database?

  • 首先,你必须得用 js 脚本为当前网站创建或打开一个 Web SQL 数据库(最好使用 html 文件的 js 脚本打开,因为这个库,一刷新页面又没了,需要一个"索引"来连接它,别以为它没了就会销毁,它只是消失了,但数据还会保留的):
    在这里插入图片描述
  • 使用 html 文件 js 脚本连接数据库,并打开页面:
    在这里插入图片描述
  • 打开数据库,在库的那项中,就能输入 SQL 语句了:
    在这里插入图片描述
  • 输入关键字时,会有提示,按 “→” 自动填充,前往别按 “Enter” (回车键),它会之间中断输入执行语句:
    在这里插入图片描述
  • 通过输入 SQL 语句对数据进行操作,插入、修改、删除、查询:
    在这里插入图片描述
  • 错误语句报错:
    在这里插入图片描述
  • 一个数据库可创建多个数据表:
    在这里插入图片描述

1. 创建数据表并设置字段:

关键字

a. 【"IF NOT EXISTS"】

“如果不存在(就执行)”:设置此关键词后,即使创建同名表不成功也不会报错(报错会中断后继执行,特别在用 JS 控制的时候)。

CREATE TABLE IF NOT EXISTS 表名(字段1, 字段2, 字段3, ...);

在这里插入图片描述
在这里插入图片描述

约束

b. 【NOT NULL】

“非空”:指示某列不能存储 NULL 值。

CREATE TABLE 表名 (字段1 NOT NULL, 字段2, 字段3, ...);

在这里插入图片描述

c. 【UNIQUE】

“唯一”:保证某列的每行必须有唯一的值。

CREATE TABLE 表名 (字段1 UNIQUE, 字段2, 字段3, ...);

在这里插入图片描述

d. 【CHECK】

“核查”:保证列中的值符合指定的条件。如:check(a>10),表示 a 字段的值只能大于 10,否则报错。

CREATE TABLE 表名 (字段1 CHECK(限制条件), 字段2, 字段3, ...);

注意,当值为非数字时,不会报错,这个是 Web SQL 的问题,本来需要设置 int 类型的,这里设置了无效。
在这里插入图片描述
在这里插入图片描述

e. 【DEFAULT】

“默认”:规定没有给列赋值时的默认值。如:default ‘0’,当该字段不插入值时,自动插入 “0” 值。

CREATE TABLE 表名 (字段1 DEFAULT '默认值', 字段2, 字段3, ...);

在这里插入图片描述

f. 【PRIMARY KEY】

“主键”:NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。

CREATE TABLE 表名 (字段1 PRIMARY KEY, 字段2, 字段3, ...);

可得出:在这里,主键已经废了,仅仅只有 “唯一” 特性的主键,那干嘛不用 “唯一” 约束?
在这里插入图片描述

g. 【PRIMARY KEY()】

“复合主键”:在同一个表内设置多个"主键"。

CREATE TABLE 表名 (字段1, 字段2, 字段3, ..., PRIMARY KEY(字段1, 字段2, 字段3, ...));

复合主键也已经废了,仅仅只有 “唯一” 特性…
在这里插入图片描述

数据类型

  Web SQL 问题真多,int、varchar等数据类型虽然能设置,但是没有限制值的输入,比如,虽然设置了 int 整数型,但你插入字符串也可以…
  所以,这些数据类型在这里是废了,可以舍弃不用了,还有什么自增属性等也失效了…

h. 【TIMESTAMP】

“时间戳”:以 “年-月-日 时-分-秒” 的格式插入值。

CREATE TABLE 表名 (字段1 TIMESTAMP, 字段2, 字段3, ...);
  • 时间类有四种:DATE(日期)、TIME(时间)、DATETIME(日期时间)、TIMESTAMP(时间戳),但在 Web SQL 中,四种时间插入的值都是相同的,所以选一个即可,推荐 “TIMESTAMP”(时间戳)
    【Web SQL 的问题,虽然很多正确的 SQL 语句没报错,但却没有得到理想的结果】
    在这里插入图片描述
    在这里插入图片描述

其他属性

i. 【CURRENT_TIMESTAMP】

“当前时间戳”:跟随其它字段值的插入而自动添加时间戳。

// 时间戳
CREATE TABLE 表名 (字段1 TIMESTAMP CURRENT_TIMESTAMP, 字段2, 字段3, ...);
  • 综上,有很多 SQL 语句在 Web SQL 中都失效了,现在又没有人去维护它,可以说 Web SQL 已经是个残缺品了,怪不得被废弃…
  • SQL语句并不区分大小写,但字段值区分大小写,比如:username=“demo”。
    • 可识别:sql = ‘select username from login where USERname=“demo”’;
    • 不可识别:sql = ‘select username from login where username=“DEMO”’;

2. 删除数据表

区分:DELETE FROM 表名,这个是清空表,保留字段,保留表,但 DROP TABLE 表名 是删除、摧毁表,不保留字段;

DROP TABLE 已存在表名;

3. 插入数据

插入值

a. 【对应字段名插入值】(插入单条)
INSERT INTO 表名 VALUES (1,2,3, ...);
  • 此举需对应字段名位置插入值:
    在这里插入图片描述
    在这里插入图片描述
  • 插入值少一个不行,多一个也不行:
    在这里插入图片描述
b. 【指定字段名插入值】(插入单条)
INSERT INTO 表名 (字段1, 字段2) VALUES (1,2);
  • 对指定字段进行插入值:
    在这里插入图片描述
    在这里插入图片描述
  • 也要对应所指定的字段名插入值,同样多一个值不行,少一个值不行:
    在这里插入图片描述
c. 【对应字段名插入值】(插入多条)
INSERT INTO 表名 VALUES (1,2,3, ...), (值x, 值y, 值z, ...), ...;
  • 一个括号代表一行值,括号内的值对应字段位置插入多行值:
    在这里插入图片描述
    在这里插入图片描述
  • (括号内)也是多一个值不行,少一个值不行:
    在这里插入图片描述
d. 【指定字段名插入值】(插入多条)
INSERT INTO 表名 (字段1, 字段2) VALUES (1,2), (值x, 值y), ...;
  • 按指定字段,插入多行值:
    在这里插入图片描述
    在这里插入图片描述
  • 同样的,(括号内)多一个值不行,少一个值不行:
    在这里插入图片描述

新增列

e. 【尾部插入字段名】(新增单列)

  只有尾部插入列是可用的,其它什么开头插入列、修改字段数据类型、删除列均失效或报错…

ALTER TABLE 表名 ADD 字段名 数据类型;

// 或者

ALTER TABLE 表名 ADD COLUMN 字段名 数据类型;
  • 不需要设置数据类型,因为数据类型在 Web SQL 中失效了…
    在这里插入图片描述

4. 修改数据

逐个修改 单/多 项

a. 【匹配单字段值修改单项值】(修改单项)
UPDATE 表名 SET 字段 = 想改的值 WHERE 字段 =;

在这里插入图片描述

b. 【匹配多字段值修改单项值】(修改单项)
UPDATE 表名 SET 字段 = 想改的值 WHERE 字段1 =1 AND 字段2 =2 AND ...;

在这里插入图片描述

c. 【匹配单字段值修改多项值】(修改多项)
UPDATE 表名 SET 字段x = 想改的值, 字段y = 想改的值, ... WHERE 字段1 =1;

在这里插入图片描述

d. 【匹配多字段值修改多项值】(修改多项)
UPDATE 表名 SET 字段x = 想改的值, 字段y = 想改的值, ... WHERE 字段1 =1 AND 字段2 =2 AND ...;

在这里插入图片描述

批量修改 单/多 列

e. 【修改单列同值】(修改单列)
UPDATE 表名 SET 字段 = 想改的值;

在这里插入图片描述

f. 【修改多列同值】(修改多列)
UPDATE 表名 SET 字段1 = 想改的值1, 字段2 = 想改的值2, ...;

在这里插入图片描述

5. 查询数据(N种查询…)

在这里插入图片描述

“SELECT” 主句

a. 【选取所有列】
SELECT * FROM 表名;

在这里插入图片描述

b. 【选取单列】
SELECT 字段 FROM 表名;

在这里插入图片描述

c. 【选取多列】
SELECT 字段1, 字段2, ... FROM 表名;

在这里插入图片描述

“WHERE” 子句

d. 【"=" 等于】

注意:如果希望精确到一行,可选择唯一字段,来精确匹配。

SELECT * FROM 表名 WHERE 字段 =;

在这里插入图片描述

e. 【"<> 或 !=" 不等于】
SELECT * FROM 表名 WHERE 字段 <>;

// 或者

SELECT * FROM 表名 WHERE 字段 !=;

在这里插入图片描述

f. 【">" 大于】

“>=” 大于等于同理
注意:一般用于筛选数值(不带引号),而不是字符串;非数值项被保留…

SELECT * FROM 表名 WHERE 字段 >;

在这里插入图片描述

g. 【"<" 小于】

“<=” 小于等于同理
注意:一般用于筛选数值(不带引号),而不是字符串;在这里居然筛掉了非数值项。

SELECT * FROM 表名 WHERE 字段 <;

在这里插入图片描述

“NOT、AND、OR、逗号” 运算符

h. 【"NOT" 否定】(子句)
SELECT * FROM 表名 WHERE NOT 条件;

在这里插入图片描述

i. 【"AND" 和/并且】(子句)
SELECT * FROM 表名 WHERE 条件1 AND 条件2;

在这里插入图片描述

j. 【"OR" 或者】(子句)
SELECT * FROM 表名 WHERE 条件1 OR 条件2;

在这里插入图片描述

k. 【"," 逗号】(主句)
SELECT1,2 FROM 表名;

在这里插入图片描述

“BETWEEN” 操作符,区间查询

l. 【区间值为数值时】
SELECT * FROM 表名 WHERE 字段 BETWEEN 数值1 AND 数值2;

在这里插入图片描述

m. 【区间值为字符串时】
SELECT * FROM 表名 WHERE 字段 BETWEEN 字符串1 AND 字符串2;

在这里插入图片描述

“IN” 操作符,范围查询

n. 【"IN" 在之内】
SELECT * FROM 表名 WHERE 字段 IN (1,2,3, ...);

在这里插入图片描述

“ORDER BY” 子句,排序查询

o. 【"ASC" 升序/顺序】
SELECT * FROM 表名 ORDER BYASC;

在这里插入图片描述

p. 【"DESC" 降序/倒序】
SELECT * FROM 表名 ORDER BYDESC;

在这里插入图片描述

q. 【升序、降序搭配】

注意:第一个排序条件优先级最大,第二个紧跟其后…

SELECT * FROM 表名 ORDER BY1 ASC,2 DESC,3 ...;

// 或者

SELECT * FROM 表名 ORDER BY1 DESC,2 ASC,3 ...;

在这里插入图片描述

“LIKE” 操作符,模糊查询(不区分大小写)

r. 【"%" 替代任意数量字符或数字】
// 值中,有"字符串"
SELECT * FROM 表名 WHERELIKE '%字符%';

// 值中,"字符串"开头
SELECT * FROM 表名 WHERELIKE '字符%';

// 值中,"字符串"结尾
SELECT * FROM 表名 WHERELIKE '%字符';

// 值中,开头结尾固定,中间模糊查询
SELECT * FROM 表名 WHERELIKE '字符%字符';

在这里插入图片描述

s. 【"_" 仅替代一个字符或数字】
// 开头结尾各替换一个字符
SELECT * FROM 表名 WHERELIKE '_字符串_';
// 开头结尾各替换多个字符
SELECT * FROM 表名 WHERELIKE '___字符串________';

// 开头替换一个字符
SELECT * FROM 表名 WHERELIKE '_字符串';
// 开头替换多个字符
SELECT * FROM 表名 WHERELIKE '______字符串';

// 结尾替换一个字符
SELECT * FROM 表名 WHERELIKE '字符串_';
// 结尾替换多个字符
SELECT * FROM 表名 WHERELIKE '字符串_______';

// 中间替换一个字符
SELECT * FROM 表名 WHERELIKE '字符串_字符串';
// 中间替换多个字符
SELECT * FROM 表名 WHERELIKE '字符串______字符串';

在这里插入图片描述

"[charlist]、[^charlist]、[!charlist]" 失效

在这里插入图片描述

“GLOB” 操作符,模糊查询(区分大小写)

t. 【"*" 替代任意数量字符或数字】
// 值中,有"字符串"
SELECT * FROM 表名 WHERE 列 GLOB '*字符*';

// 值中,"字符串"开头
SELECT * FROM 表名 WHERE 列 GLOB '字符*';

// 值中,"字符串"结尾
SELECT * FROM 表名 WHERE 列 GLOB '*字符';

// 值中,开头结尾固定,中间模糊查询
SELECT * FROM 表名 WHERE 列 GLOB '字符*字符';

在这里插入图片描述

u. 【"?" 仅替代一个字符或数字】
// 开头结尾各替换一个字符
SELECT * FROM 表名 WHERELIKE '?字符串?';
// 开头结尾各替换多个字符
SELECT * FROM 表名 WHERELIKE '???字符串????';

// 开头替换一个字符
SELECT * FROM 表名 WHERELIKE '?字符串';
// 开头替换多个字符
SELECT * FROM 表名 WHERELIKE '?????字符串';

// 结尾替换一个字符
SELECT * FROM 表名 WHERELIKE '字符串?';
// 结尾替换多个字符
SELECT * FROM 表名 WHERELIKE '字符串?????';

// 中间替换一个字符
SELECT * FROM 表名 WHERELIKE '字符串?字符串';
// 中间替换多个字符
SELECT * FROM 表名 WHERELIKE '字符串????字符串';

在这里插入图片描述

“GROUP BY” 子句,分组查询

v. 【对某列进行分组】

分组后,保留最先插入的数据。

SELECT * FROM 表名 GROUP BY;

在这里插入图片描述

w. 【"SUM()" 列求和】

注意:SUM() 函数,只保留数字,对非数字的字符自动转换成 “0”,比如 “aa445aa”,转换成 “445”;“aa”,转换成 “0”。
SUM() 将列的数据进行求和,与 GROUP BY 配合,对合并的数据进行求和统计。

SELECT1, SUM(2), SUM(3), ... FROM 表名 GROUP BY 需操作的列;

在这里插入图片描述

“HAVING” 子句,过滤分组查询

x. 【过滤出现次数】
SELECT * FROM 表名 GROUP BYHAVING COUNT() 操作符 次数;

在这里插入图片描述

“DISTINCT” 关键字,去重查询

y. 【单列去重】
SELECT DISTINCTFROM 表名;

在这里插入图片描述

z. 【多列去重】
SELECT DISTINCT1,2,3, ... FROM 表名;

在这里插入图片描述

“OFFSET、LIMIT” 子句,限制查询

aa. 【"LIMIT" 查询多少行】
SELECT * FROM 表名 LIMIT 查询行数;

在这里插入图片描述

【"OFFSET" 从第几行开始】不支持

在这里插入图片描述

6. 删除数据

a. 【单行删除】
DELETE FROM 表名 WHERE 字段 =;

在这里插入图片描述

a. 【清空数据表】

区分:DELETE FROM 表名,是清空表,保留字段,保留表,但 DROP TABLE 表名 是删除、摧毁表,不保留字段;

DELETE FROM 表名;

在这里插入图片描述



五、Web SQL Database实例

代码虽然粗制滥造,但能实现功能就懒得改了。
在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
	<style type="text/css">
		body {min-width: 625px;}
		.signup, .update {float: left;padding: 20px;border: 1px solid #c3c3c3;}
		.signup {margin-right: 10px;}
		.wrap {text-align: center;}
		input[type="button"] {margin: 0 10px;padding: 5px 20px;}
		#mask {display: none;}
	</style>
	<script type="text/javascript">
		window.onload = function() {
			// 表单
			var uname = document.getElementById('uname');
			var upw = document.getElementById('upw');
			var get_uname = document.getElementById('get_uname');
			var show_data = document.getElementById('show_data');
			var newpw = document.getElementById('newpw');
			var msg = document.getElementById('msg');
				msg.innerHTML = '';

			// 按钮
			var sub_btn = document.getElementById('sub_btn');
			var rst_btn = document.getElementById('rst_btn');
			var chg_btn = document.getElementById('chg_btn');
			var del_btn = document.getElementById('del_btn');
			var confirm = document.getElementById('confirm');
			var show_btn = document.getElementById('show_btn');
			var clr_btn = document.getElementById('clr_btn');

			// 隐藏、显示
			var mask = document.getElementById('mask');

			// 数据库信息
			var db_data = {
				dbName : 'userdata',
				dbVersion : '1.0',
				dbtag : 'users data',
				dbRAM : 2 * 1024 * 1024
			}

			// 创建年月日时分秒实例,自动补 '0'
			var g_year = (new Date()).getFullYear();
			var g_month = ((new Date()).getMonth()+1).toString().padStart(2,'0');
			var g_date = ((new Date()).getDate()).toString().padStart(2,'0');
			var g_hours = ((new Date()).getHours()).toString().padStart(2,'0');;
			var g_minutes = ((new Date()).getMinutes()).toString().padStart(2,'0');;
			var g_seconds = ((new Date()).getSeconds()).toString().padStart(2,'0');;
			var gettime = g_year+'-'+g_month+'-'+g_date+' '+g_hours+':'+g_minutes+':'+g_seconds;

			try {
				var db = openDatabase(db_data.dbName, db_data.dbVersion, db_data.dbtag, db_data.dbRAM);

				// 自动创建数据表(若不存在)
				db.transaction(function(tx) {
					tx.executeSql('create table if not exists login (id unique, username, userpassword, gettime)');
				});

				// 注册账号
				sub_btn.onclick = function() {
					db.transaction(function(tx) {
						// 查询账号是否存在
						tx.executeSql('select * from login where username=?', [uname.value], function(tx, retval) {
							if (retval.rows.length > 0) {
								msg.innerHTML = '错误提示:账号已存在,请重新输入!';
							} else {
								// 查询所有账号
								tx.executeSql('select * from login', [], function(tx, retval) {
									// 获取最后一项 id,并自增
									var uid;
									var len = retval.rows.length;
									if (len > 0) {
										uid = retval.rows[len-1].id + 1;
									} else {
										uid = 1;
									}
									if (uname.value !== '' && upw.value !== '') {
										// 插入数据
										tx.executeSql('insert into login (id, username, userpassword, gettime) values (?, ?, ?, ?)',
											[uid, uname.value, upw.value, gettime], function() {
											alert('注册成功!');
											uname.value = '';
											upw.value = '';
											msg.innerHTML = '';
										});
									} else {
										msg.innerHTML = '错误提示:请勿提交空值!';
									}
								});
							}
						});
					});
				};

				// 修改查询
				chg_btn.onclick = function() {
					db.transaction(function(tx) {
						if (get_uname.value !== '') {
							// 判断是否存在账号
							tx.executeSql('select * from login where username=?', [get_uname.value], function(tx, retval) {
								if (retval.rows.length > 0) {
									if (mask.getAttribute('data-disable') === null) {
										// 初始计数
										var i = 0;
										// 计时器淡入
										setInterval(function() {
											if (i < 10) {
												i++;
												mask.style.display = 'block';
												mask.style.opacity = i/10;
											}
										}, 100);
										// 控制开关,防止反复点击
										mask.setAttribute('data-disable', 'on');
									}
								} else {
									msg.innerHTML = '错误提示:账号不存在,请重新输入!';
								}
							});
						} else {
							msg.innerHTML = '错误提示:请勿提交空值!';
						}
					});
					msg.innerHTML = '';
				}

				// 修改密码
				confirm.onclick = function() {
					db.transaction(function(tx) {
						if (newpw.value !== '') {
							// 检测账号是否存在
							tx.executeSql('select * from login where username=?', [get_uname.value], function(tx, retval) {
								// 判断密码是否存在
								if (newpw.value !== retval.rows[0].userpassword) {
									// 修改密码
									tx.executeSql('update login set userpassword=? where username=?', [newpw.value, get_uname.value], function() {

										get_uname.value = '';
										newpw.value = '';
										alert('新密码修改成功!');
									});
								} else {
									msg.innerHTML = '错误提示:请勿与原密码相同!';
								}
							});
						} else {
							msg.innerHTML = '错误提示:请勿提交空值!';
						}
					});
				}

				// 删除账号
				del_btn.onclick = function() {
					db.transaction(function(tx) {
						if (get_uname.value !== '') {
							// 判断是否存在账号
							tx.executeSql('select * from login where username=?', [get_uname.value], function(tx, retval) {
								if (retval.rows.length > 0) {
									tx.executeSql('delete from login where username=?', [get_uname.value]);
									alert('账号删除成功!');
									get_uname.value = '';
								} else {
									msg.innerHTML = '错误提示:账号不存在,请重新输入!';
								}
							});
						} else {
							msg.innerHTML = '错误提示:请勿提交空值!';
						}
					});
				};

				// 查询所有账号(只读)
				show_btn.onclick = function() {
					db.readTransaction(function(tx) {
						// 查询所有数据
						tx.executeSql('select * from login', [], function(tx, retval) {
							var dt_rows = retval.rows;
							var html = '<table border="1"><tr><th>id</th><th>账号</th><th>密码</th><th>注册时间</th></tr>';
							// 遍历输出
							for (var i = 0; i < dt_rows.length; i++) {
								html += '<tr><td>' + dt_rows[i].id +
										'</td><td>' + dt_rows[i].username +
										'</td><td>' + dt_rows[i].userpassword +
										'</td><td>' + dt_rows[i].gettime +
										'</td></tr>';
							}
							html += '</table>';
							show_data.innerHTML = html;
							msg.innerHTML = '';
						});
					});
				}

				// 清空所有账号
				clr_btn.onclick = function() {
					db.transaction(function(tx) {
						tx.executeSql('delete from login');
						show_data.innerHTML = '';
					});
				}

				// 重置表单
				rst_btn.onclick = function() {
					uname.value = '';
					upw.value = '';
					msg.innerHTML = '';
				}
			} catch (err) {
				msg.innerHTML = '错误提示:' + err;
			}
		}
	</script>
</head>
<body>
	<div class="signup">
		<h3>账号注册</h3>
		<p>&emsp;&emsp;号:<input type="text" id="uname"></p>
		<p>&emsp;&emsp;码:<input type="password" id="upw"></p>
		<p class="wrap">
			<input type="button" id="sub_btn" value="提交" />
			<input type="button" id="rst_btn" value="重置" />
		</p>
	</div>
	<div class="update">
		<h3>账号操作</h3>
		<p>查询账号:<input type="text" id="get_uname"></p>
		<p class="wrap">
			<input type="button" id="chg_btn" value="修改密码" />
			<input type="button" id="del_btn" value="删除账号" />
		</p>
		<div id="mask">
			<h3>修改密码</h3>
			<p>新的密码:<input type="password" id="newpw" /></p>
			<p><input type="button" id="confirm" value="确定修改" /></p>
		</div>
	</div>
	<div style="clear: both;">
		<p>
			<h3>数据操作</h3>
			<input type="button" id="show_btn" value="显示所有账号" />
			<input type="button" id="clr_btn" value="清空所有账号" />
		</p>
		<div id="show_data"></div>
	</div>
	<div id="msg" style="color: red;"></div>
</body>
</html>
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值