まったく同じ構造のテーブルがいくつかあり、すべてのテーブルの値を更新する必要があります。
そのために、次のスクリプトを作成してみました。
DO
$do$
DECLARE
i pg_tables%rowtype;
BEGIN
FOR i IN SELECT * FROM pg_catalog.pg_tables where schemaname like 'public' and tablename like '%_knex_migrations'
LOOP
UPDATE i.tablename SET name = replace(name, '.js', '.ts');
END LOOP;
END
$do$;
i.tablename
は正しい値(チェックするためにtmpテーブルに挿入)を持っていますが、更新は失敗します。
name: error
length: 223
severity: ERROR
code: 42P01
internalPosition: 8
internalQuery: UPDATE i."tablename" SET name = replace(name, '.js', '.ts')
where: PL/pgSQL function inline_code_block line 7 at SQL statement
file: parse_relation.c
line: 965
routine: parserOpenTable
ただプラグインi.tablename
UPDATE
ステートメントが機能しません。
それを機能させる方法はありますか?または、すべてのテーブルを一度に更新する簡単な方法は?
あなたは実際に近いです。最初にいくつかのテストデータを作成します。
_CREATE TABLE foo_knex_migrations ( name )
AS VALUES ('test.js'),('test2.js'),('bicycles');
CREATE TABLE bar_knex_migrations AS TABLE foo_knex_migrations;
CREATE TABLE baz_knex_migrations AS TABLE foo_knex_migrations;
_
次に、_EXECUTE...
_と共に_%I
_ FORMAT()
を使用します。
_DO
$do$
DECLARE
i pg_tables%rowtype;
BEGIN
FOR i IN SELECT * FROM pg_catalog.pg_tables where schemaname like 'public' and tablename like '%_knex_migrations'
LOOP
EXECUTE FORMAT(
$$
UPDATE %I
SET name = replace(name, '.js', '.ts');
$$,
i.tablename
);
END LOOP;
END
$do$;
TABLE baz_knex_migrations ;
name
----------
test.ts
test2.ts
bicycles
(3 rows)
test=# TABLE foo_knex_migrations ;
name
----------
test.ts
test2.ts
bicycles
(3 rows)
_
補足として、
information_schema
_を使用する必要があり、速度は重要ではありません。UPDATE
句を追加して、WHERE
を実行する必要があるかどうかを確認する必要があります。それ以外の場合は、テーブルを無料で書き換えます。knex_migrations
_に複数のテーブルがある場合は、すべてのテーブルの命名規則に基づいてカタログを検索するのではなく、_CREATE SCHEMA knex_migrations
_にテーブルを格納することを検討してください。基本的に機能するソリューションをコメントとして投稿しました。
ただし、弱点は残ります。UPDATE
のテーブル名をスキーマで修飾せず、スキーマが現在の検索パスの最初にない場合、間違ったテーブルが更新される可能性があります。代わりに検討してください:
DO
$do$
DECLARE
sch text := 'public'; -- your schema here
tbl text;
BEGIN
FOR tbl IN
SELECT tablename FROM pg_catalog.pg_tables
WHERE schemaname = sch
AND tablename LIKE '%_knex_migrations'
LOOP
EXECUTE format($$UPDATE %I.%I SET name = replace(name, '.js', '.ts')$$, sch, tbl);
END LOOP;
END
$do$;
関連: