如何在postgresql中使用for循环创建多个表

时间:2012-12-12 14:18:13

标签: shell psql

如何在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;

1 个答案:

答案 0 :(得分:1)

你犯了两个错误:

  • FORBEGIN ... 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生成系统?如果是这样,不要重新发明那个轮子,那里已经有很多轮子了。

另外,如果您正在做这样的事情,那么您需要阅读模式(如果您尝试进行多租户),表分区等等。