使用obclient 建库,脚本里面的&会被当成变量,导致数据执行进去是错的

【 使用环境 】生产环境 or 测试环境
【 OB or 其他组件 】oboracle
【 使用版本 】
【问题描述】使用obclient 建库,脚本里面的&会被当成变量,导致数据执行进去是错的
【复现路径】问题出现前后相关操作
obclient -h$Host -u$User -P$Port -p$PW $DataBase --default-character-set=utf8 -A -c -vvvnc -e “source $SQL_FILE”

INSERT INTO KD_SYSMENU_EXT (SYSID,MENUID,ICON,PAGE_URL,REFER_MENU,LOAD_TYPE) VALUES (100,999999996,NULL,‘external/report/index.html#/admin-report/views/ReportPage?uuId=999999996&editable=false’,NULL,‘1’)
插入后数据
external/report/index.html#/admin-report/views/ReportPage?uuId=999999996=false
【附件及日志】推荐使用OceanBase敏捷诊断工具obdiag收集诊断信息,详情参见链接(右键跳转查看):

【SOP系列 22 】——故障诊断第一步(自助诊断和诊断信息收集)

【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!

5 个赞

您好,根据您的描述,在使用obclient建库时遇到了脚本中的特殊字符&被误解析为变量导致的问题。这个问题听起来像是SQL语句执行过程中遇到了特定字符的转义问题,可能需要检查SQL语句本身以及使用的客户端工具设置。

对于这种类型的问题,虽然obdiag主要用于处理OceanBase数据库运行时遇到的一些常见性能、稳定性问题等场景,并没有直接针对SQL语法错误或特殊字符解析异常的具体分析场景。但是,通过收集集群的基础信息或者SQL执行相关的日志文件,也许能够帮助我们更好地理解问题背景。

因此建议先进行基础信息和SQL执行相关日志的收集工作:

日志采集场景: 集群基础信息
日志采集命令: obdiag gather scene run --scene=observer.base

日志采集场景: SQL执行出错
日志采集命令: obdiag gather scene run --scene=observer.sql_err --env "{db_connect='-h<your_host> -P<port> -u<username>@<tenant> -p<password> -D<database>', trace_id='<your_trace_id>'}"

请将上述命令中的<your_host><port><username><tenant><password><database>替换为您实际连接OceanBase数据库时所需的值;另外,请提供一个具体的trace_id以便更精确地定位问题发生的上下文。

为了能够更加准确地定位问题并提供解决方案,我还需要您提供以下一些额外的信息:

  1. 您所使用的obclient版本是多少?
  2. 能否分享引起问题的具体SQL脚本部分?(确保敏感信息已被脱敏)
  3. 执行该脚本时是否还有其他特殊的环境配置或参数设定?
  4. 发生问题前后,是否有任何错误消息输出?如果有,请详细说明。
  5. 该问题是在尝试创建新的数据库表结构时出现还是在向已有表中插入数据时发生?

请您按照上述指引操作后,将收集到的日志打包发送给我们,我们将进一步协助您解决此问题。感谢您的配合!

附上敏捷诊断工具 obdiag 使用帮助链接

1 个赞

obclient Ver 2.2.8 Distrib 10.4.18-MariaDB, for Linux (x86_64) using readline 5.1

#!/bin/bash
source ./config_oceanbase_oracle.ini
echo "oceanbase host: $Host port: $Port basedir: $File "

set ob_query_timeout=36000000000;
set ob_trx_timeout=36000000000;
set names SIMPLIFIED CHINESE_CHINA.AL32UTF8;
execute_sql_file() {
local User=$1
local PW=$2
local DataBase=$3
local SQL_FILE=$4

if [ ! -f "$SQL_FILE" ]; then
    echo "Error: File $SQL_FILE not found!"
    exit 1
fi

 obclient -h$Host -u$User -P$Port -p$PW $DataBase --default-character-set=utf8 -A -c -vvvnc -e "source $SQL_FILE"

}

execute_sql_file “$user_master” “$pass_master” “$database_master” “${File}/master/kd_sysmenu_ext.sql”

kd_sysmenu_ext.sql
set define off

INSERT INTO KD_SYSMENU_EXT (SYSID,MENUID,ICON,PAGE_URL,REFER_MENU,LOAD_TYPE) VALUES (100,999999992,NULL,‘external/report/index.html#/admin-report/views/ReportPage?uuId=999999992&editable=false’,NULL,‘1’);

INSERT INTO KD_SYSMENU_EXT (SYSID,MENUID,ICON,PAGE_URL,REFER_MENU,LOAD_TYPE) VALUES (100,999999994,NULL,‘external/report/index.html#/admin-report/views/ReportPage?uuId=999999994&editable=false’,NULL,‘1’);

INSERT INTO KD_SYSMENU_EXT (SYSID,MENUID,ICON,PAGE_URL,REFER_MENU,LOAD_TYPE) VALUES (100,999999995,NULL,‘external/report/index.html#/admin-report/views/ReportPage?uuId=999999995&editable=false’,NULL,‘1’);

INSERT INTO KD_SYSMENU_EXT (SYSID,MENUID,ICON,PAGE_URL,REFER_MENU,LOAD_TYPE) VALUES (100,999999996,NULL,‘external/report/index.html#/admin-report/views/ReportPage?uuId=999999996&editable=false’,NULL,‘1’);

commit;

set define on

在 obclient 中,脚本里的 & 被当作替换变量,需在脚本开头加 SET DEFINE OFF 禁用此行为;但仅 OBClient ≥ v2.2.4 支持该命令。‌‌
1)若 ‌OBClient 版本 ≥ 2.2.4:在建库/执行脚本的首行添加 ‌SET DEFINE OFF;,即可让 & 作为普通字符处理;
2)若 ‌OBClient 版本 < 2.2.4:‌不支持 SET DEFINE OFF(会报语法错误),需改用 CHR(38)替代&,例如 ‘NSSM_AH32_X’ || CHR(38) || ‘NSSM_AH32_Y’,或在程序/工具层面预处理转义;
3)确认版本:执行 obclient --version;若低于 2.2.4,建议升级客户端。
注意:SET DEFINE OFF是 obclient 客户端命令(非 SQL 语句),仅对当前会话有效,必须放在脚本最开头。‌若无法升级且脚本含大量 &,推荐用 CHR(38) 拼接或改用其他客户端(如 MySQL Shell、DBeaver)执行初始化脚本。‌‌

1 个赞

现在的版本是
[root@localhost init_data]# obclient --version
obclient Ver 2.2.8 Distrib 10.4.18-MariaDB, for Linux (x86_64) using readline 5.1

加了set define off不生效,要怎么处理呢

是不是可以转义啊,可以用\转义不

可不可以不要用转义,有没有参数控制,这样脚本无法兼容,ob的mysql模式就没有这种问题

--obclient 版本
obclient --version
obclient  Ver 2.2.13 Distrib 10.4.18-MariaDB, for Linux (x86_64) using readline 5.1(Built Mar  4 2026 15:12:55)



第一种方法:转义& 
obclient(SYS@oracle_tenant1)[SYS]> alter session  set current_schema=test;
Query OK, 0 rows affected (0.001 sec)

obclient(SYS@oracle_tenant1)[SYS]> create table t1 (id number(20),info varchar(300));
Query OK, 0 rows affected (0.344 sec)

obclient(SYS@oracle_tenant1)[SYS]> insert into t1 (id,info) values (1,'external/report/index.html#/admin-report/views/ReportPage?uuId=999999992'||'&'||'editable=false');
Query OK, 1 row affected (0.009 sec)

obclient(SYS@oracle_tenant1)[SYS]> commit;
Query OK, 0 rows affected (0.002 sec)

obclient(SYS@oracle_tenant1)[SYS]> select * from t1;
+------+-----------------------------------------------------------------------------------------+
| ID   | INFO                                                                                    |
+------+-----------------------------------------------------------------------------------------+
|    1 | external/report/index.html#/admin-report/views/ReportPage?uuId=999999992&editable=false |
+------+-----------------------------------------------------------------------------------------+
1 row in set (0.006 sec)



--第二种方式设置 SET DEFINE OFF; 
obclient(SYS@oracle_tenant1)[SYS]> SET DEFINE OFF;
obclient(SYS@oracle_tenant1)[SYS]> insert into t1 (id,info) values (2,'external/report/index.html#/admin-report/views/ReportPage?uuId=999999994&editable=false');
Query OK, 1 row affected (0.003 sec)

obclient(SYS@oracle_tenant1)[SYS]> commit;
Query OK, 0 rows affected (0.003 sec)

obclient(SYS@oracle_tenant1)[SYS]> select * from t1;
+------+-----------------------------------------------------------------------------------------+
| ID   | INFO                                                                                    |
+------+-----------------------------------------------------------------------------------------+
|    1 | external/report/index.html#/admin-report/views/ReportPage?uuId=999999992&editable=false |
|    2 | external/report/index.html#/admin-report/views/ReportPage?uuId=999999994&editable=false |
+------+-----------------------------------------------------------------------------------------+

你好,你提的这个技术问题牵涉到OceanBase企业版范围内的功能细节。建议你通过以下方式寻求帮助:
1.如你所在的企业客户已签署OceanBase企业版销售合同,请你联系客户经理;
2.如你所在的企业客户尚未签署OceanBase企业版销售合同,你可通过OceanBase官网商务咨询页面留下你的联系方式,OceanBase企业版的业务顾问会在一个工作日内与你联系。
OceanBase官网商务咨询

https://www.oceanbase.com/contactus?fromPage=https%3A%2F%2Fwww.oceanbase.com%2Fsoftwarecenter-enterprise&dataSources=softwarecenter-enterprise_footercontact_d2022

1 个赞

签到…

学到了