【DM版本】: V8 DB Version: 0x7000c
【操作系统】:Windows 11 专业版
【CPU】: Intel(R) Core(TM) i5-10500 CPU @ 3.10GHz 3.10 GHz
【问题描述】*:其他数据库如 SQL Server
、MySQL
和 PostgreSQL
在 Golang 中使用 GORM 同时执行多条 SQL 语句是正常的,而 DM
会报 语法分析出错,希望可以允许在 Golang 中同时执行多条 SQL 语句,谢谢。
有如下 3 条SQL 语句:
DROP TABLE IF EXISTS "test_migrator";
CREATE TABLE "test_migrator" (
"id" BIGINT NOT NULL COMMENT '流水号参数唯一标识',
"data_table_name" VARCHAR(255) NOT NULL COMMENT '数据库表名',
"data_table_desc" VARCHAR(255) COMMENT '数据库表名(中文)说明信息',
"serial_value" VARCHAR(64) COMMENT '流水号当前最大值',
"serial_length" TINYINT COMMENT '流水号长度,不足前缀补“0”,不能超过所属字段长度',
"enabled" BIT COMMENT '是否可用:0-禁用;1-可用',
"remark" VARCHAR(1000) COMMENT '备注信息',
PRIMARY KEY ("id")
);
COMMENT ON TABLE "test_migrator" IS '系统流水号配置表';
在 “DM管理工具” 中同时选中 3 条 SQL 语句可以正常执行:
总共3个语句正依次执行...
[执行语句1]:
DROP TABLE IF EXISTS "test_migrator";
执行成功, 执行耗时106毫秒. 执行号:2410
影响了0条记录
[执行语句2]:
CREATE TABLE "test_migrator" (
"id" BIGINT NOT NULL COMMENT '流水号参数唯一标识',
"data_table_name" VARCHAR(255) NOT NULL COMMENT '数据库表名',
"data_table_desc" VARCHAR(255) COMMENT '数据库表名(中文)说明信息',
"serial_value" VARCHAR(64) COMMENT '流水号当前最大值',
"serial_length" TINYINT COMMENT '流水号长度,不足前缀补“0”,不能超过所属字段长度',
"enabled" BIT COMMENT '是否可用:0-禁用;1-可用',
"remark" VARCHAR(1000) COMMENT '备注信息',
PRIMARY KEY ("id")
);
执行成功, 执行耗时45毫秒. 执行号:2411
影响了0条记录
[执行语句3]:
COMMENT ON TABLE "test_migrator" IS '系统流水号配置表';
执行成功, 执行耗时17毫秒. 执行号:2412
影响了0条记录
3条语句执行成功
在 Go 语言中使用 GORM 同时执行 3 条 SQL 语句报 语法分析出错:
func TestDaMengMigratorOnce(t *testing.T) {
tx := initDaMengConn()
sqlRaw := `DROP TABLE IF EXISTS "test_migrator";
CREATE TABLE "test_migrator" (
"id" VARCHAR(32) NOT NULL COMMENT '流水号参数唯一 ID',
"data_table_name" VARCHAR(255) NOT NULL COMMENT '数据库表名',
/* ... */
"enabled" BIT COMMENT '是否可用:0-禁用;1-可用',
"remark" VARCHAR(1000) COMMENT '备注信息',
PRIMARY KEY ("id")
);
COMMENT ON TABLE "test_migrator" IS '系统流水号配置表';`
tx = tx.Exec(sqlRaw)
if err := tx.Error; err != nil {
t.Errorf("TestDaMengMigratorOnce() got error: %v", err)
} else {
t.Log("TestDaMengMigratorOnce() success!")
}
}
[INFO] 2023/11/01 11:54:36.086622 @[ db_conn_test.go:355 ] 初始化 GORM 数据库连接成功:[ dm -> 192.168.200.81:5237 ]
2023-11-01 11:54:36.089 ERROR database/database.go:58
[SQL 语句] DROP TABLE IF EXISTS "test_migrator";
CREATE TABLE "test_migrator" (
"id" VARCHAR(32) NOT NULL COMMENT '流水号参数唯一 ID',
"data_table_name" VARCHAR(255) NOT NULL COMMENT '数据库表名',
/* ... */
"enabled" BIT COMMENT '是否可用:0-禁用;1-可用',
"remark" VARCHAR(1000) COMMENT '备注信息',
PRIMARY KEY ("id")
);
COMMENT ON TABLE "test_migrator" IS '系统流水号配置表';
[错误信息] Error -2007: 第 12 行, 第 10 列[COMMENT]附近出现错误:
语法分析出错
stack info:
1). github.com/godoes/gorm-dameng/dm8.(*dm_build_833).dm_build_866
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/zq.go:725
2). github.com/godoes/gorm-dameng/dm8.(*dm_build_833).dm_build_822
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/zq.go:712
3). github.com/godoes/gorm-dameng/dm8.(*dm_build_833).dm_build_825
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/zq.go:762
4). github.com/godoes/gorm-dameng/dm8.(*dm_build_414).dm_build_454
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/a.go:269
5). github.com/godoes/gorm-dameng/dm8.(*dm_build_414).Dm_build_482
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/a.go:360
6). github.com/godoes/gorm-dameng/dm8.(*dm_build_414).Dm_build_500
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/a.go:381
7). github.com/godoes/gorm-dameng/dm8.(*DmConnection).executeInner
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/m.go:204
8). github.com/godoes/gorm-dameng/dm8.(*DmConnection).execContext
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/m.go:598
9). github.com/godoes/gorm-dameng/dm8.(*filterChain).DmConnectionExecContext
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/zd.go:149
10). github.com/godoes/gorm-dameng/dm8.(*reconnectFilter).DmConnectionExecContext
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/zf.go:238
11). github.com/godoes/gorm-dameng/dm8.(*filterChain).DmConnectionExecContext
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/zd.go:146
12). github.com/godoes/gorm-dameng/dm8.(*DmConnection).ExecContext
E:/Workspace/Go/granada.framework/vendor/github.com/godoes/gorm-dameng/dm8/m.go:293
13). database/sql.ctxDriverExec
D:/Dev/Go/SDK/go/src/database/sql/ctxutil.go:31
14). database/sql.(*DB).execDC.func2
D:/Dev/Go/SDK/go/src/database/sql/sql.go:1675
15). database/sql.withLock
D:/Dev/Go/SDK/go/src/database/sql/sql.go:3405
16). database/sql.(*DB).execDC
D:/Dev/Go/SDK/go/src/database/sql/sql.go:1670
17). database/sql.(*DB).exec
D:/Dev/Go/SDK/go/src/database/sql/sql.go:1655
18). database/sql.(*DB).ExecContext.func1
D:/Dev/Go/SDK/go/src/database/sql/sql.go:1634
19). database/sql.(*DB).retry
D:/Dev/Go/SDK/go/src/database/sql/sql.go:1538
20). database/sql.(*DB).ExecContext
D:/Dev/Go/SDK/go/src/database/sql/sql.go:1633
21). gorm.io/gorm/callbacks.RawExec
E:/Workspace/Go/granada.framework/vendor/gorm.io/gorm/callbacks/raw.go:9
22). gorm.io/gorm.(*processor).Execute
E:/Workspace/Go/granada.framework/vendor/gorm.io/gorm/callbacks.go:130
23). gorm.io/gorm.(*DB).Exec
E:/Workspace/Go/granada.framework/vendor/gorm.io/gorm/finisher_api.go:765
24). basic/database.TestDaMengMigratorOnce
E:/Workspace/Go/granada.framework/basic/database/db_conn_test.go:457
25). testing.tRunner
D:/Dev/Go/SDK/go/src/testing/testing.go:1576
26). runtime.goexit
D:/Dev/Go/SDK/go/src/runtime/asm_amd64.s:1598
[执行用时] 1.98ms
[影响行数] 0
db_conn_test.go:459: TestDaMengMigratorOnce() got error: Error -2007: 第 12 行, 第 10 列[COMMENT]附近出现错误:
语法分析出错
stack info:
...
--- FAIL: TestDaMengMigratorOnce (0.04s)
FAIL
在 Go 语言中使用 GORM 分开执行 3 条 SQL 语句结果正常:
func TestDaMengMigrator(t *testing.T) {
tx := initDaMengConn()
dropRaw := `DROP TABLE IF EXISTS "test_migrator";`
createRaw := `
CREATE TABLE "test_migrator" (
"id" VARCHAR(32) NOT NULL COMMENT '流水号参数唯一 ID',
"data_table_name" VARCHAR(255) NOT NULL COMMENT '数据库表名',
/* ... */
"enabled" BIT COMMENT '是否可用:0-禁用;1-可用',
"remark" VARCHAR(1000) COMMENT '备注信息',
PRIMARY KEY ("id")
);`
commentRaw := `COMMENT ON TABLE "test_migrator" IS '系统流水号配置表';`
type args struct {
tx *gorm.DB
raw string
}
tests := []struct {
name string
args args
}{
{"DROP", args{tx, dropRaw}},
{"CREATE", args{tx, createRaw}},
{"COMMENT", args{tx, commentRaw}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db := tt.args.tx
db = tx.Exec(tt.args.raw)
if err := db.Error; err != nil {
t.Errorf("TestDaMengMigrator() got error %v", err)
} else {
t.Log("TestDaMengMigrator() success!")
}
})
}
}
[INFO] 2023/11/01 11:59:00.971363 @[ db_conn_test.go:355 ] 初始化 GORM 数据库连接成功:[ dm -> 192.168.200.81:5237 ]
=== RUN TestDaMengMigrator/DROP
2023-11-01 11:59:01.058 DEBUG database/database.go:37
[SQL 语句] DROP TABLE IF EXISTS "test_migrator";
[执行用时] 86.50ms
[影响行数] 0
db_conn_test.go:435: TestDaMengMigrator() success!
=== RUN TestDaMengMigrator/CREATE
2023-11-01 11:59:01.099 DEBUG database/database.go:37
[SQL 语句]
CREATE TABLE "test_migrator" (
"id" VARCHAR(32) NOT NULL COMMENT '流水号参数唯一 ID',
"data_table_name" VARCHAR(255) NOT NULL COMMENT '数据库表名',
/* ... */
"enabled" BIT COMMENT '是否可用:0-禁用;1-可用',
"remark" VARCHAR(1000) COMMENT '备注信息',
PRIMARY KEY ("id")
);
[执行用时] 40.88ms
[影响行数] 0
db_conn_test.go:435: TestDaMengMigrator() success!
=== RUN TestDaMengMigrator/COMMENT
2023-11-01 11:59:01.116 DEBUG database/database.go:37
[SQL 语句] COMMENT ON TABLE "test_migrator" IS '系统流水号配置表';
[执行用时] 15.16ms
[影响行数] 0
db_conn_test.go:435: TestDaMengMigrator() success!
--- PASS: TestDaMengMigrator (0.18s)
--- PASS: TestDaMengMigrator/DROP (0.09s)
--- PASS: TestDaMengMigrator/CREATE (0.04s)
--- PASS: TestDaMengMigrator/COMMENT (0.02s)
PASS
</details>
可以把多条需要执行的语句,装到
begin
execute immediate 'sql;'
execute immediate 'sql';
.
.
COMMIT;
end;
/