🐛 fix(oracle): 修复 Oracle/Dameng 打开表时缺少 schema 前缀导致 ORA-00942

- 问题根因:GetTables 在 dbName 为空时走 user_tables 分支返回纯表名,下游 SQL 缺少 owner 前缀,引用未授权 schema 的表时报 ORA-00942
- SQL 修复:user_tables 分支改用 USER 伪列拼接 owner,确保始终返回 OWNER.TABLE_NAME 格式
- 驱动兼容:列别名用双引号包裹强制大写(AS "OWNER" / AS "TABLE_NAME"),避免不同驱动返回不一致 case 导致 row map 取值失败
- 边界保护:增加 TABLE_NAME 为 NULL 的跳过逻辑,避免污染表名输出
- 达梦对齐:DamengDB.GetTables 同步修复,保持与 Oracle 实现一致
- 测试覆盖:新增 3 个回归用例(all_tables 路径、user_tables 路径、NULL 值跳过),扩展 recording driver 支持 mock 任意查询结果
Refs #445
This commit is contained in:
Syngnat
2026-05-11 19:46:24 +08:00
parent 2d9d5f0e98
commit b22d28b79c
6 changed files with 138 additions and 163 deletions

View File

@@ -217,9 +217,13 @@ func (o *OracleDB) GetDatabases() ([]string, error) {
func (o *OracleDB) GetTables(dbName string) ([]string, error) {
// dbName is Schema/Owner
query := "SELECT table_name FROM user_tables"
// 始终返回 OWNER.TABLE_NAME避免下游 SQL 缺少 schema 前缀导致 ORA-00942refs issue #445
// 列别名用双引号包裹强制大写,避免不同驱动版本返回不一致 case 导致 row map 取值失败
var query string
if dbName != "" {
query = fmt.Sprintf("SELECT owner, table_name FROM all_tables WHERE owner = '%s' ORDER BY table_name", strings.ToUpper(dbName))
query = fmt.Sprintf(`SELECT owner AS "OWNER", table_name AS "TABLE_NAME" FROM all_tables WHERE owner = '%s' ORDER BY table_name`, strings.ToUpper(dbName))
} else {
query = `SELECT USER AS "OWNER", table_name AS "TABLE_NAME" FROM user_tables ORDER BY table_name`
}
data, _, err := o.Query(query)
@@ -229,16 +233,14 @@ func (o *OracleDB) GetTables(dbName string) ([]string, error) {
var tables []string
for _, row := range data {
if dbName != "" {
if owner, okOwner := row["OWNER"]; okOwner {
if name, okName := row["TABLE_NAME"]; okName {
tables = append(tables, fmt.Sprintf("%v.%v", owner, name))
continue
}
}
owner, okOwner := row["OWNER"]
name, okName := row["TABLE_NAME"]
if okOwner && okName && name != nil {
tables = append(tables, fmt.Sprintf("%v.%v", owner, name))
continue
}
if val, ok := row["TABLE_NAME"]; ok {
tables = append(tables, fmt.Sprintf("%v", val))
if okName && name != nil {
tables = append(tables, fmt.Sprintf("%v", name))
}
}
return tables, nil