注释只有两种写法能进脚本:--(两个减号加空格)和 /* */。
# 是 MySQL 客户端认、SQLite 不认,脚本里别用。
Demo 真撞了三次墙:# 报 unrecognized token: "#"、
一次送两句报 You can only execute one statement at a time、
SELECT 与 select 给同一个数 2。
前四篇讲的是「装和连」,这一篇讲「怎么写」——注释、分号、大小写、示例库,四件小事, 但每一件都能让人卡半天。 它是全书的书写公约,后面 18 章不再重复这些规矩。
一、注释:三种写法,两种通用
-- 是标准 SQL 注释,注意 MySQL 要求两个减号后面跟一个空格,
--注释 在 MySQL 里不合法(SQLite 反而认)。写成 -- 注释 两边都过。
# 是 MySQL 特有的行注释,命令行里常用。
但它不是标准 SQL,SQLite、PostgreSQL 都不认——脚本里用它,换库就报错。
/* */ 是块注释,可以跨行,
两边都认,还能用来临时屏蔽一整段。
MySQL 还有一种 /*! */ 是「版本条件执行」,那是给兼容性用的,本课不讲。
二、分号:语句的句号
一条语句以分号结尾,
这是客户端的约定——它靠分号判断「这句发完了」。 少一个分号,客户端就一直等你继续敲。
客户端可以一次发一批(编辑器里全选运行),但 Python 的驱动一次只收一条:
execute 遇到两句会报 You can only execute one statement at a time,
要整批发得用 executescript。
这条差异很实用:以后写脚本报这个错,不用怀疑 SQL 写错了,是发送方式不对。
三、大小写:关键字随便,值不行
SQL 关键字不分大小写:SELECT、select、Select 一个意思。
本书统一大写写关键字、小写写表名字段名,纯粹为了好读。
但有两处真的在乎大小写:一是字符串里的值('张伟' 和 '张伟 ' 是两个值);
二是 Linux 上的表名(lower_case_table_names=0 时 Students 和 students 是两张表)。
Windows 上默认不区分,换到 Linux 就翻车。
稳妥做法:表名、字段名一律小写加下划线(order_detail),永远不用大小写来区分对象。
四、本书的示例库:六张表,一条线到底
本课自造了一套六张表的库:classes(班级)、students(学生)、scores(成绩)、
goods(商品)、orders(订单)、order_detail(订单明细)。
为什么自造:教材的案例库不在手上,
但结构照它的思路来——两三条线(学生线、商品线)互相能连上,
这样第 10 章讲多表、第 19 章做案例时都有真数据可算。
数据量刻意做小:12 个学生、36 条成绩、10 件商品、14 张订单、17 条明细。
小到能手算验证,大到能看出规律——每个数都能在正文里被验算一遍。
五、小结
教材小结:SQL 语句以分号结尾,可以用 --、#、/* */ 写注释,关键字不分大小写;
书中示例按章节顺序逐步建立。
本课补三条:一是脚本里只用 -- 和 /* */,# 留给 MySQL 命令行;
二是 Python 驱动一次只送一条语句,整批要用 executescript;
三是表名字段名一律小写,别拿大小写当区分。
六、动手 Demo:四种写法,三次撞墙
Demo 六段:试三种注释、试一次送两句、试关键字大小写,最后看示例库长什么样。 中间三处报错都是真撞出来的,不是我写给你看的。
import sqlite3
c = sqlite3.connect(":memory:")
c.execute("CREATE TABLE t1 (id INTEGER) -- 行注释")
c.execute("CREATE TABLE t2 (id INTEGER) # MySQL 认,SQLite 不认")
c.execute("CREATE TABLE t3 ( /* 块注释 */ id INTEGER )")
# 一次只送一条语句
c.execute("INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (2)")
c.executescript("INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (2)")
# 关键字不分大小写
c.execute("SELECT COUNT(*) FROM t1")
c.execute("select count(*) from t1")
实跑输出:
--------------------------------------------------------------------
第五课:这本教程的几条书写约定
--------------------------------------------------------------------
注释有三种写法,SQLite 只认其中两种
SQL> CREATE TABLE t1 (id INTEGER) -- 这是行注释,两个减号加空格
完成
SQL> CREATE TABLE t2 (id INTEGER) # 这也是行注释
报错:unrecognized token: "#"
SQL> CREATE TABLE t3 ( /* 块注释 */ id INTEGER )
完成
**结论:写进脚本的注释只用** `-- ` **和** `/* */` **,`#` 留给 MySQL 命令行里临时敲。**
一条语句以分号结尾;几条语句可以一起发
SQL> INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (2)
报错:You can only execute one statement at a time.
**这是 Python 驱动的一条规矩:一次只送一条。**图形工具的运行键不一样,
它把编辑区里所有语句整批发出去。
SQL> 换成整批发送(等价于图形工具按一次运行)
完成
SQL> SELECT * FROM t1
id
---
1
2
(2 行)
关键字不分大小写,结果一模一样
SELECT 大写给 2,select 小写也给 2
**本书统一用大写写关键字、小写写表名字段名**,纯粹为了好读,引擎一点都不在乎。
**但字符串里的值在乎**:`'张伟'` 和 `'张伟 '` 是两个值。
本书的示例库:六张表,都是真表
classes、goods、order_detail、orders、scores、students
**一共 6 张:班级、学生、成绩、商品、订单、订单明细。**
**书上用的是它自己的案例库,表名数据都不一样;本课按同样的思路自造了一套,好处是每一章都能接着上一章的数往下算。**
最后一句:这套教程怎么用
**一章一章顺着敲,别跳。** 前面的表后面还要用,跳过去就得重新造数据。
**每一节的 Demo 都要自己跑一遍。** 看别人跑出来的数,和自己敲出来的数,掌握程度差得远。
**报错不要紧,把报错读一遍。** 数据库的报错信息是全栈里最老实的一类,
它基本都告诉你「哪个词不认识」。
第一段 -- 注释。 通过,这是标准写法。
第二段 # 注释。 报 unrecognized token: "#",这就是「换库就报错」的现场。
第三段块注释。 通过,跨行也行。
第四段一次送两句。 execute 报 You can only execute one statement at a time;
换 executescript 之后两条都进去了,表里两行。
第五段大小写。 大写小写都给 2,引擎确实不在乎。
第六段示例库。 六张表列出来——后面 18 章都在这六张表上折腾。
30 秒实验
--和--在 MySQL 里有区别吗?在本沙箱里呢?- (先想再跑)把
executescript换成execute送三条语句,报的是同一个错吗? - 在 Linux 上建一张
Students表,再select * from students,能查到吗?
常见误区
- 注释写成
#。 MySQL 命令行里能用,SQLite/PostgreSQL 直接语法错,脚本不可移植。 --后面不加空格。 标准 SQL 要求有空格,--注释在 MySQL 里不算注释。- 靠大小写区分表名。 Windows 上能跑,Linux 上找不到表,这类 bug 只在部署时爆。
自测三问(点开对答案)
1. 脚本里应该用哪两种注释? —— `-- `(两个减号加空格)和 `/* */`;`#` 只有 MySQL 客户端认,不可移植。 2. 为什么 `execute` 报「一次只能一条语句」? —— Python 的 sqlite3 驱动不允许一次执行多条;要整批发得用 executescript。 3. 哪两处真的区分大小写? —— 字符串里的值('张伟' 与 '张伟 ' 不同);Linux 上默认表名区分大小写。工具装好了、规矩也定了,下一章正式进 SQL:语法、数据类型、注释,把「一句话怎么写」讲透。
- ☐ (本篇完,下一篇 2.1 SQL 是什么)