I have tables that use UUIDs. I want to be able to insert a new row with or without a UUID as sometimes the client will generate the UUID other times it won't.
Each table has this at it's core:
CREATE TABLE IF NOT EXISTS person (
id UUID PRIMARY KEY DEFAULT gen_random_uuid()
);
I'm trying to use a function to insert rows. I'd like to be able to hand a NULL id and get a default value (a generated UUID). I have something like this:
CREATE OR REPLACE FUNCTION create_person(
id UUID
) RETURNS BOOLEAN LANGUAGE plpgsql SECURITY DEFINER AS $$
BEGIN
INSERT INTO person( id )
VALUES (
COALESCE(id,default)
);
RETURN FOUND;
END;
$$;
I've tried this:
INSERT INTO person ( id ) VALUES (
COALESCE(id, default),
);
and this:
INSERT INTO person ( id ) VALUES (
CASE WHEN id IS NULL THEN default ELSE id END
);
This works, but it repeats the gen_random_uuid() code:
INSERT INTO person ( id ) VALUES (
COALESCE(id, gen_random_uuid()),
);
similarly this works too but has the same problems:
INSERT INTO person ( id ) VALUES (
CASE WHEN id IS NULL THEN gen_random_uuid() ELSE id END
);
Is there a way to do this where I don't have to repeat the gen_random_uuid()
code?
Would this be better done with plpgsql
?
If all the values in MySQL COALESCE() function are NULL then it returns NULL as the output. It means that this function does not find any non-NULL value in the list.
The SQL Coalesce and IsNull functions are used to handle NULL values. During the expression evaluation process the NULL values are replaced with the user-defined value. The SQL Coalesce function evaluates the arguments in order and always returns first non-null value from the defined argument list.
There is no coalesce for zero.
You can insert NULL value into an int column with a condition i.e. the column must not have NOT NULL constraints. The syntax is as follows. INSERT INTO yourTableName(yourColumnName) values(NULL); To understand the above syntax, let us first create a table.
There's no way to re-use the defined default on the column. The default is only there to define what happens if an INSERT
doesn't specify a value. By this definition a null
value is still "specified" and therefore default can't be used.
Your comment that someone might not use the function indicates that a trigger is better for your requirements than a simple function.
https://www.postgresql.org/docs/current/static/plpgsql-trigger.html
CREATE OR REPLACE FUNCTION default_id() RETURNS TRIGGER AS $default_id$
BEGIN
IF (NEW.id IS NULL) THEN
NEW.id := gen_random_uuid();
END IF;
RETURN NEW;
END;
$default_id$ LANGUAGE plpgsql;
CREATE TRIGGER default_id_trigger
BEFORE INSERT OR UPDATE ON person
FOR EACH ROW EXECUTE PROCEDURE default_id();
If you do want to do this with a function then the simplest way is just to assign the value before inserting:
CREATE OR REPLACE FUNCTION create_person(
id UUID
) RETURNS BOOLEAN LANGUAGE plpgsql SECURITY DEFINER AS $$
BEGIN
IF id IS NULL THEN
id := gen_random_uuid();
END IF;
-- OR
-- id := coalesce(id, gen_random_uuid());
INSERT INTO person( id )
VALUES (id);
RETURN FOUND;
END;
$$;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With