You're making two mistakes:
FOR
, BEGIN ... END
, etc are part of PL/PgSQL, not regular SQL. You can't use these in plain SQL, you need a DO
block or CREATE OR REPLACE FUNCTION
.
You're seriously muddled about the order of evaluation. You've written a PL/PgSQL FOR
loop over i
, then you reference i
in a bash variable expansion. That'll be expanded during the generation of the PL/PgSQL function text, way before the variable i
ever exists.
You can see the latter problem clearly if you just replace psql -d postgres
with cat
so it prints the generated SQL you're trying to run:
BEGIN
FOR i IN 0 1 2 3 LOOP
create table c_employee (e_name varchar(32) primary key, type smallint not null, description varchar(128), ip_address cidr);
END LOOP;
END;
As you can see, ${prefix[i]}
evaluated to c_
because i
, being undefined, was treated as zero by bash. So the other entries in your prefix
array will never be used.
You need to:
Alternately, you can generate the plain SQL CREATE TABLE
statements in a bash
for loop, doing away entirely with the need for PL/PgSQL. I would use this approach, as it's much simpler.
for p in ${prefix[*]}; do
echo "create table ${p}employee (e_name $SQLVARCHAR(32) primary key, type $SQLTINYINT not null, description $SQLVARCHAR(128), ip_address $SQLCIDR);"
done | psql
By the way, there is no such thing as postgre
. I think you meant "Postgres" or "PostgreSQL".
You probably want bytea
not varbinary
. What's with the SQL types as variables, anyway? Are you trying to write a DDL generation system? If so, don't reinvent that wheel, there are lots of them already out there.
Also, if you're doing things like this, there's a fairly strong chance you need to read up on schemas (if you're trying to do multi-tenant), table partitioning, etc.