SQL学习笔记(3)

本文是SQL学习笔记的第三部分,详细介绍了如何插入数据(完整行、部分行、通过SELECT语句插入)、更新数据、删除数据,以及创建和操作表(包括ALTER TABLE和视图)。此外,还讲解了存储过程的概念和创建方法。
摘要由CSDN通过智能技术生成

1. 插入数据 INSERT INTO

1.1 插入完整的行
INSERT INTO customers
VALUES(100,
      'Tony',
      'USA',
      NULL,
      NULL);

这个例子将一个新的顾客插入到customers表中。存储到表中的每一列数据由VALUES给出,必须给每一列提供一个值。如果某列没有值,就要用NULL(假定该列允许空值NULL)。各列必须以他们在表中定义的顺序填充。

上面的方式有个缺点:过于依赖列的顺序,因此可以使用以下形式

INSERT INTO customers(cust_id,cust_name,cust_city,cust_qq,cust_email)
VALUES(100,
      'Tony',
      'USA',
      NULL,
      NULL);

DBMS将用VALUES中的相应值填充表名后面的对应列。这样就使得插入结果不会随着表的结构改变而改变。

1.2 插入部分行

当使用明确列名来插入行(如上面的例子)时,也可以通过省略部分列来插入部分信息。这表示可以只给某些列提供值,其他列不提供值

INSERT INTO customers(cust_id,cust_name,cust_city)
VALUES(100,
      'Tony',
      'USA');

这个例子没有给cust_qq和cust_email提供值,即插入了部分行。

可以在INSERT操作中省略某些行,但是省略的行必须满足以下某个条件

  • 该列定义为允许NULL
  • 在表定义中给出默认值,这表示如果不给出值,就使用默认值。
1.3 插入检索出的值 INSERT SELECT

INSERT可以配合SELECT语句,将SELECT出来的结果插入表中

INSERT INTO customers(cust_id,cust_name,cust_city)
SELECT cust_id,cust_name,cust_city
FROM custnew;

上面的例子将从custnew表中检索出的结果插入customers表中。

INSERT SELECT中的表名:

这个例子中select出的列名与insert的列名一致,但其实不一定要列名匹配。实际上DBMS不关心SELECT返回的列名,因为它使用列的位置,因此SELECT的第一列将用来填充INSERT的第一列。。。

1.4 从一个表创建并复制到另一个表

使用CREATE SELECT语句

CREATE TABLE custcopy AS SELECT * FROM customer;

上面的例子将SELECT检索结果复制到一个新的表中。

2. 更新数据 UPDATE

不要省略WHERE子句,因为如果省略WHERE子句就是更新所有行;而如果有WHERE子句就是更新过滤出来的指定行

UPDATE user
SET username = 'wu',password='di'
WHERE username = 'wudi';

过滤出username为’wudi’的行,并将这些行的列值进行更新

如果要删除某个列的值,可以在SET子句中将该列值设为NULL(如果允许该列值为NULL的话)

UPDATE user
SET username = NULL -- 将username列设为NULL
WHERE username = 'wu';

需要注意NULL与空字符串’'不同

空字符串用’'表示,是一个值;而NULL表示没有值

3. 删除数据

不要省略WHERE子句,因为如果省略WHERE子句就是删除所有行;而如果有WHERE子句就是删除过滤出来的指定行

DELETE FROM user
WHERE username = 'wu'; -- 删除user表中username为'wu'的行

注意DELETE可以删除表中行,甚至表中所有行,但是不能删除表本身

4. 创建和操作表

4.1 创建表 CREATE TABLE

在创建表时必须保证该表名不存在。为了防止意外覆盖旧的表(比如create table 表名与一个现存表名一致),要求首先手动删除该表,然后再重建它,而不是简单地由创建表语句来覆盖。

格式:

CREATE TABLE 表名
(
	列名 数据类型 约束(是否允许为NULL、默认值等),
    ...
)

例子:

CREATE TABLE products
(
	id 		CHAR(10) 		NOT NULL, -- 不能为NULL值
    name 	CHAR(25) 		NOT NULL, -- 不能为NULL值
    price 	DECIMAL(8,2)	NULL	  -- 可以为NULL值
 )

每个列要么是NULL(允许是NULL值)要么是NOT NULL(不允许是NULL值)。NULL是默认设置,如果没有写NULL或NOT NULL,DBMS会按照NULL处理。

注意,由于主键是其值唯一标识表中每一行的列,因此主键不能是NULL的

创建带主键的表:PRIMARY KEY

CREATE TABLE products
(
	id 		CHAR(10) 		NOT NULL, -- 不能为NULL值
    name 	CHAR(25) 		NOT NULL, -- 不能为NULL值
    PRIMARY KEY(id)	 -- 设置id列为主键,其中id列不能是NULL值
 )

设置列的默认值:DEFAULT

CREATE TABLE products
(
	id 		CHAR(10) 		NOT NULL, -- 不能为NULL值
    name 	CHAR(25) 		NOT NULL DEFAULT 'WUDI' -- 设置默认值为'WUDI'
 )

5. 更新列(不是更新列的数据,而是增加删除列) ALTER TABLE

**给表增加列 **ADD

ALTER TABLE user
ADD email CHAR(20) NULL DEFAULT '123'; -- 给表user增加一列email,数据类型是char(20),允许NULL,默认值是'123'

给表删除列 DROP COLUMN

ALTER TABLE user
DROP COLUMN email; -- 删除email列

6. 删除和重命名整张表哦

删除整张表 DROP TABLE

DROP TABLE user; -- 删除表user

重命名整张表 RENAME

RENAME TABLE user TO user1; -- 将表user重命名为user1

7. 视图

视图是虚拟的表,只包含动态检索数据的查询结果。

可以简单理解为视图就是select检索语句保存下来作为一个视图VIEW,后续语句使用该VIEW时即为对SELECT语句检索结果进行操作。从而实现了SQL重用,减少了复杂性。

比如我们要对select username from user;检索结果进行多次操作,那么就需要每次先调用该select语句。这里就可以使用view,将该select语句保存为一个视图,之后直接调用该视图即可。

注意视图不是把检索语句结果保存起来,而是把检索语句本身保存起来。因此后续每次引用该视图,就会立即调用该视图引用的检索语句一次。

  • 视图名必须唯一(不能与其他表名或视图名重复)
  • 视图可以嵌套,但是严重影响性能
  • 视图不能索引、也不能有关联的触发器或默认值
7.1 创建视图 CREATE VIEW
CREATE VIEW v1 AS 
SELECT username FROM user
WHERE username > 'aaa';   -- 以下面的select语句创建一个视图并命名为v1

引用该视图

SELECT * FROM v1;
7.2 删除视图 DROP VIEW
DROP VIEW v1; -- 删除视图v1

8. 存储过程

存储过程就是为以后使用而保存的一条或多条SQL语句,可以将其视为批文件,但是其作用不仅限于批处理

可以将存储过程类比的看成一个函数。使用时可以给存储过程传递参数,也可以获取存储过程的返回值。

存储过程优点:简单安全高性能

8.1 执行存储过程 CALL

CALL接受存储过程名和需要传递给它的任何参数

CALL AddNewUser('wudi','1111'); -- 调用存储过程AddNewUser,并传递参数'wudi','1111'

假设AddNewUser是一个将新用户添加进表的存储过程,参数分别指定了行的username列和password列。但是对于主键id并没有指定参数,这是因为由于主键是唯一的,因此如果通过外部参数传递设置主键值不安全(如果设置了一个重复的id主键就会报错),而是应该在存储过程内部自动设置唯一的主键值!

8.2 创建存储过程 CREATE PROCEDURE

语法:

CREATE PROCEDURE 过程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型…]]) [特性 …] 过程体

CREATE PROCEDURE myproc(OUT s int)
	BEGIN
		SELECT COUNT(*) INTO s FROM students; -- 存储过程体,可以理解为函数体
	END

存储过程根据需要可能会有输入、输出、输入输出参数,如果有多个参数用","分割开。MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT:

IN参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值

OUT:该值可在存储过程内部被改变,并可返回

INOUT:调用时指定,并且可被改变和返回

过程体的开始与结束使用BEGIN与END进行标识。

例子1:用IN参数

DELIMITER //
  CREATE PROCEDURE in_param(IN p_in int)
    BEGIN
    SELECT p_in; -- 检索p_in参数值
    SET p_in=2; -- 将输入参数p_in值设为2,并不影响外部(类比于C++值传递)
    END;
    //
DELIMITER ;
#调用
SET @p_in=1;
CALL in_param(@p_in);

例子2:使用OUT参数

DELIMITER //
  CREATE PROCEDURE out_param(OUT p_out int)
    BEGIN
      SELECT p_out; -- 由于这是OUT参数,因此该检索返回NULL
      SET p_out=2; -- 将参数p_out值设为2,会影响到外部(类比于C++引用传递)
    END;
    //
DELIMITER ;
#调用
SET @p_out=1;
CALL out_param(@p_out);

例子3:使用INOUT参数

DELIMITER // -- 设置语句结束分隔符为'//'
  CREATE PROCEDURE inout_param(INOUT p_inout int)
    BEGIN
      SELECT p_out; -- 由于这是INOUT参数,因此该检索返回p_inout的值
      SET p_inout=2; -- 将输入参数p_inout值设为2,会影响到外部(类比于C++引用传递)
    END;
    // -- 该语句结束(注意不再是分号;)
DELIMITER ; -- 恢复语句结束分隔符为';'
#调用
SET @p_inout=1;
CALL inout_param(@p_inout) ;

DELIMITER:

其实就是告诉MySQL解释器,该段命令是否已经结束了,mysql是否可以执行了。默认情况下,delimiter是分号;。在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令。

但有时候,不希望MySQL这么做。比如可能输入较多的语句,且语句中包含有分号。 就比如一个存储过程,中间过程体中有分号;但是不希望立即执行,这种情况下,就需要事先把delimiter换成其它符号,如//或$$。 这样只有当//或$$出现之后,mysql解释器才会执行这段语句 。就比如上面的例子,将整个create proceture语句以//结束,作为一个完整的语句执行(而不是在过程体中由分号结束)

注意使用改变DELIMITER后,要将DELIMITER恢复为;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值