zoukankan      html  css  js  c++  java
  • 【mysql的编程专题①】流程控制与其他语法

    流程控制与内置函数,一般用在select的field字段上,或者用在函数,存储过程,触发器中;
    如果用在select上就会随着query出来的row来隐式迭代;

    注释与语句结束符

    语句结束符

    默认有两个:;g(只能在命令行中使用)
    可以使用delimiter 命令来修改语句结束符,例如: delimiter $$(注意,一般手工修改结束符后再手工改回原来默认值 ;)

    注释

    行注释: #--[空格]
    块注释: /* */

    变量的定义与输出

    定义变量

    MySQL中可以使用DECLARE关键字来定义变量。定义变量的基本语法如下:

    DECLARE  var_name[,...]  type  [DEFAULT value] 
    
    • 其中, DECLARE关键字是用来声明变量的;var_name参数是变量的名称,这里可以同时定义多个变量;type参数用来指定变量的类型;DEFAULT value子句将变量默认值设置为value,没有使用DEFAULT子句时,默认值为NULL。只能用在存储过程或者函数内部

    在过程中定义的变量并不是真正的定义,你只是在BEGIN/END(即复合语句)块内定义了而已。注意这些变量和会话变量不一样,不能使用修饰符@你必须清楚的在BEGIN/END块中声明变量和它们的类型。变量一旦声明,你就能在任何能使用会话变量、文字、列名的地方使用。还需要注意的一点是,在一个块内,我们需要把所有要使用的变量先声明,才能在后面使用,并且不能在声明变量的语句间夹杂其他使用变量的语句,否会报语法错误。

    CREATE PROCEDURE P5()
    BEGIN
     DECLARE a INT;
     DECLARE b INT;
     SET a = 5;
     SET b = 5;
     INSERT INTO t VALUES(a);
     SELECT s1 FROM t WHERE s1>= b;
    END;
    -------------------------------------------------
    mysql> CALL p5();
    +----+
    | s1 |
    +----+
    |  5 |
    |  5 |
    +----+
    2 rows in set
     
    Query OK, 0 rows affected
    

    MySQL中可以使用SET关键字来为变量赋值。SET语句的基本语法如下:

    SET  var_name = expr [, var_name = expr] ... 
    

    MySQL中还可以使用SELECT…INTO语句为变量赋值。其基本语法如下:

    SELECT  col_name[,…]  INTO  var_name[,…]  
    FROM  table_name  WEHRE  condition 
    

    其中,col_name参数表示查询的字段名称;var_name参数是变量的名称;table_name参数指表的名称;condition参数指查询条件。

    -- 查看系统变量 show variables [like pattern]
    show variables like "innodb%";
    
    -- set 变量名=变量值; 注意:为了区分用户自定义变量和系统变量,需要在用户自定义变量名称前加@符号。例如 set @name=’John’;
    -- 如果在存储过程或者函数中用DECLARE来预先定义了某个变量,后面的set可以不用加@,详见后文例子;
    set @userTotel = (select count(*) from users); -- Set赋值用法的变量值也可是标量查询的结果
    
    -- select 字段 from 表名 into @变量名
    select nickname from users ORDER BY user_money desc limit 1 into @richName;
    SELECT id,data INTO x,y FROM test.t1 LIMIT 1; -- 这个SELECT语法把选定的列直接存储到变量。因此,只有单一的行可以被取回
    
    -- select @变量名:=变量值 与 select @变量名=变量值
    set @who = 'zhouzhou';
    select @who='小李'; -- 注意:此处不是赋值操作,而是变量的判断,如果@who变量是已经存在了,那就判断@who中的值是否等于'小李',返回0或1;如果@who的变量不存在就返回NULL;
    

    注意

    • 变量的有效期为会话结束后,变量就失效(即断开连接后,变量失效)!
    • 变量的作用域: 用户定义的变量是全局的。但在函数内定义的变量则是局部的。
    • 变量的数据类型与字段的数据类型一致!

    输出变量

    select @who;
    

    分支语句

    IF

    语法

    IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list] ...
    [ELSE statement_list]
    END IF;
    

    statement_list: 多条语句由;号隔开

    实例

    delimiter $
    CREATE PROCEDURE `hd`(IN `arg` TINYINT)
    BEGIN
    DECLARE `age` TINYINT DEFAULT 0;
    SET `age` = `arg`;
    IF `age`<20 THEN
    SELECT "年轻人";
    ELSEIF `age`<40 THEN
    SELECT "青年人";
    ELSELF
    SELECT "OLD MAN";
    END IF;
    END$
    
    create procedure proc_getGrade
    (stu_no varchar(20),cour_no varchar(10))
    begin 
    declare stu_grade float;
    select grade into stu_grade from grade where student_no=stu_no and course_no=cour_no;
    if stu_grade>=90 then 
    select stu_grade,'a';
    elseif stu_grade<90 and stu_grade>=80 then 
    select stu_grade,'b';
    elseif stu_grade<80 and stu_grade>=70 then 
    select stu_grade,'c';
    elseif stu_grade<70 and stu_grade>=60 then 
    select stu_grade,'d';
    else 
    select stu_grade,'e';
    end if;
    end 
    

    三元表达式

    SELECT IF(@a=1,'真','失败');
    

    IFNULL(字段,值)

    select age,ifnull(age,"空") from c; -- 如果age的值为null就返回空;
    

    NULLIF(expr1,expr2)

    -- 如果表达式1=表达式2,则返回null,否则返回第1个表达式 
    SELECT NULLIF(5,5);  -- null
    
    SELECT NULLIF(10,4); -- 10
    

    case

    CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list] ...
    [ELSE statement_list]
    END CASE 
    或者
    CASE 
    WHEN search_condition THEN statement_list
    [WHEN search_condition THEN statement_list] ...
    [ELSE statement_list]
    END CASE 
    

    Example1

    delimiter $
    CREATE PROCEDURE `pro2`(INOUT `arg` INT)
    BEGIN
    DECLARE `i` INT DEFAULT 0;
    SET `i` = `arg`;
    CASE `i` 
    WHEN 1 THEN
    SELECT "sina";
    WHEN 2 THEN
    SELECT "baidu";
    ELSE 
    SELECT "163";
    END CASE;
    END;
    $
    delimiter ;
    

    Example2

    delimiter $
    CREATE PROCEDURE `pro3`(INOUT `arg` INT)
    BEGIN
    DECLARE `i` INT DEFAULT 0;
    SET `i` = `arg`;
    CASE
    WHEN i = 1 THEN
    SELECT "sina";
    WHEN i = 2 THEN
    SELECT "baidu";
    ELSE 
    SELECT "163";
    END CASE;
    END;
    $
    delimiter ;
    

    循环

    leave

    退出循环

    LEAVE label -- 退出循环,注意如果要使用leave的话,循环就必须得带上leave;
    

    while

    [begin_label:] WHILE search_condition DO
    statement_list
    END WHILE [end_label]
    

    Example1

    delimiter $
    CREATE PROCEDURE `createstu`(IN `num` INT)
    BEGIN
    DECLARE `i` INT DEFAULT 0;
    DECLARE `yeard` DATE;
    WHILE `num`>0 DO
    SET `yeard` = DATE_SUB("2000-1-1",INTERVAL `i` DAY);
    INSERT INTO `test` (`sname`,`birthday`) VALUES(MD5(`i`),`yeard`);
    SET `i`=`i`+1;
    SET `num`=`num`-1;
    END WHILE;
    END$
    

    loop

    [begin_label:] LOOP
    statement_list
    END LOOP [end_label]
    

    Example1

    delimiter $
    create procedure t_loop()
    begin 
    declare i int;
    set i = 0;
    loop_label:loop 
    insert into test(sname,birthday) values(md5(i),2005);
    set i = i + 1;
    if i > 100 then 
    leave loop_label; -- 注意这里的label是必须的哦;
    end if;
    end loop;
    end$
    delimiter ;
    

    loop是在执行后检查结果,while是在执行前检查结果

    repeat

    [begin_label:] REPEAT
    statement_list
    UNTIL search_condition  -- REPEAT语句内的语句或语句群被重复,直至search_condition 为真。
    END REPEAT [end_label]
    

    Example1

    delimiter $
    create procedure t_repeat()
    begin 
    declare i int;
    set i = 100;
    repeat 
    insert into test(sname,birthday) values(md5(i),1988);
    set i = i + 5;
    until i > 10000 -- 注意until此处没有分号,是为和下面的end链接一起的;
    end repeat;
    end;$
    

    其他

    INSERT INTO SELECT

    语法

    Insert into Table2(field1,field2,...) select value1,value2,... from Table1
    

    要求目标表Table2必须存在,如果目标table2已经存在了,并且和table1的结构一样的话,可以直接 Insert into Table2 select * from Table1,如果结构不一样,就要Table2的字段对应Table1的字段

    SELECT INTO FROM

    语法

    SELECT vale1, value2 into Table2 from Table1 
    
    1. 要求目标表Table2不存在,因为在插入时会自动创建表Table2,并将Table1中指定字段数据复制到Table2中。
    2. 注意: MySQL不支持Sybase SQL扩展:SELECT ... INTO TABLE ....。只支持select 字段 from 表名 into @变量名

    replace into

    replace into table (id,name) values('1','aa'),('2','bb') -- 此语句的作用是向表table中插入两条记录。如果主键id为1或2不存在就相当于insert into table (id,name) values('1','aa'),('2','bb') ,如果存在相同的值则不会插入数据  
    

    create...select

    -- 创建表并插入它表的数据进来;
    CREATE TABLE tdb_goods_brands (
      brand_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
      brand_name VARCHAR (40) NOT NULL
    ) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8 COMMENT = '用户信息表' SELECT
      brand_name
    FROM
      tdb_goods
    GROUP BY
      brand_name;
    
    -------------------------END-------------------------

    博客园的阅读体验比起sf的要差很多,所以博客已迁移至segmentfault。 链接:https://segmentfault.com/blog/nixi8 部分文档已整理到看云 https://www.kancloud.cn/@xiaoa
  • 相关阅读:
    链表的相关操作
    【回溯】旅行商问题
    【回溯】图的m着色问题
    奶牛卧室_待解决
    阶乘问题
    子数整数
    hihoCoder week4 Trie图
    hihoCoder week3 KMP算法
    hihoCoder week2 Trie树
    hihoCoder week1 最长回文子串
  • 原文地址:https://www.cnblogs.com/nixi8/p/4457757.html
Copyright © 2011-2022 走看看