すべてのテーブルをループして、各テーブルの行をカウントします。次のクエリでエラーが発生します。
_DO $$
DECLARE
tables CURSOR FOR
SELECT tablename FROM pg_tables
WHERE tablename NOT LIKE 'pg_%'
ORDER BY tablename;
tablename varchar(100);
nbRow int;
BEGIN
FOR tablename IN tables LOOP
EXECUTE 'SELECT count(*) FROM ' || tablename INTO nbRow;
-- Do something with nbRow
END LOOP;
END$$;
_
エラー:
_ERROR: syntax error at or near ")" LINE 1: SELECT count(*) FROM (sql_features) ^ QUERY: SELECT count(*) FROM (sql_features) CONTEXT: PL/pgSQL function inline_code_block line 8 at EXECUTE statement
_
_sql_features
_は、私のDB内のテーブルの名前です。私はすでにquote_ident()
を使用しようとしましたが、役に立ちませんでした。
カーソルはスカラー値ではなくレコードを返すため、「tablename」は文字列変数ではありません。
連結により、レコードはこの(sql_features)
のような文字列に変換されます。あなたが選択した場合スキーマ名とテーブル名、レコードのテキスト表現は(public,sql_features)
になります。
したがって、SQLステートメントを作成するには、レコード内の列にアクセスする必要があります。
DO $$
DECLARE
tables CURSOR FOR
SELECT tablename
FROM pg_tables
WHERE tablename NOT LIKE 'pg_%'
ORDER BY tablename;
nbRow int;
BEGIN
FOR table_record IN tables LOOP
EXECUTE 'SELECT count(*) FROM ' || table_record.tablename INTO nbRow;
-- Do something with nbRow
END LOOP;
END$$;
WHERE schemaname = 'public'
の代わりにnot like 'pg_%'
を使用して、Postgresシステムテーブルを除外することができます。
Plpgsqlでループするために明示カーソルを実際に使用する必要があった最後の時間を思い出せません。FOR
loop の暗黙カーソルを使用します。
DO
$$
DECLARE
rec record;
nbrow bigint;
BEGIN
FOR rec IN
SELECT *
FROM pg_tables
WHERE tablename NOT LIKE 'pg\_%'
ORDER BY tablename
LOOP
EXECUTE 'SELECT count(*) FROM '
|| quote_ident(rec.schemaname) || '.'
|| quote_ident(rec.tablename)
INTO nbrow;
-- Do something with nbrow
END LOOP;
END
$$;
すべてのスキーマ(search_path
にないスキーマを含む)でこの機能を使用するには、スキーマ名を含める必要があります。
また、実際にneedを使用して quote_ident()
またはformat()
とともに%I
を使用して、SQLインジェクションから保護します。テーブル名は、二重引用符で囲んだほとんど何でもできます。
細部:アンダースコア(_
)をLIKE
パターンでエスケープして、literalアンダースコアにします:tablename NOT LIKE 'pg\_%'
DO
$$
DECLARE
tbl regclass;
nbrow bigint;
BEGIN
FOR tbl IN
SELECT c.oid
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND n.nspname NOT LIKE 'pg\_%' -- system schema(s)
AND n.nspname <> 'information_schema' -- information schema
ORDER BY n.nspname, c.relname
LOOP
EXECUTE 'SELECT count(*) FROM ' || tbl INTO nbrow;
-- raise notice '%: % rows', tbl, nbrow;
END LOOP;
END
$$;
クエリ pg_catalog.pg_class
tablename
の代わりに、テーブルのOIDを提供します。
オブジェクト識別子タイプregclass
は、簡単にするために便利です。特に、必要に応じてテーブル名を二重引用符で囲み、スキーマで修飾します( SQLインジェクション も防止します) )。
このクエリは、一時テーブルも除外します(一時スキーマは、pg_temp%
で内部的に命名されます)。
特定のスキーマのテーブルのみが必要な場合:
AND n.nspname = 'public' -- schema name here, case-sensitive