Re: CREATE TABLE AS inside of a function

From: "Kevin Nikiforuk" <Kevin(dot)Nikiforuk(at)Acrodex(dot)com>
To: "Erik Jones" <erik(at)myemma(dot)com>, "Rodrigo De Leon" <rdeleonp(at)gmail(dot)com>
Cc: <pgsql-sql(at)postgresql(dot)org>
Subject: Re: CREATE TABLE AS inside of a function
Date: 2006-07-24 20:49:52
Message-ID: 6EA72AC41F81D242A38AAF505523A94D022DFC@kappa.acrodex.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-sql

So, I've changed my code as Erik suggested:

CREATE OR REPLACE FUNCTION rgio() RETURNS INTEGER as $$
DECLARE
lv RECORD;

BEGIN
FOR lv IN SELECT DISTINCT rg
FROM ldevrg
LOOP

EXECUTE 'CREATE TABLE rgio_' || $lv || ' AS
SELECT ldev
FROM ldevrg
WHERE rg=' || quote_literal($lv) || ';'

END LOOP;
RETURN 1;
END;
$$ LANGUAGE plpgsql;

And I get:

psql:rgio.sql:32: ERROR: syntax error at or near "$" at character 33
QUERY: SELECT 'CREATE TABLE rgio_' || $ $1 || ' AS
SELECT ldev
FROM ldevrg
WHERE rg=' || quote_literal($ $2 ) || ';' END LOOP
CONTEXT: SQL statement in PL/PgSQL function "rgio" near line 23
psql:rgio.sql:32: LINE 1: SELECT 'CREATE TABLE rgio_' || $ $1 || ' AS
psql:rgio.sql:32: ^

________________________________

From: pgsql-sql-owner(at)postgresql(dot)org on behalf of Erik Jones
Sent: Fri 7/21/2006 3:04 PM
To: Rodrigo De Leon
Cc: pgsql-sql(at)postgresql(dot)org
Subject: Re: [SQL] CREATE TABLE AS inside of a function

Rodrigo De Leon wrote:
> On 7/21/06, Kevin Nikiforuk <Kevin(dot)Nikiforuk(at)acrodex(dot)com> wrote:
>> So now that I've got my loops working, on to my next newbie
>> question. I've created my function and in it, I want to loop through
>> the results of a select and for each value of my loop counter, I want
>> to create a new table, but I can't figure out how to use a variable
>> in the name of the new table, see below.
>>
>> CREATE OR REPLACE FUNCTION rgio() RETURNS INTEGER as $$
>> DECLARE
>> lv RECORD;
>>
>> BEGIN
>> FOR lv IN SELECT DISTINCT rg FROM ldevrg LOOP
>> CREATE TABLE rgio_$lv AS
>> SELECT ldev
>> FROM ldevrg
>> WHERE rg='$lv';
>> END LOOP;
>> RETURN 1;
>> END;
>> $$ LANGUAGE plpgsql;
>>
>> Thanks,
>> Kevin
>
> See:
> http://www.postgresql.org/docs/8.1/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN
>
Also, I really recommend enough that you read chapters 32. Extending
SQL, 33. Triggers, and 36. Pl/pgSQL in their entirety. In fact, to keep
up with the linking to them for you:

http://www.postgresql.org/docs/8.1/interactive/extend.html
http://www.postgresql.org/docs/8.1/interactive/triggers.html
http://www.postgresql.org/docs/8.1/interactive/plpgsql.html

And, so that I don't feel like I'm becoming one of those rtfm jerks I
always complain about: what you need to do is place your CREATE TABLE
statement in an EXECUTE directive like so (inside the the FOR body):

EXECUTE 'CREATE TABLE rgio_' || $lv || ' AS
SELECT ldev
FROM ldevrg
WHERE rg=\'' || $lv || '\';' -- this line could have also been:
WHERE rg=' || quote_literal($lv) || ';'

EXECUTE takes a query in a string to execute and you need to use string
concatenation to build the string if you're using variables from the
function in the query. Pl/pgSQL doesn't have any variable substitution
inside of strings (like in double quoted string in PHP) which is why you
need to use the concatenation bit.

--
erik jones <erik(at)myemma(dot)com>
software development
emma(r)

---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo(at)postgresql(dot)org so that your
message can get through to the mailing list cleanly

Responses

Browse pgsql-sql by date

  From Date Subject
Next Message Bruno Wolff III 2006-07-24 21:22:36 Re: Referential integrity (foreign keys) across multiple tables
Previous Message Richard Huxton 2006-07-24 19:32:53 Re: Referential integrity (foreign keys) across multiple tables