SQL基本操作

SQL 操作

检索数据 SELECT

检索数据

-- 检索单个列
SELECT 列名 FROM table_name;-- 检索多个列
SELECT1,2 FROM table_name;-- 检索所有列
SELECT * FROM table_name;-- 检索不同的值
SELECT DISTINCT 列名 FROM table_name;

限制检索结果

-- SQL Server / Access
SELECT TOP 5 列名 FROM table_name;-- DB2
SELECT 列名 FROM table_name FETCH FIRST 5 ROWS ONLY;-- Oracle
SELECT prod_name FROM table_name WHERE ROWNUM <= 5;-- MySQL / MariaDB / PostgreSQL / SQLite
SELECT prod_name FROM table_name LIMIT 5;-- MySQL 从第六行开始,检索五行
SELECT prod_name FROM table_name LIMIT 5 OFFSET 6;-- MySQL 与 MariaSQL 快捷键,上一条语句等价于:
SELECT prod_name FROM table_name LIMIT 5,6

排序检索数据 ORDER BY

-- 按单个列排序,默认从小到大
SELECT field1, field2 from table_name ORDER BY field1;-- 按多个列排序,先按第一个排,第一个相同再按第二个排
SELECT field1, field2 from table_name ORDER BY field1, field2;-- 按列位置排序
SELECT field1, field2 from table_name ORDER BY 4,5;-- 降序排序,与DESC相对的是ASC,但ASC是默认的,DESC只作用于他前面的那一列
SELECT field1, field2 from table_name ORDER BY field1 DESC,field2 DESC;

过滤数据 WHERE

-- ORDER BY 语句应该始终放在最后
SELECT field1, field2 FROM table_name WHERE field1 = 3;

WHERE操作符

操作符说明
=等于
!=或<>不等于
<(>)小于(大于)
<= (》=)小于等于(大于等于)
!<不小于
!>不大于
BETWEEN在指定两个值之间
IS NULL为NULL值
-- 范围检查,范围需要用AND连接,包括边界
SELECT * FROM stu WHERE grade BETWEEN 70 AND 100;
+----+----------+-----+-------+---------------------+
| id | name     | sex | grade | birthday            |
+----+----------+-----+-------+---------------------+
|  1 | zhangsan | boy |    99 | 2019-09-12 19:21:31 |
|  3 | wangwu   | boy |    77 | 2019-09-03 19:22:52 |
|  4 | zhaoliu  | boy |    77 | 2019-09-10 19:28:22 |
+----+----------+-----+-------+---------------------+
3 rows in set (0.33 sec)

高级数据过滤

-- AND 操作
SELECT * FROM stu WHERE grade>90 AND sex = "boy";-- OR 操作
SELECT * FROM stu WHERE grade > 90 OR grade < 60;-- IN 操作
SELECT * FROM stu WHERE name IN ('zhangsan', "lisi");-- NOT操作
SELECT * FROM stu WHERE NOT name IN ('zhangsan', "lisi");
  • AND 操作符优先级高于OR,可以加括号改变优先级
  • IN比OR执行更快
  • IN可以包含其他SELECT语句
  • NOT否定跟在它后面的语句

使用通配符进行数据过滤 LIKE

通配符作用
%匹配任何字符出现任意次
_匹配单个字符
[]匹配指定位置的一个字符(只有SQL Server支持)
-- 匹配name中带有n的字段
select * from stu where name like "%n%";-- 匹配name以z或w开头的字段(SQL Server)
select * from stu where name like "[zw]%";
  • 通配符搜索耗时比其他搜索长,不要依赖于通配符搜索

创建计算字段

计算字段并不存在于数据库,只是在执行SELECT语句时生成的

拼接字段

DBMS符号
Access, SQL Server+
DB2,Oracle,PostgreSQL,SQLite,Open Office Base||
Mysql,MariaDB使用Concat()函数
-- SQL Server
SELECT name + "(" + grade + ")" FROM stu ORDER BY grade;-- MySQL
SELECT CONCAT(name,"(",grade,")") FROM stu ORDER BY grade;
+----------------------------+
| CONCAT(name,"(",grade,")") |
+----------------------------+
| lisi(66)                   |
| wangwu(77)                 |
| zhaoliu(77)                |
| zhangsan(99)               |
+----------------------------+

使用别名

-- SQL Server
SELECT
name + "(" + grade + ")" AS new_name
FROM stu ORDER BY grade;-- MySQL
SELECT CONCAT(name,"(",grade,")") AS new_name
FROM stu ORDER BY grade;
+--------------+
| new_name     |
+--------------+
| lisi(66)     |
| wangwu(77)   |
| zhaoliu(77)  |
| zhangsan(99) |
+--------------+

执行算数运算

支持 +,-,*,/

SELECT * ,
grade*0.1 AS new_grade
FROM stu ORDER BY grade;
+----+----------+-----+-------+---------------------+-----------+
| id | name     | sex | grade | birthday            | new_grade |
+----+----------+-----+-------+---------------------+-----------+
|  2 | lisi     | boy |    66 | 2019-09-04 19:22:05 |       6.6 |
|  3 | wangwu   | boy |    77 | 2019-09-03 19:22:52 |       7.7 |
|  4 | zhaoliu  | boy |    77 | 2019-09-10 19:28:22 |       7.7 |
|  1 | zhangsan | boy |    99 | 2019-09-12 19:21:31 |       9.9 |
+----+----------+-----+-------+---------------------+-----------+
4 rows in set (0.00 sec)

函数

每个DBMS都支持自己特定的函数,只有少数函数被大多DBMS支持

数据处理函数

文本处理函数

函数说明
LEFT()返回字符串左边的字符
RIGHT()返回字符串右边字符
LENGTH()或DATALENGTH()或LEN()返回字符串长度
LOWER() Access使用LCASE()将字符串转换为小写
UPPER() Access使用UCASE()将字符串转换为大写
LTRIM()去掉字符串左边空格
RTRIM()去掉字符串右边空格
SOUNDEX()返回字符串的SOUNDEX值
  • soundex是判断读音是不是相同,可惜中文不行,有趣的是这个算法发明的时间比计算机发明的时间还早,哈哈哈
mysql> SELECT * FROM stu WHERE SOUNDEX(name) = SOUNDEX("enn");
+----+------+-----+-------+---------------------+
| id | name | sex | grade | birthday            |
+----+------+-----+-------+---------------------+
|  5 | en   | boy |    33 | 2019-09-29 20:41:41 |
+----+------+-----+-------+---------------------+

时间日期处理函数

-- SQL Server
SELECT * FROM stu WHERE DATEPART(yy, birthday) = 2012;-- Access
SELECT * FROM stu WHERE DATEPART("yyyy", birthday) = 2012;-- PostgreSQL
SELECT * FROM stu WHERE DATE_PART('year', birthday) = 2012;-- Oracle
SELECT * FROM stu WHERE to_number(to_char(birthday,'yyyy')) = 2012;-- MySQL MairiaDB
SELECT * FROM stu WHERE YEAR(birthday) = 2012;-- SQLite
SELECT * FROM stu WHERE strftime('%Y', birthday) = 2102;

数值处理函数

函数说明
ABS()绝对值
COS(),SIN(),TAN()余弦,正弦,正切
PI()圆周率
EXP()指数
SQRT()平方根

聚集函数

SQL聚集函数

函数说明
AVG()返回某列平均值
COUNT()返回某列行数
MAX() MIN()返回某列最大最小值
SUM()返回某列之和
  • COUNT(*)对表中所有行计数,不管是否包含空值
  • COUNT(列)对特定列中具有特定值的行计数,忽略空值
  • 可以使用DISTINCT聚集不同的值(Access不支持)
SELECT
COUNT(*) AS count_num,
AVG(DISTINCT grade) AS avg_grade,
MAX(grade) AS max_grade,
MIN(grade) AS min_grade,
SUM(grade) AS sun_grade
FROM stu;
+-----------+-----------+-----------+-----------+-----------+
| count_num | avg_grade | max_grade | min_grade | sun_grade |
+-----------+-----------+-----------+-----------+-----------+
|         6 |   74.2000 |        99 |        33 |       448 |
+-----------+-----------+-----------+-----------+-----------+
1 row in set (0.00 sec)

分组数据 GROUP BY

select grade, count(*) AS nums from stu group by grade;
+-------+------+
| grade | nums |
+-------+------+
|    99 |    1 |
|    66 |    1 |
|    77 |    2 |
|    33 |    1 |
|    96 |    1 |
+-------+------+
5 rows in set (0.00 sec)
  • GROUP BY 子句可以包含任意数目的列,因此可以对分组进行嵌套,进行更细致的分组
  • 如果嵌套了分组,数据将在最后指定的分组上进行汇总。(所有列一起计算)
  • GROUP BY 子句中列出的每一列都必须是检索列或有效的表达式(不能是聚集函数),如果在SELECT中使用表达式,则必须在GROUP子句中指定相同的表达式,不能使用别名.
  • 大多数DBMS不允许GROUP BY 带有长度可变的数据类型
  • 除聚集计算语句外,SELECT语句中的每一列都必须在GROUP BY中给出
  • 如果分组列中包含一个NULL值,则NULL作为一个分组返回,多个NULL作为一个分组。
  • GROUP BY应该出现在WHERE之前,ORDER BY 之前。

过滤分组 HAVING

select grade, count(*) AS nums from stu group by grade having grade > 60;
+-------+------+
| grade | nums |
+-------+------+
|    99 |    1 |
|    66 |    1 |
|    77 |    2 |
|    96 |    1 |
+-------+------+
4 rows in set (0.10 sec)

HAVING 与 WHERE 的区别:
WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤,WHERE排除的行不包括在分组中,这可能会改变计算值,从而影响HAVING中基于这些值过滤掉的分组。
如果不指定GROUP BY 大多数DBMS会同等对待他们,不过,使用HAVING时应该结合GROUP BY 而WHERE应该用于标准的行级过滤。

分组和排序

GROUP BY 与 ORDER BY 经常完成相同的工作,但他们非常不同,ORDER BY 是对产生的输出进行排序,而GROUP BY 是对行进行排序,但输出的可能不是分组的顺序,所以在使用GROUP BY时,也应该给出ORDER BY 子句。

--- 除ACCESS外,大部分DBMS支持用别名排序
select grade, count(*) AS nums from stugroup by grade having grade > 60order by count(*);
+-------+------+
| grade | nums |
+-------+------+
|    66 |    1 |
|    96 |    1 |
|    99 |    1 |
|    77 |    2 |
+-------+------+

子查询

select * from songs where singer in  -> (select id from singer where name = "张靓颖");
+-----------+---------------------+--------------------------------------------------------+--------+
| id        | name                | link                                                   | singer |
+-----------+---------------------+--------------------------------------------------------+--------+
|    169794 | 天下无双            | http://music.163.com/song/media/outer/url?id=169794    |  10561 |
|    327089 | 画心                | http://music.163.com/song/media/outer/url?id=327089    |  10561 |
|    327163 | 我们说好的          | http://music.163.com/song/media/outer/url?id=327163    |  10561 |
|    327225 | 如果爱下去          | http://music.163.com/song/media/outer/url?id=327225    |  10561 |
|   5233037 | 另一个天堂          | http://music.163.com/song/media/outer/url?id=5233037   |  10561 |
|  31877130 | 饿狼传说 (Live)     | http://music.163.com/song/media/outer/url?id=31877130  |  10561 |
| 431853688 | 我的梦 (Live)       | http://music.163.com/song/media/outer/url?id=431853688 |  10561 |
+-----------+---------------------+--------------------------------------------------------+--------+
7 rows in set (0.25 sec)
  • 子查询可以嵌套,但出于效能考虑,不应该嵌套过多。

作为计算字段使用子查询

mysql> SELECT name,-> (SELECT COUNT(*) FROM songs WHERE songs.singer = singer.id) AS nums-> FROM singer WHERE type IN-> (SELECT id FROM singer_type WHERE type = "华语男歌手")-> ORDER BY name-> LIMIT 5;
+-----------------+------+
| name            | nums |
+-----------------+------+
| “阿兰姐”        |   50 |
| 023 GC          |    0 |
| A3              |   32 |
| abduwali tohti  |    8 |
| ABSDJHONG       |   22 |
+-----------------+------+
5 rows in set (0.69 sec)

联结表

联结是一种机制,用来在一条SELECT语句中关联表,因此,称为联结

--- 等值联结
mysql> SELECT songs.name,link,singer.name FROM songs,singer-> WHERE songs.singer = singer.id-> LIMIT 5;
+-----------------+----------------------------------------------------+--------+
| name            | link                                               | name   |
+-----------------+----------------------------------------------------+--------+
| Happy Birth Day | http://music.163.com/song/media/outer/url?id=59867 | 阿信   |
| 几年了          | http://music.163.com/song/media/outer/url?id=59870 | 阿杜   |
| Valentines Day | http://music.163.com/song/media/outer/url?id=59875 | 阿杜   |
| 再唱一首        | http://music.163.com/song/media/outer/url?id=59877 | 阿杜   |
| 圣堂之门        | http://music.163.com/song/media/outer/url?id=59886 | 阿沁   |
+-----------------+----------------------------------------------------+--------+
5 rows in set (0.01 sec)
  • 创建表联结时的WGERE语句非常重要,他作为过滤条件,只包含那些匹配给定条件的行,没有联结条件则会返回要联结的表的笛卡尔积(叉联结)
  • 完全限定名:引用列可能出现歧义,这种情况应该使用表名.列名的完全限定名

内连接(inner-join)

上面的等值连接也叫内连接,可以显式声明联结类型

mysql> SELECT songs.name, link, singer.name AS singer-> FROM songs INNER JOIN singer ON-> songs.singer = singer.id-> LIMIT 5;
+-----------------+----------------------------------------------------+--------+
| name            | link                                               | singer |
+-----------------+----------------------------------------------------+--------+
| Happy Birth Day | http://music.163.com/song/media/outer/url?id=59867 | 阿信   |
| 几年了          | http://music.163.com/song/media/outer/url?id=59870 | 阿杜   |
| Valentines Day | http://music.163.com/song/media/outer/url?id=59875 | 阿杜   |
| 再唱一首        | http://music.163.com/song/media/outer/url?id=59877 | 阿杜   |
| 圣堂之门        | http://music.163.com/song/media/outer/url?id=59886 | 阿沁   |
+-----------------+----------------------------------------------------+--------+
5 rows in set (0.00 sec)
  • SQL本身不限制联结表的数量,但许多DBMS有限制
  • 联结表越多,性能下降越厉害
  • 允许使用表别名(Oracle 不用 AS)

自联结(self-join)

mysql> SELECT s1.name,s1.singer-> FROM songs AS s1,songs AS s2-> WHERE s1.singer = s2.singer AND s2.name="光年之外";
+-----------------------------+--------+
| name                        | singer |
+-----------------------------+--------+
| 来自天堂的魔鬼              |   7763 |
|(Live Piano Session II)  |   7763 |
| 光年之外                    |   7763 |
| 断讯                        | 916042 |
| 光年之外                    | 916042 |
| 那个她                      | 916042 |
+-----------------------------+--------+
6 rows in set (4.53 sec)
  • 联结中的两张表是同一张表,必须使用别名区分。
  • 许多DBMS处理自联结比处理子查询快。

自然联结

自然联结是一种特殊的等值联结(内联结),他要求两个关系中进行比较的分量必须是同名的属性组,并且在结果中把重复的属性列去掉,事实上,我们迄今为止建立的每个内联结都是自然联结,也很可能永远都不会用到不是自然联结的内联结。通常对一个表使用通配符(SELECT *)其他表使用明确的子集来完成。

mysql> SELECT s.* ,e.name-> FROM songs AS s,singer AS e-> WHERE s.singer = e.id AND e.name = "袁娅维";

外联结

两个关系R和S在做自然连接时,他们在公共属性上值相等的元组构成新的关系,但是关系R中某些元组可能在关系S中不存在公共属性上值相等的元组,从而造成R中的这些元组被舍弃了,同样的S中的元组也有可能被舍弃,这些被舍弃的元组被称为 悬浮元组

如果把悬浮元组也保存到结果关系中,而在其他属性上填空值,这种联结叫做外联结,如果只保留左边关系R中的悬浮元组就叫做左外连接,如果只保留右边关系S中的悬浮元组就叫做右外连接。

-- 原来表的数据
mysql> select * from r;
+----+----+----+
| A  | B  | C  |
+----+----+----+
| a1 | b1 | 5  |
| a1 | b2 | 6  |
| a2 | b3 | 8  |
| a2 | b4 | 12 |
+----+----+----+
4 rows in set (0.00 sec)mysql> select * from s;
+----+----+
| B  | E  |
+----+----+
| b1 | 3  |
| b2 | 7  |
| b3 | 10 |
| b3 | 2  |
| b5 | 2  |
+----+----+
5 rows in set (0.00 sec)-- 左外连接
mysql> SELECT r.*,s.*-> FROM r LEFT OUTER JOIN s-> ON r.b = s.b;
+----+----+----+------+------+
| A  | B  | C  | B    | E    |
+----+----+----+------+------+
| a1 | b1 | 5  | b1   | 3    |
| a1 | b2 | 6  | b2   | 7    |
| a2 | b3 | 8  | b3   | 10   |
| a2 | b3 | 8  | b3   | 2    |
| a2 | b4 | 12 | NULL | NULL |
+----+----+----+------+------+
5 rows in set (0.00 sec)-- 右外联结
mysql> SELECT r.*,s.*-> FROM r RIGHT OUTER JOIN s-> ON r.b = s.b;
+------+------+------+----+----+
| A    | B    | C    | B  | E  |
+------+------+------+----+----+
| a1   | b1   | 5    | b1 | 3  |
| a1   | b2   | 6    | b2 | 7  |
| a2   | b3   | 8    | b3 | 10 |
| a2   | b3   | 8    | b3 | 2  |
| NULL | NULL | NULL | b5 | 2  |
+------+------+------+----+----+
5 rows in set (0.00 sec)

还有一种全外联结(FULL OUTER JOIN)包含两个表中不相关的行,Access,MariaDB,MySQL,Open Office Base,SQLite不支持。

使用带聚集函数的联结

组合查询 UNION

mysql> SELECT id, name from singer where name="阿沁"-> UNION-> SELECT name, id FROM singer WHERE name="林俊呈";
+-----------+----------+
| id        | name     |
+-----------+----------+
| 1872      | 阿沁     |
| 林俊呈    | 30107224 |
+-----------+----------+
2 rows in set (0.07 sec)
  • UNION 语句中必须包含相同的列,表达式或聚集函数(次序可以不同)
  • 列数据类型必须兼容
  • 只能使用一条ORDER BY 语句,位于最后一个select之后
  • UNION会自动删除相同的行,如果不希望这样,可以使用 UNION ALL

插入数据 INSERT

-- 不安全
mysql> INSERT INTO stu-> VALUES(-> 7,-> "dapeng",-> "girl",-> 99,-> "2019-10-9 10:11:21");
Query OK, 1 row affected (0.09 sec)

应该给出列名(虽然更加麻烦),尤其是你只打算插入部分行时。

mysql> INSERT INTO stu(id,->                 name,->                 sex,->                 grade)-> VALUES(8,->        "xiaowei",->        "girl",->        99);
Query OK, 1 row affected (0.05 sec)

插入检索出的数据

mysql> INSERT INTO stu(name,->                 sex,->                 grade,->                 birthday)-> SELECT name,->        sex,->        grade,->        birthday-> FROM stu WHERE id = 1;
Query OK, 1 row affected (1.67 sec)
Records: 1  Duplicates: 0  Warnings: 0
  • 可以从本表中检索插入,也可以从其他表中检索插入。

从一个表复制到另一个表 SELECT INTO

  • DB2 不支持
-- MariaDB,MySQL,Oracle,PostgreSQL,SQLite
mysql> CREATE TABLE s_copy AS SELECT * FROM s;
Query OK, 5 rows affected (0.11 sec)
Records: 5  Duplicates: 0  Warnings: 0mysql> show tables;
+----------------------+
| Tables_in_sqlstudent |
+----------------------+
| r                    |
| s                    |
| s_copy               |
| stu                  |
+----------------------+
4 rows in set (0.00 sec)-- 其他DBMS
SELECT * INTO s_copy FROM s;

更新和删除数据

mysql> UPDATE stu-> SET sex="boy",->     birthday=Null-> WHERE name = "dapeng";
Query OK, 1 row affected (0.08 sec)
Rows matched: 1  Changed: 1  Warnings: 0
  • 可以只写一条UPDATE语句更新多列数据
  • 部分DBMS支持FROM语法,把别的表中的数据更新到这张表里
  • 不写WHERE语句会更新所有行
  • UPDATE允许使用子查询
mysql> DELETE FROM stu WHERE id=2;
Query OK, 1 row affected (0.04 sec)
  • 不写WHERE语句会删除所有数据
  • DELETE不需要列名或通配符,应为它删除的是整个行
  • 如果想删除所有行,应该使用TRUNCATE TABLE,它更快,所以无论何时,使用DELETE时记得加WHERE

创建和操纵表

删除表

mysql> DROP TABLE s_copy;
Query OK, 0 rows affected (0.07 sec)
  • 没提示确认

创建表

mysql> CREATE TABLE Products(-> id int(255) NOT NULL,-> name VARCHAR(100) NULL-> );
Query OK, 0 rows affected (0.08 sec)
  • 不同DBMS的表创建语句有差异
  • 创建新表时,指定的表名必须不存在
  • 创建表时字段允许为空则指定NULL,否则,如果要求插入时必须给出值,则指定为NOT NULL
  • NULL不同于'',前者是没有值,后者是空字符串
  • 不指定时大部分DBMS默认为NULL,但DB2不指定会报错
  • 允许NULL值的列不允许作为主键
  • DEFAULT 用来指定默认值,常用于时间或时间戳列

获取系统日期

DBMS函数
AccessNOW()
DB2CURRENT_DATE
MySQLCURRENT_TIMESTAMP
OracleSYSDATE
PostgreSQLCURRENT_DATE
SQL ServerGETDATE()
SQLitedate(‘now’)
CREATE TABLE User
(id      INT(255)        NOT NULL,name    VARCHAR(255)    NOT NULL,create_time timestamp   DEFAULT CURRENT_TIMESTAMP
);

更新表 ALTER TABLE

  • 一般不要在表中包含数据时更新表
  • 所有DBMS都允许怎加列,不过对所增加列的数据类型(NULL和DEFAULT的使用)有限制
  • 许多DBMS不允许删除或更改列
  • 许多DBMS允许重命名列
-- 增加列
ALTER TABLE User ADD phone CHAR(20);mysql> DESCRIBE User;
+-------------+--------------+------+-----+-------------------+-------------------+
| Field       | Type         | Null | Key | Default           | Extra             |
+-------------+--------------+------+-----+-------------------+-------------------+
| id          | int(255)     | NO   |     | NULL              |                   |
| name        | varchar(255) | NO   |     | NULL              |                   |
| create_time | timestamp    | YES  |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| phone       | char(20)     | YES  |     | NULL              |                   |
+-------------+--------------+------+-----+-------------------+-------------------+
4 rows in set (0.00 sec)
-- 删除列
ALTER TABLE User DROP COLUMN phone;

视图

视图是一张虚拟的表,不包含数据,只包含使用时动态检索数据的查询。

为什么使用视图:

  • 重用SQL语句
  • 简化复杂的SQL操作
  • 只是用表的一部分而不是整个表
  • 保护数据,可以授予用户访问表的特定部分的权限,而不是整个表的访问权限
  • 更改数据格式和表示

性能问题

视图不包含数据,每次使用视图时,都必须处理查询执行时需要的所有检索,如果使用多个联结和过滤创立了复杂的视图或嵌套了视图,性能可能会下降的很厉害

视图的规则和限制

  • 必须拥有唯一命名
  • 创建视图的数目没有限制
  • 必须拥有足够的访问权限
  • 可以嵌套,嵌套层数因DBMS而异
  • 许多DBMS禁止使用ORDER BY
  • 有些DBMS要求对所返回的所有列命名,如果是计算字段,需要使用别名
  • 有些DBMS把视图作为只读查询
  • 有些DBMS允许创建这样的视图:不能进行导致行不再属于视图的插入或更新

创建视图 CREATE VIEW

CREATE VIEW song_singer AS
SELECT songs.name AS song_name,
songs.link,
singer.name AS singer_name,
singer_type.type
FROM songs,singer,singer_type
WHERE songs.singer = singer.id AND
singer.type = singer_type.id;

创建视图时可以使用格式化语句或计算字段

使用视图

SELECT语句中的所有约束条件在视图中都适用。

mysql> SELECT * FROM song_singer WHERE singer_name = "薛之谦";

存储过程

存储过程可以理解为保存一条或多条语句,将其视为批文件,也可以看作是编程语言中的函数

为什么使用存储过程

  • 把处理分装在一个易用的单元中,可以简化操作
  • 由于不要求反复建立一系列处理步骤,从而保证了数据的一致性
  • 简化对变动的管理存储过程通常以编译过的形式存储,所以DBMS处理命令的工作较少,提高了性能
  • 存在一些只能用在单个请求中的SQL元素和特性,存储过程可以使用他们编写功能更强,更灵活的代码
  • 存在一些只能用在单个请求中的SQL元素和特性,存储过程可以使用他们编写更强更灵活的代码。

缺点

  • 不同DBMS的存储过程语法不同,可移植性差
  • 编写复杂

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457548.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git 忽略 部分文件夹_git提交忽略某些文件或文件夹

记得第一次用 github 提交代码&#xff0c;node_modules 目录死活传不上去&#xff0c;哈哈哈&#xff0c;后来才知道在 .gitignore 文件里设置了忽略 node_modules 目录上传。是的&#xff0c; .gitignore 文件就是设置那些你不想用 git 一起上传的文件和文件夹。比如刚接触到…

Ajax实现原理详解

Ajax&#xff1a;Asynchronous javascript and xml&#xff0c;实现了客户端与服务器进行数据交流过程。使用技术的好处是&#xff1a;不用页面刷新&#xff0c;并且在等待页面传输数据的同时可以进行其他操作。 这就是异步调用的很好体现。首先得了解什么是异步和同步的概念。…

SpringJDBC解析3-回调函数(update为例)

PreparedStatementCallback作为一个接口&#xff0c;其中只有一个函数doInPrepatedStatement&#xff0c;这个函数是用于调用通用方法execute的时候无法处理的一些个性化处理方法&#xff0c;在update中的函数实现&#xff1a; protected int update(final PreparedStatementCr…

python上下文管理器

DAY 23. python上下文管理器 Python 的 with 语句支持通过上下文管理器所定义的运行时上下文这一概念。 此对象的实现使用了一对专门方法&#xff0c;允许用户自定义类来定义运行时上下文&#xff0c;在语句体被执行前进入该上下文&#xff0c;并在语句执行完毕时退出该上下文&…

勾股定理python思路_趣叮咚编程数学揭秘:为什么勾股定理a+b=c?

我们都知道&#xff1a;三角形3个外角之和360度可是谁知道为什么等于360度呢&#xff1f;其实利用编程制作动图演绎了解啦&#xff1a;那勾股定理abc又是为什么呢&#xff1f;还有很多有趣的数学公式都可以演绎&#xff1a;圆的面积公式、圆周长...通过动图演绎原来晦涩难懂的定…

System.InvalidOperationException : 不应有 Response xmlns=''。

xml如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <Response version"2"><datacash_reference>4700203048783633</datacash_reference><information>Failed to identify the card scheme of the supp…

Navicat Premium连接SQL Server

Navicat Premium连接SQL Server 步骤&#xff1a; 激活SQL Server 服务配置SQL Server网络配置连接SQL Server 激活SQLServer服务 直接搜索 计算机管理 点 服务和应用程序&#xff0c; 点 SQL Server配置管理器&#xff0c; 双击第一个SQL Server服务 不出意外的话&#xf…

mysql 单标递归_MySql8 WITH RECURSIVE递归查询父子集的方法

背景开发过程中遇到类似评论的功能是&#xff0c;需要时用查询所有评论的子集。不同数据库中实现方式也不同&#xff0c;本文使用Mysql数据库&#xff0c;版本为8.0Oracle数据库中可使用START [Param] CONNECT BY PRIORMysql 中需要使用 WITH RECURSIVE需求找到name为张三的孩子…

processon完全装逼指南

一、引言 作为一名IT从业者&#xff0c;不仅要有扎实的知识储备&#xff0c;出色的业务能力&#xff0c;还需要具备一定的软实力。软实力体现在具体事务的处理能力&#xff0c;包括沟通&#xff0c;协作&#xff0c;团队领导&#xff0c;问题的解决方案等&#xff0c;这些能力在…

mysql在空闲8小时之后会断开连接(默认情况)

调试程序的过程发现&#xff0c;在mysql连接空闲一定时间&#xff08;默认8小时&#xff09;之后会断开连接&#xff0c;需要重新连接&#xff0c;也引发我对重连机制的思考。转载于:https://www.cnblogs.com/ppzbty/p/5707576.html

selector多路复用_多路复用器Selector

Unix系统有五种IO模型分别是阻塞IO(blocking IO)&#xff0c;非阻塞IO( non-blocking IO)&#xff0c;IO多路复用(IO multiplexing)&#xff0c;信号驱动(SIGIO/Signal IO)和异步IO(Asynchronous IO)。而IO多路复用通常有select&#xff0c;poll&#xff0c;epoll&#xff0c;k…

解决svn log显示no author,no date的方法之一

只要把svnserve.conf中的anon-access read 的read 改为none&#xff0c;也不需要重启svnserve就行 sh-4.1# grep "none" /var/www/html/svn/pro/conf/svnserve.conf ### and "none". The sample settings below are the defaults. anon-access none转载…

REST framework 权限管理源码分析

REST framework 权限管理源码分析 同认证一样&#xff0c;dispatch()作为入口&#xff0c;从self.initial(request, *args, **kwargs)进入initial() def initial(self, request, *args, **kwargs):# .......# 用户认证self.perform_authentication(request)# 权限控制self.che…

解决larave-dompdf中文字体显示问题

0、使用MPDF dompdf个人感觉没有那么好用&#xff0c;最终的生产环境使用的是MPDF&#xff0c;github上有文档说明。如果你坚持使用&#xff0c;下面是解决办法。可以明确的说&#xff0c;中文乱码是可以解决的。 1、安装laravel-dompdf依赖。 Packagist&#xff1a;https://pa…

mfc程序转化为qt_小峰的QT学习笔记

我的专业是输电线路&#xff0c;上个学期&#xff0c;我们开了一门架空线路设计基础的课&#xff0c;当时有一个大作业是计算线路的比载&#xff0c;临界档距&#xff0c;弧垂最低点和安装曲线。恰逢一门结课考试结束&#xff0c;大作业ddl快到&#xff0c;我和另外两个同专业的…

MS SQL的存储过程

-- -- Author: -- Create date: 2016-07-01 -- Description: 注册信息 -- ALTER PROCEDURE [dbo].[sp_MebUser_Register]( UserType INT, MobileNumber VARCHAR(11), MobileCode VARCHAR(50), LoginPwd VARCHAR(50), PayPwd VARCHAR(50), PlateNumber VARCHAR(20), UserTr…

mysql 中 all any some 用法

-- 建表语句 CREATE TABLE score(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20),SUBJECT VARCHAR(20),score INT);-- 添加数据 INSERT INTO score VALUES (NULL,张三,语文,81), (NULL,张三,数学,75), (NULL,李四,语文,76), (NULL,李四,数学,90), (NULL,王五,语文,81), (…

REST framework 用户认证源码

REST 用户认证源码 在Django中&#xff0c;从URL调度器中过来的HTTPRequest会传递给disatch(),使用REST后也一样 # REST的dispatch def dispatch(self, request, *args, **kwargs):""".dispatch() is pretty much the same as Djangos regular dispatch,but w…

scrapyd部署_如何通过 Scrapyd + ScrapydWeb 简单高效地部署和监控分布式爬虫项目

来自 Scrapy 官方账号的推荐需求分析初级用户&#xff1a;只有一台开发主机能够通过 Scrapyd-client 打包和部署 Scrapy 爬虫项目&#xff0c;以及通过 Scrapyd JSON API 来控制爬虫&#xff0c;感觉 命令行操作太麻烦 &#xff0c;希望能够通过浏览器直接部署和运行项目专业用…

最长上升子序列 (LIS算法(nlong(n)))

设 A[t]表示序列中的第t个数&#xff0c;F[t]表示从1到t这一段中以t结尾的最长上升子序列的长度&#xff0c;初始时设F [t] 0(t 1, 2, ..., len(A))。则有动态规划方程&#xff1a;F[t] max{1, F[j] 1} (j 1, 2, ..., t - 1, 且A[j] < A[t])。 现在&#xff0c;我们仔细…