Reputation: 14258
I have a table:
CREATE TABLE IF NOT EXISTS "account" (
"id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
"nickname" TEXT NOT NULL UNIQUE,
"time_updated" TIMESTAMPTZ NOT NULL
);
and a function:
CREATE OR REPLACE FUNCTION account_register(
e JSON,
t TIMESTAMPTZ DEFAULT now()
) RETURNS JSON AS $$
DECLARE
o_account ACCOUNT;
BEGIN
INSERT INTO "account" (nickname, time_updated) VALUES (e -> 'nickname', t) RETURNING * INTO o_account;
RETURN row_to_json(o_account);
END
$$ LANGUAGE 'plpgsql';
It works like
SELECT account_register('{"nickname":"bob"}');
--
-- {"id"":"d3a771a9-fcff-419f-ad80-b8f5caa847da",
-- "nickname":"bob",
-- "time_updated":"2021-02-08T00:32:25.698293"}
--
I'd like to be able to replace the e JSON
to acc ACCOUNT
and have it looking something like this:
CREATE OR REPLACE FUNCTION account_register_new(
acc ACCOUNT, -- was JSON
t TIMESTAMPTZ DEFAULT now()
) RETURNS ACCOUNT AS $$ -- was JSON
DECLARE
o_account ACCOUNT;
BEGIN
-- <2. NEEDS HELP>
INSERT INTO "account" <RECORD acc> RETURNING * INTO o_account;
RETURN o_account
END
$$ LANGUAGE 'plpgsql';
to be used like:
-- <1. NEEDS HELP>
SELECT account_register(<TO_ACCOUNT>('{"nickname":"bob"}'));
So I have two questions:
{"nickname":"bob"}
into a record of type ACCOUNT
type ACCOUNT
into the ACCOUNT
tableUpvotes: 0
Views: 47
Reputation:
You need to access the columns from the passed record in the function:
CREATE OR REPLACE FUNCTION account_register(
p_new_row account,
p_time_updated TIMESTAMPTZ DEFAULT now()
)
RETURNS account
AS $$
insert into account (nickname, time_updated)
values ((p_new_row).nickname, p_time_updated)
returning *;
$$
LANGUAGE sql;
To convert a JSON value to a known record type, use json_populate_record()
select account_register(json_populate_record (null::account, '{"nickname":"bob"}'));
Btw: your function which accepts a JSON value can be simplified. There is no need to use PL/pgSQL. And you should extract the nickname using ->>
so you get a text
value, rather than json
(or jsonb
).
CREATE OR REPLACE FUNCTION account_register(
p_new_row jsonb,
p_time_updated TIMESTAMPTZ DEFAULT now()
)
RETURNS jsonb
AS $$
with new_account as (
INSERT INTO "account" (nickname, time_updated)
VALUES (e ->> 'nickname', t)
RETURNING *
)
select to_jsonb(new_account)
from new_account;
$$
LANGUAGE sql;
jsonb
is the recommended data type to work with JSON in Postgres.
Upvotes: 1