古いテーブルから新しいテーブル構造の更新を作成しようとしていますが、関数は使用していません。私はそれにスクリプトを作成しようとしています。古いテーブルは次のとおりです。
-- old table (OldTable)
name| col_a | col_b | col_c |
--------|---------|---------|--------|
ABC | 0 |NULL | 1 |
DEF | 1 | 1 | 1 |
GHI | NULL | 1 | 0 |
And, new tables:
-- Table Users
ID | NAME
----| ---------
1 | ABC
2 | DEF
3 | GHI
-- Table Rules
ID | RULE_NAME
--- | ------------------
1 | col_a
2 | col_b
3 | col_c
4 | col_d
-- Table UserRules
ID_USER | ID_RULE
------------- |-------------
したがって、ユーザー名がテーブルユーザーのユーザー名と等しく、テーブルミックスの列の値が1と等しいTableMixでの選択からの結果をテーブルUserRulesに入力する必要があります(OldTableからOldTable.nameを選択します) = Users.name)。まあ、私はこれを試しています:
DO $$
DECLARE rules CURSOR FOR SELECT column_name FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'OldTable'
AND data_type = 'numeric' AND column_name NOT IN ('foo','bar');
-- "foo" and "bar" are another numerc cols, but not define rules.
DECLARE users CURSOR FOR SELECT name FROM public.Users;
BEGIN
FOR ruleName IN rules LOOP
FOR userName IN users LOOP
EXECUTE format('SELECT COALESCE(%I,col,$1) FROM public.OldTable
WHERE name = ''$2''', ruleName, username);
-- insert on... populate the table Rules after get the id of the rule in table Rules if the result of select in OldTable equals 1 (or true if has a "where ... = 1")
END LOOP;
END LOOP;
END $$
この後、私は進歩していません...誰かが私を助けますか?よろしく!
[〜#〜]更新[〜#〜]
このようにして、本当の価値を得ることができます:
DO $$
DECLARE
rules CURSOR FOR SELECT column_name FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'oldtable' AND data_type = 'numeric'
AND column_name NOT IN ('foo','bar');
names CURSOR FOR SELECT username FROM public.users;
res integer;
BEGIN
FOR rulename IN rules LOOP
EXECUTE format('SELECT %s FROM oldtable WHERE nome = %L', rulename, 'USER NAME') INTO res;
-- IF res > 0 THEN
RAISE NOTICE '%', res;
--END IF;
END LOOP;
END $$
結果は実際の整数値です。
しかし、ユーザー名にループを使用すると、機能しません。
DO $$
DECLARE
rules CURSOR FOR SELECT column_name FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'oldtable' AND data_type = 'numeric'
AND column_name NOT IN ('foo','bar');
names CURSOR FOR SELECT username FROM public.users;
res integer;
BEGIN
FOR name IN names LOOP
FOR rulename IN rules LOOP
EXECUTE format('SELECT %s FROM oldtable WHERE nome = %L', rulename, name) INTO res;
-- IF res > 0 THEN
RAISE NOTICE '%', res;
--END IF;
END LOOP;
END LOOP;
END $$
したがって、resulは常にです。どこがいけないの?
USING
句を探していると思います。
EXECUTE format('SELECT COALESCE(%I,col,$1) FROM public.TableMix
WHERE name = $2', ruleName)
USING (username, whateverTheSecondParameterIs);
あなたが使う $1
、$2
など、配置パラメータの場合、USING
によって渡されます。あなたが使う %I
は、format
によって拡張された識別子。
更新:列名を合体させたい場合ruleName
がnullの場合、おそらく次のようなものが必要です。
EXECUTE format('SELECT %I FROM public.TableMix
WHERE name = $1', coalesce(ruleName, 'col'))
USING (username);
??
評価の順序について考える必要があります。生成されたSQLの一部、およびそのSQLを作成するために何が評価されますか?