我正在使用 PostgreSQL 中的序列在 Typescript 中执行如下 Upsert:
let SAVE_CUSTOMER = `
INSERT INTO "db"."customers" ("id", "name")
VALUES (NEXTVAL('customers_sq'), $1)
ON CONFLICT ("id") DO UPDATE
SET "name" = $1;
`;
function saveCustomer(name: string) {
datasource.query(SAVE_CUSTOMER, name)
}
地点:
我收到以下错误消息:
error: i: relation \"customers_sq\" does not exist
我尝试过的事情也不起作用:
NEXTVAL('db'.'customers_sq')
NEXTVAL("db"."customers_sq")
NEXTVAL("customers_sq")
我可以在 Postgres 数据库查看器中看到该序列(也是全部小写)。有关如何调试的任何提示?
nextval()
需要一个regclass
类型的单个参数,这是一种“对象标识符类型”,基本上是基本数据类型
oid
的别名。 说明书:
按命名空间分组的对象的所有 OID 别名类型 接受模式限定名称,并将显示模式限定名称 如果在当前搜索路径中找不到该对象,则在输出中 没有资格。例如,
是可以接受的 输入myschema.mytable
(如果有这样的表格)。该值可能是 输出为regclass
,或只是myschema.mytable
,具体取决于 当前搜索路径。mytable
因此,如果您的模式名称是
db
并且序列名称是 customers_sq
- 都是令人惊讶的选择! - 那么这是正确的调用:
SELECT nextval('db.customers_sq')
如果涉及任何“非法”名称,则需要用双引号引起来。参见:
如果涉及到列所拥有的
SQUENCE
(serial
或 IDENTITY
列就是这种情况),请使用函数 pg_get_serial_sequence(table text, column text)
获得明确的答案:
SELECT pg_get_serial_sequence('db.customers', 'id');
结果经过适当格式化以传递给序列函数。
要测试给定名称的对象是否存在,而不烧录序列号,请尝试以下之一:
SELECT 'db.customers_sq'::regclass;
SELECT to_regclass('db.customers_sq');
如果对象不存在,第一个会引发异常,第二个仅返回 null。准确地说,该名称可能解析为任何类似表格的对象:表、视图等。为了确保它存在并且是一个序列:
SELECT *
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'db' -- schema name
AND c.relname = 'customers_sq' -- sequence name
AND c.relkind = 'S' -- is type sequence
或者,对于一个简短的布尔答案:
SELECT EXISTS (
SELECT FROM pg_catalog.pg_class c
WHERE c.relnamespace = 'db'::regnamespace -- schema name
AND c.relname = 'customers_sq' -- sequence name
AND c.relkind = 'S' -- is type sequence
);
参见: