PostgREST用UUID作ID迁移Oracle报错,求推荐适配数据类型
你遇到的报错核心原因是:Oracle数据库没有原生的UUID和BIGINT数据类型,同时用双引号包裹标识符会强制Oracle区分大小写(默认标识符为大写,你的语句里用了小写的"id",导致后续约束引用时出现标识符无效的问题)。
针对Oracle的ID字段,主要有以下几种推荐方案,并非只能用NUMBER类型:
1. NUMBER类型(最常用的自增ID方案)
这是Oracle中最传统且通用的ID类型,配合序列(SEQUENCE)可实现自增主键,兼容性最好。
示例建表及序列创建语句:
-- 创建序列,用于生成自增ID CREATE SEQUENCE users_id_seq START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE; -- 创建users表 CREATE TABLE users ( id NUMBER(19) NOT NULL, password VARCHAR2(255) NOT NULL, name VARCHAR2(255) NOT NULL, surname VARCHAR2(255) NOT NULL, created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, deleted_at TIMESTAMP NULL, PRIMARY KEY (id) ); -- 插入数据时调用序列生成ID INSERT INTO users (id, password, name, surname) VALUES (users_id_seq.NEXTVAL, 'encrypted_pass', 'John', 'Doe');
如果是Oracle 12c及以上版本,还可以用**标识列(IDENTITY COLUMN)**简化自增逻辑,无需手动创建序列:
CREATE TABLE users ( id NUMBER(19) GENERATED ALWAYS AS IDENTITY NOT NULL, password VARCHAR2(255) NOT NULL, name VARCHAR2(255) NOT NULL, surname VARCHAR2(255) NOT NULL, created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, deleted_at TIMESTAMP NULL, PRIMARY KEY (id) );
2. RAW(16)类型(存储二进制UUID)
如果想延续PostgREST中UUID的使用习惯,Oracle可以用RAW(16)存储二进制格式的UUID,通过内置函数SYS_GUID()生成唯一值,相比字符串存储更节省空间。
示例建表语句:
CREATE TABLE users ( id RAW(16) DEFAULT SYS_GUID() NOT NULL, password VARCHAR2(255) NOT NULL, name VARCHAR2(255) NOT NULL, surname VARCHAR2(255) NOT NULL, created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, deleted_at TIMESTAMP NULL, PRIMARY KEY (id) );
若需将二进制UUID转换为可读的字符串格式,可使用RAWTOHEX(id)函数得到32位十六进制字符串;如果要生成标准带横杠的36位UUID,可自定义函数处理。
3. VARCHAR2(36)类型(存储字符串格式UUID)
如果更倾向于直接存储可读的字符串格式UUID,可以用VARCHAR2(36)类型,通过自定义函数或第三方工具生成标准UUID字符串插入。
示例建表语句:
CREATE TABLE users ( id VARCHAR2(36) NOT NULL, password VARCHAR2(255) NOT NULL, name VARCHAR2(255) NOT NULL, surname VARCHAR2(255) NOT NULL, created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, deleted_at TIMESTAMP NULL, PRIMARY KEY (id) );
补充说明
你原来的语句中用双引号包裹标识符(比如"id"),这会让Oracle把标识符识别为小写,而Oracle默认标识符为大写,这也是导致ORA-00904: "id": invalid identifier报错的原因之一。如果不需要区分大小写,建议去掉双引号,让Oracle自动处理为大写标识符。
内容的提问来源于stack exchange,提问作者Julián Oviedo

