2

forpostgresqlでループを使用して複数のテーブルを作成するにはどうすればよいですか?

例: 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;
4

1 に答える 1

2

あなたは2つの間違いを犯しています:

  • FORBEGIN ... ENDなどは、通常の SQL ではなく、PL/PgSQL の一部です。これらはプレーン SQL では使用できません。DOブロックまたはCREATE OR REPLACE FUNCTION.

  • あなたは評価の順序について真剣に混乱しています。PL/PgSQLFORループをに書き込んでから、bash変数展開でi参照します。これは、変数が存在する前に、PL/PgSQL 関数テキストの生成中に展開されます。ii

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;

ご覧のとおり、未定義の が bash によってゼロとして扱われたため、 に${prefix[i]}評価されました。したがって、配列内の他のエントリは使用されません。c_iprefix

必要がある:

  • PL/PgSQL コードを実行するには、DOブロックまたは関数呼び出しを使用します。CREATE OR REPLACE FUNCTION

  • EXECUTE format(...)動的 SQL の実行に使用

または、for ループでプレーンな SQLCREATE TABLEステートメントを生成することもできます。これ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 生成システムを作成しようとしていますか? もしそうなら、その車輪を再発明しないでください。それらはすでにたくさんあります。

また、このようなことをしている場合は、スキーマ (マルチテナントを行おうとしている場合)、テーブルのパーティション分割などについて読む必要がある可能性がかなり高くなります。

于 2012-12-12T23:40:17.487 に答える