背景
在做数据迁移的时候经常要用到的一些语句,记录一下
比如,从开发库要表和数据初始化到另外一个测试库作为初始化数据
通过脚本去执行当然可以,但效率会相对低一点
近来有这么一个交付验收的场景,于是把相关的操作记录一下
清库
清库的方式有三种:
● (1)把库都删掉,然后再把库创建回来
drop database if exists activiti_db;
create database activiti_db;
● (2)不删库,只删表(更通用一些)
先查询这个库下面的所有表,然后再拼出drop table 的语句。
达梦下,查询全部表的语句:
select table_name from dba_tables WHERE owner = 'mydb'; —— 达梦,要使用DBA账号才能查询得到
select table_name from information_schema.tables WHERE owner = 'mydb'; —— mysql
SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') FROM information_schema.tables WHERE table_schema = 'mydb'; —— 这种是mysql 的写法
SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') FROM dba_tables WHERE owner = 'mydb'; —— 达梦的写法,没啥区别
● (3)还有一种,比较狠,把某个用户下的所有东西全部删掉,不建议使用,轻易别使用
drop user 用户名 cascade;
导入导出的语句
导出语句
2.1 导出一个库
./dexp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exp.dmp DIRECTORY=/opt/dm/scripts LOG=table_dev_imp.log
2.2 导出某一张或几张表
如下,只导出 dev_member, dev_base 这两张表
./dexp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exp.dmp DIRECTORY=/opt/dm/scripts LOG=table_dev_imp.log TABLES=dev_member, dev_base
2.4 不导部分表
./dexp USERID=username/'"password"''@127.0.0.1:5237 FILE=dev_part1.dmp DIRECTORY=/opt/dm/scripts LOG=dev_exp.log EXCLUDE=TABLES:DEV_TE, DEV_LVE;
2.5 只导表结构,不导出表数据
- 语句一:
./dexp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exp.dmp DIRECTORY=/opt/dm/scripts LOG=table_dev_imp.log TABLES=dev_member EXCLUDE=ROWS (这是一种方式)
- 语句二:
./dexp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exp.dmp DIRECTORY=/opt/dm/scripts LOG=table_dev_imp.log TABLES=dev_member ROWS=N
2.6 只导出部分数据(表结构全要,但数据只要一部分)
● 指定部分表(精准匹配)
./dexp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exptest.dmp DIRECTORY=/opt/dm/scripts LOG=table_dev_imp.log TABLES=dev_member, dev_base QUERY="where rownum <= 5"
● 指定部分表(模糊匹配)
./dexp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exptest.dmp DIRECTORY=/opt/dm/scripts LOG=table_dev_imp.log TABLES=% QUERY="where rownum < 2" fuzzy_match=y —— 这样可以
./dexp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exptest.dmp DIRECTORY=/opt/dm/scripts LOG=table_dev_imp.log TABLES=% QUERY="where rownum < 2" —— 这样报错 [警告]导出模式错误
问题:
出现了 [警告]导出模式错误 这样的错误提示
【问题解决】
query 参数必须与 tables 参数一起使用,如果要导出全库的表结构及部分数据则可以使用如下的方法:
dexp.exe SYSDBA/SYSDBA FILE=D:\TEST.dmp tables=sysdba.%,test.%, ... query="where rownum<=100" fuzzy_match=y
其中 fuzzy_match=y 表示启用模糊匹配,tables 要列出所有模式。
原来官网上有描述了。。。
导入语句
2.7 导入一个空库
这种情况,表和数据会一起导入
./dimp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exp.dmp DIRECTORY=/opt/dm/scripts REMAP_SCHEMA=dev:pre FULL=Y PRIMARY_CONFLICT=OVERWRITE
2.7 只导入表结构,不导入数据
./dimp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exp.dmp DIRECTORY=/opt/dm/scripts REMAP_SCHEMA=dev:pre FULL=Y PRIMARY_CONFLICT=OVERWRITE EXCLUDE=ROWS (ROWS=N也是一样的)
关于导入导出的一些场景:
背景描述:比如有A库,和B库,要把A库的 MEMBER表导出,然后再导入给B库
-
场景1:A库的表结构和B库的表结构不一致,这个时候导入会出现什么现象呢?
—— 无论是怎么个不一致法,它都无法导入成功 会提示:[警 告 ]导 入 表 dev_member错 误 , 检 查 表 定 义
—— 所以说,要么表不存在,要表结构得一致才行(这里说的表结构一致,只需要是表字段都匹配得上就行,其它的约束没有受限) -
场景2:B库中的member表 已经存在
如果直接执行./dimp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exp.dmp DIRECTORY=/opt/dm/scripts REMAP_SCHEMA=dev:pre FULL=Y, 会提示报错,因为表已经存在
添加一个参数: ./dimp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exp.dmp DIRECTORY=/opt/dm/scripts REMAP_SCHEMA=dev:pre FULL=Y PRIMARY_CONFLICT=OVERWRITE 这样就可以导入成功了
(REMAP_SCHEMA=dev:pre 这个参数不一定需要,有试过,用了这个参数虽然导入成功,但是查询总会报没有查询权限的问题,原因不明。但不添加这个参数,也能够正常导入,并且查询正常。所以这个参数,在必要的时候再添加即可。)
并且:
【重点】
如果先有表结构,只要字段匹配,表结构及其约束不会再更新,但数据可以同步过去。比如,原有创建一张A表,id 可重复,然后再把另外一张表结构一样的B表导进来,即使B表的id字段不允许重复,它导进来了,它只会把数据带过来,而不会破坏原有表结构的约束。
意思就是:导入的表不会改变原有表的约束。只需要表结构一致,就可以导入。
如果表结构一致,就不要破坏原有表的约束或规则
如果表不存在,就会完全同步过来。
- 场景3:多次导入(导入语句执行多次)
从 dev 库导出一张表 dev_member 导出, pre 库存在这张表,表结构一致,约束也是一样的,如果尝试 dimp, 能否导入?数据能否覆盖?还是新增?
导入的语句是:./dimp USERID=username/'"password"''@127.0.0.1:5237 FILE=imp_exp.dmp DIRECTORY=/opt/dm/scripts REMAP_SCHEMA=dev:pre FULL=Y PRIMARY_CONFLICT=OVERWRITE
—— 会重复新增,并且主键也重复了,好奇怪。
这个 id 竟然不是主键???还是说即使是主键,也能够写入?有这么强吗?这个id 在这里是自增的,但竟然也还是写进去了,是怎样做到的?还是说,这就是个bug ?
很疑惑,还是有什么参数可调???
—— 如果不带后面的 PRIMARY_CONFLICT=OVERWRITE 参数,就会报 [警 告 ]表 已 存 在 , 表 dev_member 导 入 失 败 ... 的错误。所以不带会报错,带了会出现主键重复。也是挺头疼的,估计是有其它的参数设置吧。