第9章、语言结构

字符串常量

字符串是包含在单引号(')或双引号(")字符中的字节或字符序列。 以下几行例子是等同的:

'a string'
"a string"
'a' ' ' 'string'

如果ANSI_QUOTES启用了SQL模式,则字符串文字只能在单引号内引用,因为在双引号内引用的字符串被解释为标识符。

  • 二进制字符串是一组字节。每个二进制字符串都有一个名为binary的字符集和排序规则。
  • 非二进制的字符串是一组字符。它具有二进制以外的字符集和与字符集兼容的排序规则。

对于这两种类型的字符串,比较都是基于字符串单元的数值。 对于二进制字符集,单位是字节,使用字节值进行比较; 对于非二进制字符集,单位是字符和字符集支持多字节字符,使用数值进行比较;

一个字符串文字可以有一个可选的字符集introducer和COLLATE clause,用来指定它是一个使用特定字符集和排序规则的字符串:

[_charset_name]'string' [COLLATE collation_name]
// 例子
SELECT _latin1'string';
SELECT _binary'string';
SELECT _utf8'string' COLLATE utf8_danish_ci;

在一个字符串中,某些序列具有特殊的含义,除非NO_BACKSLASH_ESCAPES启用了SQL模式。这些序列中的每一个都以反斜杠(\)开始,称为转义字符

image.png

这些%_序列用于搜索模式匹配上下文中的文字实例,%_解释为通配符。

mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+
| hello | "hello" | ""hello"" | hel'lo | 'hello |
+-------+---------+-----------+--------+--------+

mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+
| hello | 'hello' | ''hello'' | hel"lo | "hello |
+-------+---------+-----------+--------+--------+

mysql> SELECT 'This\nIs\nFour\nLines';
+--------------------+
| This
Is
Four
Lines |
+--------------------+

mysql> SELECT 'disappearing\ backslash';
+------------------------+
| disappearing backslash |
+------------------------+

在编写应用程序时,任何可能包含任何这些特殊字符的字符串必须在将该字符串用作发送到MySQL服务器的SQL语句中的数据值之前正确转义。

你可以通过两种方式来做到这一点:

  • 使用转义特殊字符的函数处理字符串。
  • 作为显式转义特殊字符的替代方法,许多MySQL API提供了一个占位符功能,使您能够将特殊标记插入到语句字符串中,然后在发出语句时将数据值绑定到它们。在这种情况下,API会负责为您转义值中的特殊字符。

数字常量

数字文字包括精确值(整数)和 DECIMAL文字和近似值(浮点)文字。

FLOATDOUBLE是浮点类型,其计算结果是近似值。

日期时间常量

日期和时间值可以用多种格式表示,例如带引号的字符串或数字,具体取决于值的确切类型和其他因素。

MySQL使用type关键字,并且这些结构分别生成 DATETIMEDATETIME值,如果指定,则包括尾随小数秒部分。该 TIMESTAMP语法产生 DATETIME在MySQL的价值,因为 DATETIME有更紧密地对应于标准SQL的范围 TIMESTAMP类型,其中有一年范围00019999。(MySQL的TIMESTAMP年份范围是19702038。)

MySQL识别日期/时间比较宽松,通常符合日期/时间规则的都可以被转化成功,具体可以参考链接:https://dev.mysql.com/doc/refman/5.7/en/date-and-time-literals.html

十六进制

SELECT HEX('MySQL'),0x4D7953514C,x'4D7953514C',X'4D7953514C'

默认情况下,十六进制文字是一个二进制字符串,其中每对十六进制数字表示一个字符。

标识符命名限制

MySQL 中的某些对象,包括数据库,表,索引,列,别名,视图,存储过程,分区,表空间以及其他对象名称都被称为标识符。

  • 标识符使用引号(可选),但若标识符中包含特殊字符或者保留字,则必须使用引号。
  • 标识符在内部转化为Unicode字符,他们通常包括以下字符:
    • ASCII:U + 0001 .. U + 007F
    • 扩展字符:U+0080 .. U+FFFF
  • 标识符不允许使用 ASCII NUL (U + 0000)和补充字符 (U + 10000或更高)
  • 标识符可以以数字开头,但不能是纯数字
  • 数据库,表,列表不能以空格字符结尾

标识符的引号字符是反引号(`):

mysql> SELECT * FROM `select` WHERE `select`.id > 100;

ASNI_QUOTES启用了SQL模式,则可以使用双引号引用标识符。该ANSI_QUOTES模式使服务器将双引号字符串解释为标识符。因此,启用此模式时,字符串文字必须包含在单引号内。它们不能用双引号括起来。

在查询的SELECT列表中,可以使用标识符或字符串引用字符指定引用的列别名:

mysql> SELECT 1 AS `one`, 2 AS 'two';

不建议在命名使使用数字+英文+数字格式命名,因为这样可能会造成模糊不清的语意。举例:1e+3

小心使用MD5()生成表名,因为会产生上一条的问题。

下表描述了每种标识符的最大长度:

标识符

最大长度(字符)

Database

64

Table

64

Column

64

Index

64

Constraint

64

Stored Program

64

View

64

Tablespace

64

Server

64

Log File Group

64

Alias

256

Compound Statement Label

16

User-Defined Variable

64

标识符限定符

标识符可能合格或不合格。一个在上下文环境中可以正确推断无歧义的标识符是被允许的。限定名称至少包含一个限定符,通过重写默认上下文或提供缺失上下文来阐明解释上下文。

例如,该语句使用不限定名称t1创建一个表:

CREATE TABLE t1 (i INT);

因为t1未指明数据库,所以该次查询使用当前默认的数据库。如果当前未有默认数据库,则会抛出错误。

使用限定名db1.t1创建一个表:

CREATE TABLE db1.t1 (i INT);

因为已经指明了使用数据库db1,所以会在db1中创建表t1。如果不存在默认数据库,则必须指定数据库限定符。 如果存在默认数据库,且就是要使用的数据库,则可不指定数据库限定符(不推荐)。 如果存在默认数据库,但与要使用的不同,则必须指定数据库限定符。

限定符具备以下特征:

  • 不合格名称由单个标识符组成。限定名由多个标识符组成。
  • 限定符以.分隔。
  • 限定符是单独的字符串,不需要彼此相邻。如:tbl_name.col_nametbl_name . col_name是等价的。

标识符是区分大小写的,具体详情参照这里

关键字与保留字

对于非保留的关键字可不使用引号,对于保留的关键字得使用引号。

mysql> CREATE TABLE `interval` (begin INT, end INT);

BEGIN并且END是关键字但不保留,所以它们作为标识符的使用不需要引用。INTERVAL是一个保留关键字,必须用引号将其用作标识符。

避免使用保留字,避免因为语意含糊不清引发的问题。

保留字的清单可以在这里轻松查询到。

表达式语法

expr:
    expr OR expr
  | expr || expr
  | expr XOR expr
  | expr AND expr
  | expr && expr
  | NOT expr
  | ! expr
  | boolean_primary IS [NOT] {TRUE | FALSE | UNKNOWN}
  | boolean_primary

boolean_primary:
    boolean_primary IS [NOT] NULL
  | boolean_primary <=> predicate
  | boolean_primary comparison_operator predicate
  | boolean_primary comparison_operator {ALL | ANY} (subquery)
  | predicate

comparison_operator: = | >= | > | <= | < | <> | !=

predicate:
    bit_expr [NOT] IN (subquery)
  | bit_expr [NOT] IN (expr [, expr] ...)
  | bit_expr [NOT] BETWEEN bit_expr AND predicate
  | bit_expr SOUNDS LIKE bit_expr
  | bit_expr [NOT] LIKE simple_expr [ESCAPE simple_expr]
  | bit_expr [NOT] REGEXP bit_expr
  | bit_expr

bit_expr:
    bit_expr | bit_expr
  | bit_expr & bit_expr
  | bit_expr << bit_expr
  | bit_expr >> bit_expr
  | bit_expr + bit_expr
  | bit_expr - bit_expr
  | bit_expr * bit_expr
  | bit_expr / bit_expr
  | bit_expr DIV bit_expr
  | bit_expr MOD bit_expr
  | bit_expr % bit_expr
  | bit_expr ^ bit_expr
  | bit_expr + interval_expr
  | bit_expr - interval_expr
  | simple_expr

simple_expr:
    literal
  | identifier
  | function_call
  | simple_expr COLLATE collation_name
  | param_marker
  | variable
  | simple_expr || simple_expr
  | + simple_expr
  | - simple_expr
  | ~ simple_expr
  | ! simple_expr
  | BINARY simple_expr
  | (expr [, expr] ...)
  | ROW (expr, expr [, expr] ...)
  | (subquery)
  | EXISTS (subquery)
  | {identifier expr}
  | match_expr
  | case_expr
  | interval_expr

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C/C++基础

C++ Hash表模板

利用C++类模板实现任意类型的Hash表,提供的功能有: (1)指定shmkey或内存地址创建Hash表; (2)获取指定key元素; (3)遍历指...

62840
来自专栏JavaEE

mybatis的association以及collection的用法association:一对一关联(has one)collection:一对多关联(has many)

73480
来自专栏pangguoming

sharding-jdbc之——分库分表实例

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/79368021

45110
来自专栏测试开发架构之路

总结了一些指针易出错的常见问题(五)

指针与链表及其操作 //结构体定义 typedef struct _person{ char* firstname; char* lastna...

29150
来自专栏JavaQ

温故而知新-MySQL数据类型

选择数据类型的原则 MySQL支持多种数据类型,选择合适的数据类型存储数据对MySQL存储引擎来说至关重要,下面的一些原则可以在选择数据类型的时候做出更合适的选...

32070
来自专栏Python

Django中Q查询及Q()对象

问题 一般我们在Django程序中查询数据库操作都是在QuerySet里进行进行,例如下面代码: >>> q1 = Entry.objects.filter(h...

31450
来自专栏开发与安全

从零开始学C++之对象的使用(三):static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符

一、static 与单例模式 单例模式也就是简单的一种设计模式,它需要: 保证一个类只有一个实例,并提供一个全局访问点 禁止拷贝 #include <i...

25200
来自专栏乐沙弥的世界

PL/SQL 集合的方法

    PL/SQL中提供了常用的三种集合联合数组、嵌套表、变长数组,而对于这几个集合类型中元素的操作,PL/SQL提供了相应的函数或过程来操 纵数组中的元素...

9030
来自专栏机器学习入门

LWC 56:718. Maximum Length of Repeated Subarray

LWC 56:718. Maximum Length of Repeated Subarray 传送门:718. Maximum Length of Repea...

22660
来自专栏Java后端技术

你敢说自己了解单例模式?

  最近在学习设计模式,在看到单例模式的时候,我一开始以为直接很了解单例模式了,实现起来也很简单,但是实际上单例模式有着好几个变种,并且多线程中涉及到线程安全问...

11920

扫码关注云+社区

领取腾讯云代金券