达梦数据库操作及一些奇葩错误

背景

国产数据库:达梦

操作

1、登录

安装路径在:/dm8/bin
登录脚本:./disql username/'"pwd"'@127.0.0.1:5236 (密码要用双引号给圈起来,因为如果密码也有一个 @ 符号的话,容易串

传输脚本到服务器:scp sys_*.sql username@10.12.2.21:/home/dmdba/dbscript/grey_init_script
执行脚本:start /home/dmdba/script/grey_test/sys_area_.sql ( 对,就在窗口,这样执行一个语句,它会读取文件,然后一行一行执行。。。总感觉效率是很低的样子)

有一个很崩溃的点:它执行报错,还是会继续往下跑,根本不会停下来。你都不知道从什么时候,就开始错了。很崩溃。

知识点

1、达梦脚本不支持 '' (esc 下面那个键的标点), 需要改成双引号, 即: user_name` 要改成 "user_name"
2、它对脚本是大小写敏感的。(至少就现在观察而言,如果字段是大写,Insert语句写了小写,就会报错,识别不了字段)

3、自增列

4、查看建表语句

5、start xxx.sql (这个语句后面不能加 “;”)

6、把查询的结果,输出到文本上

将查询结果输出到指定文件。
语法如下:
SPOOL /data/files/test.txt
select * from user;
SPOOL OFF

7、id自增的表,要导入数据:Only if specified in the column list and SET IDENTITY_INSERT is ON, then identity column could be as

两个步骤:
(1)SET IDENTITY_INSERT 表名 on;
(2)insert into 表名(id, 列1,列2,... 列n) select * from 另一个表 limit 10; (意思是, 目标表必须要把列给标明,否则还是会报错的)

8、关于锁表

(注:执行这个语句,要dba权限)
(1)查询被锁表的信息:
select distinct b.NAME,c.SESS_ID from v$lock a
left join sysobjects b on b.ID=a.TABLE_ID
left join v$sessions c on a.TRX_ID=c.TRX_ID where b.name = 'xxx';
(建议做一下表的过滤,数据可能很多)
(2)关闭被锁会话:
sp_close_session(sess_id) //sess_id为上面语句执行后查询出来的数据
(3)但是会发现步骤1执行后,结合会很多,就是一个表会有很多会话,都是阻塞等待,锁表状态,所以,一个一个去复制粘贴明显是不太行的;同时,在达梦的cli窗口上,是没有比较好的办法查看全量记录的,拿不到全量的 sess_id, 所以也关不掉全量的。
so,需要把步骤1的结果,输出到文本上,再在文本上编辑,就容易多了。——见下一个话题

9、把语句的执行结果输出到文本中

有一些时候,需要把语句的执行结果存储起来,并且也去导库导表又太麻烦,可以把结果输入到文本中。
语法如下:
SPOOL /data/files/test.txt
select * from "user";
SPOOL OFF

即可。
其中 /data/files/test.txt 为要存放结果的文本。
中间一行或多行,为要执行的语句。

10、创建用户

create tablespace tbs_xxxdb DATAFILE '/dmdata/dmdb/tbs_xxxdb.dbf' SIZE 200 AUTOEXTEND ON NEXT 10;
CREATE USER tbs_xxxdb IDENTIFIED BY "tbs_xxxdb@abc" default tablespace tbs_xxxdb default INDEX TABLESPACE tbs_xxxdb;
grant resource,public to tbs_xxxdb;
用户:tbs_xxxdb
密码:tbs_xxxdb@abc

11、连账号带表都清掉(清库)

drop user 用户名 cascade;

12、查看实例名

创建了多个实例,虽然有账号密码,也可以登录了,但代码连接数据库的时候,还是需要拿到实例名才可以连接。那实例名要怎样查看呢:
进入达梦安装的服务器,
使用 ps 查看进程启动详情, ps -ef | grep dm

拿到实例名,就可以在代码里面创建连接了。

也就是这个:
jdbc:dm://192.168.1.100:5236/dbmbutf8?useUnicode=true&characterEncoding=UTF-8
或者
jdbc:dm://192.168.1.100:5236/dmdb?useUnicode=true&characterEncoding=UTF-8
然后连接不同实例名,和对应的账号密码进行连接。

13、达梦保留关键词的配置

默认情况下,有一些关键词会被保留,比如 domain,
但原来的库表里面已经用了 domain 作为字段名,代码也写了这么一个sql 。执行的时候,会报错。怎么办呢,这个时候,要把这个关键词在 dm.ini 文件中标记,让它不要对这个词进行检测,

首先, ps -ef | grep dm,
找到 :
/home/dmdba/dmdbms/bin/dmserver path=/dmdata/dbmbutf8/dbmbutf8/dm.ini -noconsole
发现现在这个进程修改这个路径下的dm.ini
vim /dmdata/dbmbutf8/dbmbutf8/dm.ini

把要排队掉的保留字,添加进去即可。

然后再重启dm
systemctl stop DmService
systemctl start DmService
(附: ls -l /usr/lib/systemd/system/Dm* 这个语句,可以看一下达梦注册的服务叫什么名字)。

14、查看表结构

desc table_name;

15、查看版本号:

select id_code;
版本号:1-2-98-21.12.30-154539-10040-SEC Pack1

16、设置 mysql 兼容

出现 只能select 限于 group by 的字段。
比如 select a from user group by a; 这种可以; 但 select b from user group by a; 这种执行的情况。

select para_name,para_value,file_value from v$dm_ini where para_name='COMPATIBLE_MODE';
行号 para_name para_value file_value
---------- --------------- ---------- ----------
1 COMPATIBLE_MODE 0 0

sp_set_para_value(2,'COMPATIBLE_MODE',4);
行号 para_name para_value file_value
---------- --------------- ---------- ----------
1 COMPATIBLE_MODE 0 4

17、创建表空间时,报错:[-3410]:表空间上有事务未提交.

解决步骤:

  • 找到了个有一点挨近的可能性:https://blog.csdn.net/weixin_42447367/article/details/107910837

  • 找到未提交的事务
    活动事务数量 SELECT COUNT(1) FROM V$TRX WHERE STATUS='ACTIVE';
    这个有4条数据,显示是活动中的事务

  • 停掉,或删除掉未提交的事务,是不是就可以了

  • 好吧,其实找了很多,都没有特别好的解决方法(应该是我的搜索能力一直不太够,想找的问题,一直都没有匹配度较高的)
    最后,想了一下,既然它说,表空间上有事务未提交,那找到全部的事务(会话),全部close掉,是不是就好了。。

  • 嗯,事实证明,这个办法,可行。
    select sess_id from v$sessions; --这个语句,找到所有的会话,然后放到一个 文本上,
    sp_close_session(sess_id); -- 杀掉这些会话。嗯
    再创建表空间,嗯。。。就好了。(无了个大语。。。)

18、特殊字符处理

方法有两种,

  • 方法1:
    简单的方法就是:在执行语句之前,先执行一下: set define off;

  • 方法2:
    相关麻烦一点,
    每个特殊字符前后都用 '||' 包起来
    image

19、输入单引号

在达梦里面,单引号代表字符串,如果想输入一个单引号,需要用 '''' 代表一个单引号(即用 4个 " ' '" 来输出一个)
image

20、达梦 fail to cast string

这个是类型错误的问题,比如想做一个非空判断,

在 DEPARTMENT 这张表里面  dept_type 这个字段是 Int 类型, 把一个 Int 类型和一个字符串做比较,就会报错
-- 可以
select  case when dept_type = '' then NULL else dept_type end as dept_type from DEPARTMENT limit 1;  
-- 不可以
select  case when dept_type = '' or DEPT_TYPE = 'null' then NULL else dept_type end as dept_type from DEPARTMENT limit 1; 

这个语句会报: [22000][-6111]Fail to cast string  (意为类型转换错误)

21、导出的脚本,再导入,报错 [-7021]:无效的索引名.

奇怪啊。这个真的很奇葩
如果一个表在创建的时候,定义的唯一主键
再把这个表导出的时候,它就会自动创建一个唯一索引
并且这个唯一索引,再执行的时候,还报错!
大概是长这个样子的:CREATE UNIQUE INDEX INDEX33559118 ON INSTANCE (INSTANCE_ID,PORT);
这个 INDEX33559118 索引名是非法的。看样子是达梦它自己维护的一个唯一索引(也是唯一主键)
嗯,怎么办呢,

现在使用的办法就是曲线救国,把这个索引名给改掉,
把 INDEX33559118 改成 INDEX_33559118 就好了。(对,只要不是 INDEX + 数字就行)
服了。

二、一些常用指令:

达梦常用的指令

--、查看关键字:
SELECT * FROM V$RESERVED_WORDS;


达梦 查询全部表
select table_name from user_tables; //当前用户拥有的表
select table_name from all_tables; //所有用户的表
select table_name from dba_tables; //包括系统表
select table_name from dba_tables where owner='用户名'
	user_tables:table_name,tablespace_name,last_analyzed等
	dba_tables: ower,table_name,tablespace_name,last_analyzed等
	all_tables: ower,table_name,tablespace_name,last_analyzed等
	all_objects   ower,object_name,subobject_name,object_id,created,last_ddl_time,timestamp,status等​
 
-- 获取表字段:​
select * from user_tab_columns where Table_Name='用户表';
select * from all_tab_columns where Table_Name='用户表';
select * from dba_tab_columns where Table_Name='用户表';
	user_tab_columns:
		table_name,column_name,data_type,data_length,data_precision,data_scale,nullable,column_id等
	all_tab_columns :
		ower,table_name,column_name,data_type,data_length,data_precision,data_scale,nullable,column_id等
	dba_tab_columns:
		ower,table_name,column_name,data_type,data_length,data_precision,data_scale,nullable,column_id等​
 
-- 获取表注释:​
select * from user_tab_comments
	user_tab_comments:table_name,table_type,comments
	相应的还有dba_tab_comments,all_tab_comments,这两个比user_tab_comments多了ower列。
 
-- 获取字段注释:
select * from user_col_comments
	user_col_comments:table_name,column_name,comments


-- 修改表字段类型
alter table "user" modify("name" VARCHAR(36) NOT NULL);
-- (char 类型会自动填充空格,varchar不会。如果原来用了 char 类型,填充了空格,再使用 alter table 改为 varchar类型后,会自动把空格去掉的)








posted @ 2022-04-19 13:50  aaacarrot  阅读(5420)  评论(0编辑  收藏  举报