跳转至

Oracle Database 连接器

Oracle Database 经 ODPI-C 走 OCI 接入。编译出的 SQL 用的是 Oracle 自己的写法——FETCH FIRST 做限制、TRUNC(x, 'FMT') 做时间粒度截断、带引号的 interval 字面量(INTERVAL '1' MONTH)、表别名不带 AS

构建期不依赖 Oracle:ODPI-C 随 crate 一起编译,免费的 Oracle Instant Client 在首次连接时才加载。只有真正要连 Oracle 的机器才需要装它。连接走池化、按需建立。由 exec-oracle 控制。

连接配置

datasources:
  oracle:
    type: oracle
    host: db.internal
    port: 1521
    username: main
    password: ${ORACLE_PASSWORD}
    database: ORCLPDB1        # 服务名

或者用 EZConnect URL:

datasources:
  oracle:
    type: oracle
    uri: oracle://main:${ORACLE_PASSWORD}@db.internal:1521/ORCLPDB1

参数

类型 必填 默认 说明
type string oracle
host string 是* *除非给了 uri:
port int 监听器默认 可选:EZConnect 也接受 //host/service
username string 是* 离散写法下必填。
password string 是* 离散写法下必填。尽量用 ${VAR}
database string 是* 这里填的是服务名,不是 schema。离散写法下必填。
uri string oracle://user:pass@host:port/service。口令里带 @ 也没问题——主机是从最后一个 @ 切开的。
default bool false 连接配置

本连接器解析但不使用的键: schema(这里没有 CURRENT_SCHEMA 固定,见下)、sslmodesslrootcertarrow_flight_portcatalogaccountrolewarehousecompat_mode

每条连接打开时都会开启自动提交,并执行四条 ALTER SESSIONTIME_ZONE = 'UTC' 用于无时区取值约定,以及 ISO 的 NLS_DATE_FORMAT / NLS_TIMESTAMP_FORMAT——没有它们,Oracle 默认的 DD-MON-RR 会直接拒绝编译出来的 CAST('2024-01-01' AS DATE) 字面量。

schema 怎么解析

在 Oracle 里,schema 就是用户。编译出的 SQL 按模型里写的引用 <schema>.<table>,所以登录账号必须拥有这些对象,或者能看到它们。这里没有 schema: 键可以改写这一点:要么用模型里那个名字创建登录用户,要么授权后用同义词。

有一处语义差异 Dosi 不做归一:Oracle 把 '' 当成 NULL。

已知限制

Oracle 23ai 上没有需要声明的限制——它自带原生的三参数 DATEDIFF,那个在别的引擎上都要跳过的用例,在这里能跑。

两点与版本相关:19c 和 21c 没有 DATEDIFF,所以用到它的指标无法移植到那些版本;另外多行 INSERTDROP TABLE IF EXISTS 和原生 BOOLEAN 类型(灌数路径会用到)都是 23ai 才有的能力。

实际使用中最现实的限制是运行时依赖:机器上没有 Instant Client,这个连接器根本连不上。

本地验证连接

$ dosi query --model model.yaml \
    --metrics revenue --group-by orders.status --execute --connection oracle

排错

报错 原因与处理
提到 DPI-1047config 错误,提示里说连接 Oracle 需要装上免费的 Oracle Instant Client 并放到加载路径上 装它(dnf install oracle-instantclient-basic),或者解压后把 LD_LIBRARY_PATH 指过去。库的架构必须和二进制一致。
connection "x": oracle needs database: (the service name) database: 填服务名(例如 FREEPDB1),不是 schema。
connection "x": oracle needs username: / … needs password: 离散写法下两者都必填。
connection "x": expected an oracle:// url uri: 必须用 oracle:// scheme。
connection "x": oracle url needs user:pass@host/service URL 里缺了凭据或服务名部分。
server rejected SQL (ORA-NNNNN): <message> Oracle 拒了编译出的语句;ORA-00942 通常意味着模型里的 schema 不是登录用户。
this build has no oracle executor (feature "exec-oracle" not enabled) 官方二进制自带;自己编译的要加 --features exec-oracle

参考链接