如何在postgresql中使用for
循环创建多个表?
例如:我需要创建c_emloyee,r_employee,i_employee等。 我在FOR
附近遇到语法错误! /bin/sh
#Invoke postgre
SQLVARCHAR="varchar"
SQLINTEGER="integer"
SQLBIGINT="bigint"
SQLSMALLINT="smallint"
SQLTINYINT="smallint"
SQLCIDR="cidr"
SQLBINARY="varbinary"
SQLTIME="timestamp"
SQLMACADDRESS="macaddr"
prefix[0]=c_
prefix[1]=r_
prefix[2]=s_
prefix[3]=i_
echo ${prefix[0]}
echo ${prefix[1]}
echo ${prefix[2]}
echo ${prefix[3]}
psql -d postgres <<EOF
BEGIN
FOR i IN 0 1 2 3 LOOP
create table ${prefix[i]}employee (e_name $SQLVARCHAR(32) primary key, type $SQLTINYINT not null, description $SQLVARCHAR(128), ip_address $SQLCIDR);
END LOOP;
END;
答案 0 :(得分:1)
你犯了两个错误:
FOR
,BEGIN ... END
等是PL / PgSQL的一部分,而不是常规SQL。您不能在纯SQL中使用它们,需要DO
块或CREATE OR REPLACE FUNCTION
。
你对评估的顺序感到非常困惑。您已经在FOR
上编写了PL / PgSQL i
循环,然后在 bash 变量扩展中引用了i
。这将在生成PL / PgSQL函数文本期间进行扩展,在变量i
之前存在。
如果您只是将psql -d postgres
替换为cat
,则可以清楚地看到后一个问题,以便打印您尝试运行的生成的SQL:
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;
如您所见,${prefix[i]}
已评估为c_
,因为i
未定义,被bash视为零。因此,prefix
数组中的其他条目将永远不会被使用。
你需要:
使用DO
阻止或CREATE OR REPLACE FUNCTION
和函数调用来执行PL / PgSQL代码;以及
使用EXECUTE format(...)
运行动态SQL
或者,您可以在CREATE TABLE
for循环中生成纯SQL bash
语句,完全消除了对PL / PgSQL的需求。我会使用这种方法,因为它更简单。
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
顺便说一句,没有postgre
这样的东西。我认为你的意思是“Postgres”或“PostgreSQL”。
您可能希望bytea
不是varbinary
。无论如何,SQL类型作为变量是什么?您是否正在尝试编写DDL生成系统?如果是这样,不要重新发明那个轮子,那里已经有很多轮子了。
另外,如果您正在做这样的事情,那么您需要阅读模式(如果您尝试进行多租户),表分区等等。