pg_get_serial_sequence 无法识别 table 名字
pg_get_serial_sequence not recognizing table name
我试图通过在过程中使用 pg_get_serial_sequence()
来获取在 table 中创建的最后一个 SERIAL ID
,但我不断收到错误消息:
[42P01]ERROR: relation "user" does not exist
Where: SQL function "insert_new_user" statement 2
User
table当然存在,我可以从中SELECT
下面是用于创建受我的函数影响的 2 tables 的 DDL 脚本:
CREATE TABLE users.User
(
ID SERIAL PRIMARY KEY,
Name TEXT NOT NULL UNIQUE,
EmailAddress TEXT,
ROWCREATE_TS TIMESTAMP,
IS_ACTIVE BOOLEAN,
INACTIVE_TS TIMESTAMP
);
CREATE TABLE users.Credential
(
CredentialValue TEXT,
UserId INT REFERENCES users.User(ID)
);
这是返回错误的过程:
/**
Creates a new user
*/
CREATE OR REPLACE PROCEDURE users.INSERT_NEW_USER(userName TEXT, emailAddress TEXT, password TEXT)
LANGUAGE SQL
AS $$
INSERT INTO users.User
(
NAME,
EmailAddress,
ROWCREATE_TS,
IS_ACTIVE
)
SELECT
INSERT_NEW_USER.userName,
INSERT_NEW_USER.emailAddress,
CURRENT_TIMESTAMP,
TRUE
WHERE
NOT EXISTS(
SELECT TRUE
FROM users.User
WHERE
NAME = INSERT_NEW_USER.userName
);
INSERT INTO users.Credential
(
CREDENTIALVALUE,
USERID
)
VALUES
(
INSERT_NEW_USER.password,
(SELECT currval(pg_get_serial_sequence('user', 'id')))
);
$$;
(注意:在有人提到它之前 - 我不打算在此处以纯文本形式存储密码。)
我能做些什么来解决这个 pg_get_serial_sequence
无法识别 User
table 的问题,或者最终将最后创建的 ID 存储到我可以使用的变量中可以传递到我的 INSERT INTO users.Credential
语句中吗?
已通过结合使用评论中的建议解决了这个问题。
我重命名了 table,因为 User
是 PostgreSQL 关键字,并且还在 pg_get_serial_sequence()
调用中使用了完全限定名称 users.NewTableName
,如下所示.
SELECT currval(pg_get_serial_sequence('users.NewTableName', 'id'))
.
编辑:值得指出的是,对于未来遇到类似问题的读者,以下内容也可以解决我将该 ID 保留到第二条语句的目标。我能够使用 WITH
:
来做到这一点
CREATE OR REPLACE PROCEDURE users.INSERT_NEW_USER(userName TEXT, emailAddress TEXT, password TEXT)
LANGUAGE SQL
AS $$
WITH Inserted as(
INSERT INTO users.Users
(
NAME,
EmailAddress,
ROWCREATE_TS,
IS_ACTIVE
)
SELECT
INSERT_NEW_USER.userName,
INSERT_NEW_USER.emailAddress,
CURRENT_TIMESTAMP,
TRUE
WHERE
NOT EXISTS(
SELECT TRUE
FROM users.Users
WHERE
NAME = INSERT_NEW_USER.userName
)
RETURNING ID
)
INSERT INTO users.Credential
(
CREDENTIALVALUE,
USERID
)
VALUES
(
INSERT_NEW_USER.password,
(SELECT Inserted.ID FROM Inserted)
);
$$;
话虽如此,我也想提醒读者,他们应该避免使用 PostgreSQL 关键字来命名 tables、变量等
我试图通过在过程中使用 pg_get_serial_sequence()
来获取在 table 中创建的最后一个 SERIAL ID
,但我不断收到错误消息:
[42P01]ERROR: relation "user" does not exist
Where: SQL function "insert_new_user" statement 2
User
table当然存在,我可以从中SELECT
下面是用于创建受我的函数影响的 2 tables 的 DDL 脚本:
CREATE TABLE users.User
(
ID SERIAL PRIMARY KEY,
Name TEXT NOT NULL UNIQUE,
EmailAddress TEXT,
ROWCREATE_TS TIMESTAMP,
IS_ACTIVE BOOLEAN,
INACTIVE_TS TIMESTAMP
);
CREATE TABLE users.Credential
(
CredentialValue TEXT,
UserId INT REFERENCES users.User(ID)
);
这是返回错误的过程:
/**
Creates a new user
*/
CREATE OR REPLACE PROCEDURE users.INSERT_NEW_USER(userName TEXT, emailAddress TEXT, password TEXT)
LANGUAGE SQL
AS $$
INSERT INTO users.User
(
NAME,
EmailAddress,
ROWCREATE_TS,
IS_ACTIVE
)
SELECT
INSERT_NEW_USER.userName,
INSERT_NEW_USER.emailAddress,
CURRENT_TIMESTAMP,
TRUE
WHERE
NOT EXISTS(
SELECT TRUE
FROM users.User
WHERE
NAME = INSERT_NEW_USER.userName
);
INSERT INTO users.Credential
(
CREDENTIALVALUE,
USERID
)
VALUES
(
INSERT_NEW_USER.password,
(SELECT currval(pg_get_serial_sequence('user', 'id')))
);
$$;
(注意:在有人提到它之前 - 我不打算在此处以纯文本形式存储密码。)
我能做些什么来解决这个 pg_get_serial_sequence
无法识别 User
table 的问题,或者最终将最后创建的 ID 存储到我可以使用的变量中可以传递到我的 INSERT INTO users.Credential
语句中吗?
已通过结合使用评论中的建议解决了这个问题。
我重命名了 table,因为 User
是 PostgreSQL 关键字,并且还在 pg_get_serial_sequence()
调用中使用了完全限定名称 users.NewTableName
,如下所示.
SELECT currval(pg_get_serial_sequence('users.NewTableName', 'id'))
.
编辑:值得指出的是,对于未来遇到类似问题的读者,以下内容也可以解决我将该 ID 保留到第二条语句的目标。我能够使用 WITH
:
CREATE OR REPLACE PROCEDURE users.INSERT_NEW_USER(userName TEXT, emailAddress TEXT, password TEXT)
LANGUAGE SQL
AS $$
WITH Inserted as(
INSERT INTO users.Users
(
NAME,
EmailAddress,
ROWCREATE_TS,
IS_ACTIVE
)
SELECT
INSERT_NEW_USER.userName,
INSERT_NEW_USER.emailAddress,
CURRENT_TIMESTAMP,
TRUE
WHERE
NOT EXISTS(
SELECT TRUE
FROM users.Users
WHERE
NAME = INSERT_NEW_USER.userName
)
RETURNING ID
)
INSERT INTO users.Credential
(
CREDENTIALVALUE,
USERID
)
VALUES
(
INSERT_NEW_USER.password,
(SELECT Inserted.ID FROM Inserted)
);
$$;
话虽如此,我也想提醒读者,他们应该避免使用 PostgreSQL 关键字来命名 tables、变量等