2012-12-12 3 views
2

Comment créer plusieurs tables en utilisant une boucle for dans postgresql?Comment créer plusieurs tables en utilisant pour boucle dans postgresql

Par exemple: Je dois créer c_emloyee, r_employee, i_employee, etc. Je suis une erreur de syntaxe proche pour

! /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

S'il vous plaît toujours inclure la version de PostgreSQL et tous les messages d'erreur. –

Répondre

1

Tu fais deux erreurs:

  • FOR, BEGIN ... END, etc font partie de PL/PgSQL, pas de SQL normal. Vous ne pouvez pas les utiliser en langage SQL, vous avez besoin d'un bloc DO ou CREATE OR REPLACE FUNCTION.

  • Vous êtes sérieusement confus au sujet de l'ordre d'évaluation. Vous avez écrit une boucle PL/PgSQL FOR sur i, puis vous référencez i dans une extension de variable bash. Cela sera étendu lors de la génération du texte de la fonction PL/PgSQL, bien avant que la variable i n'existe.

Vous pouvez voir ce dernier problème clairement si vous remplacez simplement psql -d postgres avec cat il imprime le SQL généré que vous essayez d'exécuter:

 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; 

Comme vous pouvez le voir, ${prefix[i]} évalué à c_ car i, étant indéfini, a été traité comme zéro par bash. Les autres entrées de votre tableau prefix ne seront donc jamais utilisées.

Vous devez:

  • Utiliser un bloc DO ou CREATE OR REPLACE FUNCTION et un appel de fonction pour exécuter votre code PL/PgSQL; et

  • Utilisez EXECUTE format(...) pour exécuter SQL

dynamique Alternativement, vous pouvez générer les instructions SQL CREATE TABLE ordinaire dans une bash boucle, supprimant entièrement la nécessité de PL/pgSQL. J'utiliserais cette approche, car c'est beaucoup plus simple.

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 

Par ailleurs, il n'y a pas une telle chose comme postgre. Je pense que vous vouliez dire "Postgres" ou "PostgreSQL".

Vous voulez probablement bytea pas varbinary. Qu'en est-il des types SQL en tant que variables? Êtes-vous en train d'écrire un système de génération DDL? Si oui, ne réinventez pas cette roue, il y en a déjà beaucoup là-bas.

De plus, si vous faites des choses comme ça, il y a une chance assez forte, vous devez lire sur les schémas (si vous essayez de le faire à plusieurs locataires), le partitionnement de table, etc.

Questions connexes