zoukankan      html  css  js  c++  java
  • MySQL 自定义函数.txt

    =====================MySQL基础~~编程语法============================
    常量
    1.数值
      字符串:单引号或者双引号括起来。包括普通字符串或者日期格式的字符串。
      布尔值:false(FALSE)对应数字值为0、true(TRUE)对应数字值为1。
         NULL:可以参考http://www.cnblogs.com/-beyond/p/8554483.html


    变量
    2.定义用户变量

      mysql中变量分为用户变量和系统变量。

      用户变量要先定义和初始化赋值,否则变量的值为NULL。

      用户变量只在本次连接阶段有效,其他用户的连接不能使用另外一个用户定义的变量,并且当连接释放后,变量就会销毁。

      声明变量格式:set @key = value,可以一次性声明多个。

      如果变量名中有特殊符号,那么可以用引号将变量名括起来,比如 set @'abc def' = 123;


    3. 访问用户变量
      select @name;

    4. 系统变量

    系统变量是以2个@@开头。
    mysql> select @@version;

    5. 获得系统变量列表  

    mysql> show variables;
    mysql> show variables like '%test%';

    6. 算数运算符

    + - * / %  
    +和-还可以用来计算日期; 

    mysql> select now(),now() + interval 22 day;
    +---------------------+-------------------------+
    | now()               | now() + interval 22 day |
    +---------------------+-------------------------+
    | 2018-06-19 22:55:02 | 2018-07-11 22:55:02     |
    +---------------------+-------------------------+
    1 row in set (0.00 sec)


    7. 在mysql里面,判断等于只用一个等号=,不像其他编程语言一样使用双等或者三等。判断不等使用!=和<>。
    其他比较运算符和其他编程语言一样使用。


    8. 和其他语言一样。注意or比and的优先级低,所以在where子句中进行判断时,为了保证准确性,尽量使用()保证顺序。



    9.选择判断
      mysql的选择判断一般是使用case,格式如下:
    case
        when 条件1 then 表达式1
        when 条件2 then 表达式2
        else 表达式n
    end
      示例:
    mysql> select id,name,
        -> case
        ->     when price>10 then "expensive"
        ->     when price>0 then "cheap"
        ->     else "free"
        -> end as level
        -> from cate;


    10. 循环结构

    delimiter $$
    create procedure test_while()
    begin
        declare sum int default 0;
        declare t int default 5;
        while t>0 do
            set sum=sum+1;
            set t=t-1;
        end while;
        select sum;
    end
    $$
    delimiter ;


    11. repeat

    delimiter $$
    create procedure _repeat()
    begin
        declare a int default 10;
        repeat
        set a=a-1;
        until a<5
        end repeat;
        select a;
    end
    $$
    delimiter ;


    12. loop

    delimiter $$
    create procedure test_loop()
    begin
        declare t int default 0;
        label:loop
            set t=t+1;
            if t>10 then leave label;
        end if;
        end loop label;
        select t;
    end
    $$
    delimiter ;





    一、基本语法

    delimiter 自定义符号  -- 如果函数体只有一条语句, begin和end可以省略, 同时delimiter也可以省略

    create function 函数名(形参列表) returns 返回类型  -- 注意是retruns

    begin

      函数体    -- 函数内定义的变量如:set @x = 1; 变量x为全局变量,在函数外面也可以使用

      返回值

    end

    自定义符号

    delimiter ;


    二、示例
    delimiter $$
    CREATE FUNCTION hc(a int,b int) RETURNS INT
    BEGIN
        RETURN a + b;
    END
    $$
    delimiter ;


    三、查看函数
      1. show function status [like 'pattern'];  -- 查看所有自定义函数, 自定义函数只能在本数据库使用。

      2. show create function 函数名;  -- 查看函数创建语句

    四、删除函数

      drop function 函数名;

    五、综合应用

    1. 使用全局变量
        
    delimiter $$
    CREATE FUNCTION my_sum(x int) RETURNS INT
    BEGIN
        set @i = 1;
        set @sum = 0;
        while @i <= x do
            set @sum = @sum + @i;
            set @i = @i + 1;
        end while;
        RETURN @sum;
    end
    $$
    delimiter ;


    SELECT my_sum(100);


    2. 使用局部变量

    delimiter $$
    CREATE FUNCTION my_sum2(x int) RETURNS INT
    BEGIN
        DECLARE i INT DEFAULT 1;
        DECLARE sum INT DEFAULT 0;
        sumwhile:WHILE i <= x do
            IF i % 5 = 0 then
                SET i = i + 1;
                ITERATE sumwhile;  --退出当前循环iterate 相当于 continue
            END IF;
            SET sum = sum + i;
            set i = i + 1;
        END WHILE;  --退出整个循环leave 相当于break
        RETURN sum;
    END
    $$
    delimiter ;

    SELECT my_sum2(10);


    #MySQL存储过程中declare和set定义变量的区别
    1、declare定义的变量类似java类中的局部变量,仅在类中生效。即只在存储过程中的begin和end之间生效。
     
    2、@set定义的变量,叫做会话变量,也叫用户定义变量,在整个会话中都起作用(比如某个应用的一个连接过程中),即这个变量可以在被调用的存储过程或者代码之间共享数据。如何理解呢?可以看下面这个简单例子,很好理解。

    (1)先执行下面脚本,创建一个存储过程,分别有declare形式的变量和@set形式的变量
    DROP PROCEDURE IF EXISTS temp;
    DELIMITER //
    CREATE PROCEDURE temp()
    BEGIN  
        DECLARE a INT DEFAULT 1;   
        SET a=a+1;  
        SET @b=@b+1;  
        SELECT a,@b;
    END
    //
    DELIMITER ;

    (2)接着为b变量初始化。
     
    SET @b=1;

    (3)然后重复调用这个存储过程。
     
    CALL temp();

    declare定义的类似是局部变量,@set定义的类似全局变量。



    ===================MySQL (Unix 时间戳、日期)转换函数===================

    unix_timestamp(),
    unix_timestamp(date),
    from_unixtime(unix_timestamp),
    from_unixtime(unix_timestamp,format)

    下面是示例:
    select unix_timestamp(); -- 1218290027
    select unix_timestamp('2008-08-08'); -- 1218124800
    select unix_timestamp('2008-08-08 12:30:00'); -- 1218169800

    select from_unixtime(1218290027); -- '2008-08-09 21:53:47'
    select from_unixtime(1218124800); -- '2008-08-08 00:00:00'
    select from_unixtime(1218169800); -- '2008-08-08 12:30:00'

    select from_unixtime(1218169800, '%Y %D %M %h:%i:%s %x'); -- '2008 8th August 12:30:00 2008'




    删除函数我们可以使用 DROP FUNCTION IF EXISTS function_name;

    修改函数ALTER FUNCTION  function_name  函数选项


    1.IF语句
    语法:
    IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list] ...
    [ELSE statement_list]
    END IF

    实例:
    IF age>20 THEN SET @count1=@count1+1;  
    ELSEIF age=20 THEN SET @count2=@count2+1;  
    ELSE SET @count3=@count3+1;  
    END IF;

    2.CASE语句
    语法:
    CASE
    WHEN search_condition THEN statement_list
    [WHEN search_condition THEN statement_list] ...
    [ELSE statement_list]
    END CASE

    CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list] ...
    [ELSE statement_list]
    END CASE

    实例:
    CASE age
    WHEN 20 THEN SET @count1=@count1+1;
    ELSE SET @count2=@count2+1;
    END CASE ;

    CASE
    WHEN age=20 THEN SET @count1=@count1+1;
    ELSE SET @count2=@count2+1;
    END CASE ;


    3. WHILE语句

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



    实例:
    WHILE @count<100 DO
    SET @count=@count+1;
    END WHILE ;



    3. ITERATE语句
    ITERATE语句也是用来跳出循环的语句


    4. REPEAT语句是有条件控制的循环语句。


    5. LEAVE语句主要用于跳出循环控制。

    6. LOOP语句可以使某些特定的语句重复执行,实现一个简单的循环。

    语法:
    [begin_label:] LOOP
    statement_list
    END LOOP [end_label]

    实例:
    add_num: LOOP  
    SET @count=@count+1;  
    END LOOP add_num ;



    ===================================存储过程==============================
    https://www.cnblogs.com/mark-chan/p/5384139.html

    1. MySQL存储过程的创建
    语法:
    CREATE PROCEDURE  过程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型…]]) [特性 ...] 过程体

    “DELIMITER //”声明当前段分隔符

    IN:参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
    OUT:该值可在存储过程内部被改变,并可返回
    INOUT:调用时指定,并且可被改变和返回

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


    #在MySQL客户端使用用户变量
    SELECT 'Hello World' into @x;
    SELECT @x;
    Hello World

    SET @y='Goodbye Cruel World';
    SELECT @y;
    Goodbye Cruel World

    SET @z=1+2+3;
    SELECT @z;
    6

    #在存储过程中使用用户变量
    CREATE PROCEDURE GreetWorld() SELECT CONCAT(@greeting,' World');
    SET @greeting='Hello';
    CALL GreetWorld();
    Hello World

    #在存储过程间传递全局范围的用户变量

    CREATE PROCEDURE p1() SET @last_proc='p1';
    CREATE PROCEDURE p2() SELECT CONCAT('Last procedure was ',@last_proc);
    CALL p1();
    CALL p2();
    Last procedure was p1



    #MySQL存储过程的查询
    #查询存储过程
    SELECT name FROM mysql.proc WHERE db='xy7_s9';
    SELECT routine_name FROM information_schema.routines WHERE routine_schema='xy7_s9';
    SHOW PROCEDURE STATUS WHERE db='xy7_s9';

    #查看存储过程详细信息
    SHOW CREATE PROCEDURE 数据库.存储过程名;

    #MySQL存储过程的修改
    ALTER PROCEDURE 更改用CREATE PROCEDURE 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。

    ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]
    characteristic:
    { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
    | SQL SECURITY { DEFINER | INVOKER }
    | COMMENT 'string'
    sp_name参数表示存储过程或函数的名称;
    characteristic参数指定存储函数的特性。
    CONTAINS SQL表示子程序包含SQL语句,但不包含读或写数据的语句;
    NO SQL表示子程序中不包含SQL语句;
    READS SQL DATA表示子程序中包含读数据的语句;
    MODIFIES SQL DATA表示子程序中包含写数据的语句。
    SQL SECURITY { DEFINER | INVOKER }指明谁有权限来执行,DEFINER表示只有定义者自己才能够执行;INVOKER表示调用者可以执行。
    COMMENT 'string'是注释信息。
    实例:

    #将读写权限改为MODIFIES SQL DATA,并指明调用者可以执行。
    ALTER  PROCEDURE  num_from_employee
      MODIFIES SQL DATA
      SQL SECURITY INVOKER ;
    #将读写权限改为READS SQL DATA,并加上注释信息'FIND NAME'。
    ALTER  PROCEDURE  name_from_employee
      READS SQL DATA
      COMMENT 'FIND NAME' ;

    #MySQL存储过程的删除
    DROP PROCEDURE [过程1[,过程2…]]
    从MySQL的表格中删除一个或多个存储过程。


    #MySQL存储过程的控制语句

    变量作用域

    内部变量在其作用域范围内享有更高的优先权,当执行到end时,内部变量消失,不再可见了,在存储
    过程外再也找不到这个内部变量,但是可以通过out参数或者将其值指派给会话变量来保存其值。

    #变量作用域
    DELIMITER //
      CREATE PROCEDURE proc()
        BEGIN
          DECLARE x1 VARCHAR(5) DEFAULT 'outer';
            BEGIN
              DECLARE x1 VARCHAR(5) DEFAULT 'inner';
              SELECT x1;
            END;
          SELECT x1;
        END;
        //
    DELIMITER ;
    #调用
    CALL proc();
    执行结果:
    image
    image
     
    条件语句

    IF-THEN-ELSE语句

    #条件语句IF-THEN-ELSE
    DROP PROCEDURE IF EXISTS proc3;
    DELIMITER //
    CREATE PROCEDURE proc3(IN parameter int)
      BEGIN
        DECLARE var int;
        SET var=parameter+1;
        IF var=0 THEN
          INSERT INTO t VALUES (17);
        END IF ;
        IF parameter=0 THEN
          UPDATE t SET s1=s1+1;
        ELSE
          UPDATE t SET s1=s1+2;
        END IF ;
      END ;
      //
    DELIMITER ;
    CASE-WHEN-THEN-ELSE语句

    #CASE-WHEN-THEN-ELSE语句
    DELIMITER //
      CREATE PROCEDURE proc4 (IN parameter INT)
        BEGIN
          DECLARE var INT;
          SET var=parameter+1;
          CASE var
            WHEN 0 THEN
              INSERT INTO t VALUES (17);
            WHEN 1 THEN
              INSERT INTO t VALUES (18);
            ELSE
              INSERT INTO t VALUES (19);
          END CASE ;
        END ;
      //
    DELIMITER ;
     
    循环语句
    WHILE-DO…END-WHILE
    DELIMITER //
      CREATE PROCEDURE proc5()
        BEGIN
          DECLARE var INT;
          SET var=0;
          WHILE var<6 DO
            INSERT INTO t VALUES (var);
            SET var=var+1;
          END WHILE ;
        END;
      //
    DELIMITER ;
     
    REPEAT...END REPEAT
    此语句的特点是执行操作后检查结果
    DELIMITER //
      CREATE PROCEDURE proc6 ()
        BEGIN
          DECLARE v INT;
          SET v=0;
          REPEAT
            INSERT INTO t VALUES(v);
            SET v=v+1;
            UNTIL v>=5
          END REPEAT;
        END;
      //
    DELIMITER ;
     
    LOOP...END LOOP
    DELIMITER //
      CREATE PROCEDURE proc7 ()
        BEGIN
          DECLARE v INT;
          SET v=0;
          LOOP_LABLE:LOOP
            INSERT INTO t VALUES(v);
            SET v=v+1;
            IF v >=5 THEN
              LEAVE LOOP_LABLE;
            END IF;
          END LOOP;
        END;
      //
    DELIMITER ;
     
    LABLES标号
    标号可以用在begin repeat while 或者loop 语句前,语句标号只能在合法的语句前面使用。可以跳出循环,使运行指令达到复合语句的最后一步。

    ITERATE迭代

    通过引用复合语句的标号,来从新开始复合语句

    #ITERATE
    DELIMITER //
      CREATE PROCEDURE proc8()
      BEGIN
        DECLARE v INT;
        SET v=0;
        LOOP_LABLE:LOOP
          IF v=3 THEN
            SET v=v+1;
            ITERATE LOOP_LABLE;
          END IF;
          INSERT INTO t VALUES(v);
          SET v=v+1;
          IF v>=5 THEN
            LEAVE LOOP_LABLE;
          END IF;
        END LOOP;
      END;
      //
    DELIMITER ;




    #MySQL存储过程的基本函数
    字符串类
    CHARSET(str) //返回字串字符集
    CONCAT (string2 [,... ]) //连接字串
    INSTR (string ,substring ) //返回substring首次在string中出现的位置,不存在返回0
    LCASE (string2 ) //转换成小写
    LEFT (string2 ,length ) //从string2中的左边起取length个字符
    LENGTH (string ) //string长度
    LOAD_FILE (file_name ) //从文件读取内容
    LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定开始位置
    LPAD (string2 ,length ,pad ) //重复用pad加在string开头,直到字串长度为length
    LTRIM (string2 ) //去除前端空格
    REPEAT (string2 ,count ) //重复count次
    REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替换search_str
    RPAD (string2 ,length ,pad) //在str后用pad补充,直到长度为length
    RTRIM (string2 ) //去除后端空格
    STRCMP (string1 ,string2 ) //逐字符比较两字串大小,
    SUBSTRING (str , position [,length ]) //从str的position开始,取length个字符,
    注:mysql中处理字符串时,默认第一个字符下标为1,即参数position必须大于等于1
    TRIM([[BOTH|LEADING|TRAILING] [padding] FROM]string2) //去除指定位置的指定字符
    UCASE (string2 ) //转换成大写
    RIGHT(string2,length) //取string2最后length个字符
    SPACE(count) //生成count个空格


    数学类

    ABS (number2 ) //绝对值
    BIN (decimal_number ) //十进制转二进制
    CEILING (number2 ) //向上取整
    CONV(number2,from_base,to_base) //进制转换
    FLOOR (number2 ) //向下取整
    FORMAT (number,decimal_places ) //保留小数位数
    HEX (DecimalNumber ) //转十六进制
    注:HEX()中可传入字符串,则返回其ASC-11码,如HEX('DEF')返回4142143
    也可以传入十进制整数,返回其十六进制编码,如HEX(25)返回19
    LEAST (number , number2 [,..]) //求最小值
    MOD (numerator ,denominator ) //求余
    POWER (number ,power ) //求指数
    RAND([seed]) //随机数
    ROUND (number [,decimals ]) //四舍五入,decimals为小数位数] 注:返回类型并非均为整数,
    SIGN (number2 ) // 正数返回1,负数返回-1

    日期时间类
    ADDTIME (date2 ,time_interval ) //将time_interval加到date2
    CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //转换时区
    CURRENT_DATE ( ) //当前日期
    CURRENT_TIME ( ) //当前时间
    CURRENT_TIMESTAMP ( ) //当前时间戳
    DATE (datetime ) //返回datetime的日期部分
    DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或时间
    DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式显示datetime
    DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上减去一个时间
    DATEDIFF (date1 ,date2 ) //两个日期差
    DAY (date ) //返回日期的天
    DAYNAME (date ) //英文星期
    DAYOFWEEK (date ) //星期(1-7) ,1为星期天
    DAYOFYEAR (date ) //一年中的第几天
    EXTRACT (interval_name FROM date ) //从date中提取日期的指定部分
    MAKEDATE (year ,day ) //给出年及年中的第几天,生成日期串
    MAKETIME (hour ,minute ,second ) //生成时间串
    MONTHNAME (date ) //英文月份名
    NOW ( ) //当前时间
    SEC_TO_TIME (seconds ) //秒数转成时间
    STR_TO_DATE (string ,format ) //字串转成时间,以format格式显示
    TIMEDIFF (datetime1 ,datetime2 ) //两个时间差
    TIME_TO_SEC (time ) //时间转秒数]
    WEEK (date_time [,start_of_week ]) //第几周
    YEAR (datetime ) //年份
    DAYOFMONTH(datetime) //月的第几天
    HOUR(datetime) //小时
    LAST_DAY(date) //date的月的最后日期
    MICROSECOND(datetime) //微秒
    MONTH(datetime) //月
    MINUTE(datetime) //分返回符号,正负或0
    SQRT(number2) //开平方
     

    ===================================存储函数===================================

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     

    ===================================触发器===================================

    after触发器—是在记录操纵之后触发,是先完成数据的增删改,再触发,触发的语句晚于监视的增删改操作,无法影响前面的增删改动作

    before触发器—是在记录操纵之前触发,是先完成触发,再增删改,触发的语句先于监视的增删改,我们就有机会判断,修改即将发生的操作,
    如:我们在触发之前需要判断new值和old值的大小或关系,如果满足要求就触发,不通过就修改再触发;如:表之间定义的有外键,在删除主键时,
    必须要先删除外键表,这时就有先后之分,这里before相当于设置了断点,我们可以处理删除外键。

    对于INSERT语句, 只有NEW是合法的;

    对于DELETE语句,只有OLD才合法;

    对于UPDATE语句,NEW、OLD可以同时使用。


    创建触发器的语法如下:
    CREATE TRIGGER trigger_name trigger_time trigger_event ON tb_name FOR EACH ROW trigger_stmt

    CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件
    ON 表名 FOR EACH ROW
    BEGIN
        执行语句列表
    END

    trigger_name:触发器的名称
    tirgger_time:触发时机,为BEFORE或者AFTER
    trigger_event:触发事件,为INSERT、DELETE或者UPDATE
    tb_name:表示建立触发器的表明,就是在哪张表上建立触发器
    trigger_stmt:触发器的程序体,可以是一条SQL语句或者是用BEGIN和END包含的多条语句
    所以可以说MySQL创建以下六种触发器:
    BEFORE INSERT,BEFORE DELETE,BEFORE UPDATE
    AFTER INSERT,AFTER DELETE,AFTER UPDATE

    BEFORE和AFTER参数指定了触发执行的时间,在事件之前或是之后

    FOR EACH ROW表示任何一条记录上的操作满足触发事件都会触发该触发器


    触发类型             激活触发器的语句
    INSERT                    INSERT,LOAD DATE,REPLACE
    UPDATE                     UPDATE
    DELETE                     DELETE,REPLACE
    #load data语句是将文件的内容插入到表中,相当于是insert语句,而replace语句在一般的情况下和insert差不多,但是如果表中存在primary 或者unique索引的时候,如果插入的数据和原来的primary key或者unique相同的时候,会删除原来的数据,然后增加一条新的数据,所以有的时候执行一条replace语句相当于执行了一条delete和insert语句。

    触发类型        NEW和OLD的使用
    INSERT            NEW 表示将要或者已经新增的数据
    UPDATE             OLD 用来表示将要或者已经被删除的语句,NEW将要或者已经修改的数据
    DELETE             OLD 表示将要或者已经被删除的数据

     delimiter $$
     CREATE TRIGGER upd_check BEFORE UPDATE ON account
     FOR EACH ROW
     BEGIN
       IF NEW.amount < 0 THEN
         SET NEW.amount = 0;
       ELSEIF NEW.amount > 100 THEN
         SET NEW.amount = 100;
       END IF;
     END $$
     delimiter ;


    二、查看触发器

    1、SHOW TRIGGERS语句查看触发器信息
    mysql> SHOW TRIGGERSG;

    结果,显示所有触发器的基本信息;无法查询指定的触发器。

    2、在information_schema.triggers表中查看触发器信息
    mysql> SELECT * FROM information_schema.triggersG

    show create trigger trigger_name;

    结果,显示所有触发器的详细信息;同时,该方法可以查询制定触发器的详细信息。
    mysql> select * from information_schema.triggers where trigger_name='upd_check'G;
    Tips:
    所有触发器信息都存储在information_schema数据库下的triggers表中,可以使用SELECT语句查询,如果触发器信息过多,最好通过TRIGGER_NAME字段指定查询。

    三、删除触发器

    DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
    删除触发器之后最好使用上面的方法查看一遍;同时,也可以使用database.trig来指定某个数据库中的触发器。
    Tips:
    如果不需要某个触发器时一定要将这个触发器删除,以免造成意外操作,这很关键。


    ===================================事件===================================


  • 相关阅读:
    idea 插件之 SequenceDiagram
    idea 中添加mybatis的mapper文件模板
    springBoot 中 logback配置文件详解
    Mysql show processlist、show profiles 排查问题
    input 输入框效验
    Java基础之comparator和comparable的区别以及使用
    mysql sql使用记录
    mysql 优化之索引的使用
    IDEA 中常用快捷键的使用
    form表单中method的get和post区别
  • 原文地址:https://www.cnblogs.com/huanglinsheng/p/10030667.html
Copyright © 2011-2022 走看看