我们一般在写sql脚本时,是不会用到delimiter的,一般情况下也用不到他具体的作用。delimiter的作用:告诉MySQL解释器,该段命令是否已经结束了,MySQL数据库是否可以执行了。我们一般是以分号;结尾一条sql,而delimiter的默认值也是;。当我们在mysql命令行敲完一段sql语句之后,在加上分号点击回车就能执行这条sql。但是当我们需要输入一个存储过程的时候,命令行就不管用了?非也,此时就需要用到delimiter来定义结束标志。为什么要讲这段内容呢,因为我们使用批处理执行sql文件时都是在客户端用命令行执行的,一旦sql文件中包含存储过程或者函数之类的,就位报各种奇葩错误。
另外delimiter作用范围需要注意一下,他作用于客户端session级别,即你断开客户端之后下次再登录时又会恢复到默认值分号。
使用source命令进行批处理,必须要在mysql客户端进行执行,所以本地需要下载一个mysql客户端,启动mysql服务,通过mysql -h ip -u username -p 来登录远程数据库。
总的批处理命令:
source C:/Users/dstn/Desktop/数据迁移/脚本/00-batch_operate.sql
实例:
现在有8个sql文件,里面包含了存储过程以及一般的sql语句,为了避免一个个单独执行,我们整理一个批处理文件。注意斜杠和乱码问题,斜杠就是/,乱码可以将客户端的编码调成utf-8。
-- 查看当前配置的编码
show variables like ‘character_set_%’;
-- 修改为utf8
set names utf8;
-- 等同于如下:
set character_set_client=utf8;
set character_set_results=utf8;
set character_set_connection=utf8;
用于执行批处理的文件:00-batch_operate.sql
delimiter $$
-- 可以打印相关的提示信息
select sysdate() as 1_application from dual $$
source C:/Users/dstn/Desktop/数据迁移/脚本/1-application.sql
select sysdate() as 2_application_batch from dual $$
source C:/Users/dstn/Desktop/数据迁移/脚本/2-application-batch.sql
select sysdate() as 3_tc_product from dual $$
source C:/Users/dstn/Desktop/数据迁移/脚本/3-tc_product.sql
select sysdate() as 4_PRO_tc_product_queryattr from dual $$
source C:/Users/dstn/Desktop/数据迁移/脚本/4-PRO_tc_product_queryattr.sql
select sysdate() as 5_PRO_tc_product_json from dual $$
source C:/Users/dstn/Desktop/数据迁移/脚本/5-PRO_tc_product_json.sql
select sysdate() as 6_tc_intent_user from dual $$
source C:/Users/dstn/Desktop/数据迁移/脚本/6-tc_intent_user.sql
select sysdate() as 7_product_cycle_status from dual $$
source C:/Users/dstn/Desktop/数据迁移/脚本/7-product_cycle_status.sql
select sysdate() as 8_tc_log from dual $$
source C:/Users/dstn/Desktop/数据迁移/脚本/8-tc_log.sql
下面再举一个其中的sql文件:1-application.sql
DROP PROCEDURE IF EXISTS `ta_application_all`;
CREATE PROCEDURE `ta_application_all`(in productCodeTemp VARCHAR(20))
BEGIN
DECLARE applyCode VARCHAR(20);
DECLARE done INT DEFAULT FALSE;
DECLARE cur CURSOR FOR select distinct(appl_code) from tjs_dev.ta_application_detail WHERE `key` = 'productCode' and `VALUE` = productCodeTemp;
/**定义游标结束标志**/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
LOOP_LABLE:loop
FETCH cur INTO applyCode;
if done THEN
LEAVE LOOP_LABLE;
END IF;
Insert into tjfae_dev.ta_application (APPL_CODE,APPL_NAME,TYPE,STAGE,`STATUS`,OPERATOR,MEMO,IS_DELETE,GMT_CREATE,GMT_MODIFY,EXCHANGE_ID)
select APPL_CODE,APPL_NAME,TYPE,STAGE,`STATUS`,OPERATOR,MEMO,IS_DELETE,GMT_CREATE,GMT_MODIFY,EXCHANGE_ID from tjs_dev.ta_application where APPL_CODE=applyCode;
end LOOP;
CLOSE cur;
END;
$$
使用ant进行批处理的好处是,不需要下载mysql客户端,只需要引入mysql的jar包即可,使用ant还可以配合其他命令来调整脚本文件,方便多个脚本进行修改,例如修改schema。如下脚本执行命令:ant ConnectMySQL
<project name="exchange-core" basedir="." default="ConnectMySQL">
<property file="build.properties" />
<target name="replace" description="修改sql文件">
<property file="build.properties" />
<echo message="previous product vesion ${sourcePrevious}" />
<echo message="current product vesion ${sourceCurrent}" />
<replace encoding="UTF-8">
<replacefilter token="${sourcePrevious}" value="${sourceCurrent}" />
<fileset dir="${basedir}" includes="../*.sql" />
replace>
target>
<target name="ConnectMySQL" depends="replace">
<sql driver="${mysqlDriver}"
url="${mysqlUrl}"
userid="${mysqlUser}"
password="${mysqlPassword}"
classpath="${mysqlJar}"
-- 保持原有文件格式 -->
keepformat="true"
delimiter="$$"
print="true">
select sysdate() from dual;$$
<transaction src="${mysqlFile1}"/>
<transaction src="${mysqlFile2}"/>
sql>
target>
project>
属性文件,build.properties
#The source database scheme
sourcePrevious=test1
sourceCurrent=test2
#JDBC connection
mysqlDriver = com.mysql.jdbc.Driver
mysqlJar = mysql-connector-java-5.1.9.jar
#Target database
mysqlUrl = jdbc:mysql://ip/schema
mysqlUser = tjs_dev
mysqlPassword = tjs_2!3
mysqlFile1 = ../1-application.sql
mysqlFile2 = ../1-application2.sql
目录结构如下:
ant批处理mysql脚本:.
│─1-application.sql
│─1-application2.sql
│
└─build
build.properties
build.xml
mysql-connector-java-5.1.9.jar