1

I'm trying to create a schema after inserting a new "something" What is the correct syntax on PostgreSQL14 (or even older versions) that will give me the same as CREATE SCHEMA IF NOT EXISTS ischema where ischema is the function input, ischema?

CREATE OR REPLACE FUNCTION blah_insert_something(
    IN iname varchar,
    IN ischema varchar
) RETURNS UUID
    LANGUAGE plpgsql AS
$$
DECLARE
    result UUID;
BEGIN
    INSERT INTO internal.something(name, schema, data)
    VALUES ($1, $2, '{}')
    RETURNING id INTO result;

    CREATE SCHEMA IF NOT EXISTS "$2";

    RETURN result;
END;
$$

Currently it literally creates a schema called $2, if I remove the quotes or use single quotes, it complains about invalid syntax. If I put ischema in there and run

SELECT blah_insert_something('test', 'testing')

it literally creates a schema called ischema instead of testing.

What is the correct syntax to make this demo code work?

2
  • 2
    You need to use dynamic SQL with EXECUTE. Use the format() function. Commented Sep 17, 2022 at 22:27
  • Format works well with @nbk's solution: CREATE SCHEMA IF NOT EXISTS ' || format('prefix_%I', $2) || ';'; I will need to be very careful about SQL injection here Commented Sep 18, 2022 at 6:42

1 Answer 1

3

Your function makes not much sense but you need dynamic sql for that

CREATE OR REPLACE FUNCTION blah_insert_something(
    IN iname varchar,
    IN ischema varchar
) RETURNS UUID
    LANGUAGE plpgsql AS
$$
DECLARE
    result UUID;
    stmt text;
BEGIN
    INSERT INTO internal.something(name, schema, data)
    VALUES ($1, $2, '{}')
    RETURNING id INTO result;

     
     stmt = 'CREATE SCHEMA IF NOT EXISTS ' || $2 || ';';
    

     EXECUTE stmt;
    

    RETURN result;
END;
$$
Sign up to request clarification or add additional context in comments.

2 Comments

a table to track all "entities" which is inside the internal schema and then a schema for each entity so their data is completely separate
I had to remove the IMMEDIATE part and I discovered that my semicolon is in the wrong place, it should be after the $$, not after END, otherwise this solution works, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.