零、说在前面

在定义函数之前 需要先将 log_bin_trust_function_creators 值设为开启,原因如下

在主从复制的两台Mysql服务器中,slaver会从master复制数据,而一些操作,比如function所得到的结果可能在slaver和master中不同,可能存在安全隐患,因此,默认情况下该值为0 阻止function的创建。

有两种办法解决:

1.将log_bin_trust_function_creators设为ON 这样一来 开启了log-bin的Mysql server变可以随意创建function。但这样会存在潜在的数据安全问题,除非明确知道该函数在主从上的行为一致。(另外,如果在master上创建函数想通过主从复制的方式将函数复制到slaver上则也需要开启slaver 的log_bin_trust_function_creators)

mysql> show variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF |
+---------------------------------+-------+ mysql> set global log_bin_trust_function_creators=1;

2.明确致命函数的类型。

  • DETERMINISTIC 不确定的
  • NO SQL 没有SQL语句,当然也不会修改数据
  • READS SQL DATA 只是读取数据

比如 CREATE DEFINER = 'username'@'%' READS SQL DATA FUNCTION 'function_name'(,,,,,,) RETURNS ....

这里我们先选用第一种方式,,因为我们只做一下批量数据导入,slaver不会用到这些函数,,,更重要的是也没slaver。。。

==============================================分割线=================================

还有一点点

mysql 的默认结束符为“;” (半角!,这里打全角是方便看)

DELIMITER $$    命令会把结束符改为 $$

==============================================分割线=================================

一、自定义函数

创建函数

DELIMITER $$
CREATE FUNCTION 函数名称(参数列表) // CREATE FUNCTION 'fun'(a int,b int)
RETURNS 返回值类型 // RETURNS VARCHAR(255)
BEGIN
(函数体)
END $$
DELIMITER ;

查看函数

  • show function status; (可后面加函数名)--查看所有自定义函数
  • show create function (函数名) ;   --查看创建函数语句

删除函数

  • drop function 函数名;

定义变量

DECLARE 变量1[,变量2...] 变量类型 [DEFAULT 默认值]

或者可以直接 使用用户变量 @变量名

DECLARE a,b INT DEFAULT 0;
@ a;

变量赋值

SET 变量名1=值 [,变量名2=值];

SELECT INTO 变量名

:= 为第一个的简化版(:=为mysql中的赋值语句,因为=在默认环境下(想想sql语句里是不是‘=‘都是判断了)表示判断,所以 =必须配合 set 或者update使用)

1. SET x = 1 ;
SET y = fun();
=============================================
2. DECLARE x int DEFAULT 0;
SELECT COUNT(id) FROM tdb_name INTO x;
=============================================
3. x:=1;
y:=fun();

if语句

IF condition THEN ...;
[ELSEIF condition THEN ...;]
[ELSE ...;]
END IF EXA:
IF age>20 THEN SET @count1=@count1+1;
ELSEIF age=20 THEN SET @count2=@count2+1;
ELSE SET @count3=@count3+1;
END IF;

while 语句

WHILE condition DO
...;
END WHILE exa:
WHILE @count<100 DO
SET @count=@count+1;
END WHILE ;

实战啦~~

先随机产生随机整数DELIMITER $$

CREATE FUNCTION if exist rand_int(a INT,b INT) RETURNS INT
BEGIN
DECLARE ba INT(11) DEFAULT 0;
DECLARE rang INT(11) DEFAULT 0;
DECLARE ret INT(11) DEFAULT 0;
SET ba = a;
SET rang = b-a+1;
SET ret=FLOOR(base+RAND()*rang); ----------FLOOR函数取整 返回小于等于x的最大整数
RETURN ret; ----------RAND 生成0-1随机数 不包括1
END $$
DELIMITER ;

随机产生字符串函数

DELIMITER $$
CREATE FUNCTION rand_str(n INT) RETURNS VARCHAR(255)
BEGIN
DECLARE str VARCHAR(255) DEFAULT '012345679abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
DECLARE ret VARCHAR(255) DEFAULT '';
DECLARE i INT DEFAULT 0;
WHILE i < n DO
SET ret = concat(ret,SUBSTRING(str,rand_int(1,62),1));
SET i = i + 1;
END WHILE;
RETURN ret;
END $$
DELIMITER ;

concat(a,b)拼接ab两个字符串

substring (a,b,c)取a的子串,从b开始取c长。(第一个字符位置是1)

二、自定义存储过程

存储过程与函数的区别。

  • 函数只能通过return返回单个值或者表对象。而存储过程不执行return,通过out参数返回多个值(函数的参数只能是in类型)。
  • 函数是可以内嵌在sql中使用的,在select中调用,但存储过程不行。
  • 函数限制比较多,不能用临时表,只能用变量。
  • 当对数据库进行复杂操作时,可以将复杂操作用一个存储过程封装起来,与事务结合使用,简化复杂语句。
  • 存储过程中的crud会影响数据库,但函数不能。

创建存储过程

CREATE [definer = {user|current_user}] PROCEDURE 存储过程名 ( [IN|OUT|INOUT] 参数名 数据类型.....)

BEGIN

.....

END

调用存储过程:

CALL 过程名(参数名)  //没有参数的 括号也可以省略

删除存储过程

DROP PROCEDURE 过程名

查看存储过程

1.SHOW PROCEDUER STATUS

2.SHOW CREATE PROCEDURE 过程名

测试表定义

=======================================================

A表有两个字段 id INT(primarykey autoincrement)  name VARCHAR(not null default '')

B表有三个字段 id INT(primarykey autoincrement)  name VARCHAR(not null default '')  type INT(notnull default '')

type 字段关联A表id字段。

=======================================================

创建批量插入 存储过程

A表的

DELIMITER $$
CREATE PROCEDURE MUTI_INSERT_A (IN insert_time INT)
BEGIN
DECLARE i INT DEFAULT 0; ---这两行交换位置会报错。
SET AUTOCOMMIT = 0; ---可能是要先声明变量。
WHILE i<insert_time D
INSERT INTO A (name) values(rand_str(8));
SET i = i+1;
END WHILE;
COMMIT;
SET AUTOCOMMIT = 1;
END $$
DELIMITER ;

  B表

DELIMITER $$
CREATE PROCEDURE MUTI_INSERT_B (IN insert_time INT)
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE a_id_max INT DEFAULT 0;
SET AUTOCOMMIT = 0;
SELECT MAX(id) INTO a_id_max FROM A; ---获取A表中的最大id
WHILE i<insert_time DO
INSERT INTO B (name,type) values(rand_str(8),rand_int(0,a_id_max)); ---限制与A.id相关的type列最大值
SET i = i+1;
END WHILE;
COMMIT;
SET AUTOCOMMIT = 1;
END $$
DELIMITER ;

  注意!!! 此时 A表内没数据  第7行会返回null  但在表约束里 type not null  故要先插入A表数据。

测试一下 , 先跑个 百万数据。

........手残打成一千万了。。。 把会话关了。。还好事务没提交.回滚了。。。先来个十万吧。。

mysql> call muti_insert_a(100000);
Query OK, 0 rows affected (57.52 sec)

以后还是不在自己电脑上玩这种骚操作了。。

然后删表又卡主了。。。

重新清空了一下,a表跑10k条,b表跑10w

Mysql 函数定义及批量数据脚本的更多相关文章

  1. mysql批量数据脚本

    mysql批量数据脚本 1 建表 create table dept( id int unsigned primary key auto_increment, deptno mediumint uns ...

  2. MySQL批量数据脚本示例

    一.建表 # 新建库 create database bigData; use bigData; #1 建表dept CREATE TABLE dept( id INT UNSIGNED PRIMAR ...

  3. python连接mysql循环插入千万条数据脚本

    之前都是在mysql的存储过程中插入数据,毕竟mysql语法函数有限,很多都有限制.突然想到学了python正好可以练练手.首先需要安装pymysql模块包(模块包安装请自行百度) pip insta ...

  4. mysql 函数在源码中的定义

    大牛那海蓝蓝 MySQL提供了较为丰富的SQL语句,用以支持MySQL提供的主要功能.在数据库内部,MySQL又是怎么知道自己能够处理哪些对象.处理哪些事情的? 如果我们输入一条SQL语句,MySQL ...

  5. mysql函数之六:mysql插入数据后返回自增ID的方法,last_insert_id(),selectkey

    mysql插入数据后返回自增ID的方法 mysql和oracle插入的时候有一个很大的区别是,oracle支持序列做id,mysql本身有一个列可以做自增长字段,mysql在插入一条数据后,如何能获得 ...

  6. mysql函数之七:replace() MySQL批量替换指定字段字符串

    mysql replace实例说明: UPDATE tb1 SET f1=REPLACE(f1, 'abc', 'def'); REPLACE(str,from_str,to_str) 在字符串 st ...

  7. MySQL数据库笔记六:数据定义语言及数据库的备份和修复

    1. MySQL中的函数 <1>加密函数 password(str) 该函数可以对字符串str进行加密,一般情况下,此函数给用户密码加密. select PASSWORD('tlxy666 ...

  8. MySQL数据操作与查询笔记 • 【第5章 MySQL 函数】

    全部章节   >>>> 本章目录 5.1 数学函数和控制流函数 5.1.1 数学函数 5.1.2 控制流函数 5.2 字符串函数 5.2.1 字符串函数介绍 5.2.2 字符串 ...

  9. Linux C 调用MYSQL API 函数mysql_escape_string()转义插入数据

    Title:Linux C 调用MYSQL API 函数mysql_escape_string()转义插入数据 --2013-10-11 11:57 #include <stdio.h> ...

随机推荐

  1. ASP.NET一般处理程序之网站请求过程

  2. 回味Ubuntu10.10致敬Gnome桌面

    目录 Ubuntu10.10可用源 Ubuntu10.10更新语言包 输入法支持 浏览器选择 文件下载 压缩文件中文乱码的处理 视频播放 科学计算 搭建Lamp环境 实现文件分享 主题美化 Ubunt ...

  3. Google Waymo自动驾驶安全技术报告(二)

    Waymo的技术在公开道路上.封闭测试场.仿真器进行了广泛的测试,所以可以保证自动驾驶系统的每一部分在其ODD内都有强大.可靠.安全的处理能力. Waymo的自动驾驶系统由三个相互独立.严格测试的子系 ...

  4. 深入浅出Mybatis系列二-配置简介(mybatis源码篇)

    注:本文转载自南轲梦 注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 上篇文章<深入浅出Mybatis系列(一)---Mybatis入门>, ...

  5. WPF-命令-基础知识

    命令模型的主要元素: 1.命令 2.命令绑定:命令连接到相关的应用程序逻辑 3.命令源:命令源触发命令, 4.命令目标:应用程序逻辑. -------------------------------- ...

  6. react-native简单使用

    基本组件的使用介绍 View: Text: TextInput: Image: Button: ActivityIndicator: ScrollView:这是一个列表滚动的组件 ListView:也 ...

  7. SVM-支持向量机(三)SVM回归与原理

    SVM回归 我们之前提到过,SVM算法功能非常强大:不仅支持线性与非线性的分类,也支持线性与非线性回归.它的主要思想是逆转目标:在分类问题中,是要在两个类别中拟合最大可能的街道(间隔),同时限制间隔侵 ...

  8. HDFS写入数据

    HDFS副本摆放策略 不同的版本副本摆放策略可能并不一致,HDFS主要采用一种机架感知(rack-ware)的机制来实现摆放策略. 由于不同的机架上节点间通信要通过交换机(switches),同一机架 ...

  9. Wannafly Camp 2020 Day 1E 树与路径 - 树上差分,LCA

    #include <bits/stdc++.h> using namespace std; #define int long long const int N = 1000005; vec ...

  10. [CQOI2009] 中位数 - 桶

    给出 \(1~n\) 的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是 \(b\).中位数是指把所有元素从小到大排列后,位于中间的数. Solution (这个题为什么会被打上数学标签? ...