2017-01-23 16 views
0

ネストされているユーザー定義型のフィールドにはどうすればアクセスできますか?私はそれが失敗したドット表記を使用して、それを試したとき :たとえばネストされたユーザー定義型のフィールドにアクセスするにはどうすればよいですか?

ERROR: "v_zoo.bear_object.animal_name" is not a known variable 
LINE 8: v_zoo.bear_object.animal_name='Mishka'; 

を、どのように私はこのコードを「をコンパイルする」のか?それを実行しようとすると

sqls $ cat animal.sql 
DROP TYPE IF EXISTS zoo_t CASCADE; 
CREATE TYPE zoo_t AS (
    wolf_object   animal_t, 
    bear_object   animal_t 

); 
DROP TYPE IF EXISTS animal_t CASCADE; 
CREATE TYPE animal_t AS (
    animal_id   integer, 
    animal_color  varchar, 
    animal_name   varchar 
); 
CREATE OR REPLACE FUNCTION animal_func() 
RETURNS void AS $$ 
DECLARE 
    v_animal  animal_t; 
    v_zoo   zoo_t; 
BEGIN 
    v_animal.animal_name:='Chupacabras'; 
    v_zoo.bear_object.animal_name='Mishka'; 
END; 
$$ LANGUAGE PLPGSQL; 

sqls $ psql dev < animal.sql 
DROP TYPE 
CREATE TYPE 
NOTICE: drop cascades to 2 other objects 
DETAIL: drop cascades to composite type zoo_t column wolf_object 
drop cascades to composite type zoo_t column bear_object 
DROP TYPE 
CREATE TYPE 
ERROR: "v_zoo.bear_object.animal_name" is not a known variable 
LINE 8: v_zoo.bear_object.animal_name='Mishka'; 
     ^
sqls $ 
+0

私はPostgresチームから、サポートされていない機能だと回答しました。 (入れ子構造を使用) – Nulik

答えて

3

はにPL/pgSQLの欠乏のように見えます。通常のSQLでは、

test=> WITH x(zoo) AS (VALUES(ROW(ROW(1, 'red', 'panda')::animal_t, ROW(2, 'black', 'bear')::animal_t)::zoo_t)) 
SELECT (zoo).bear_object.animal_color FROM x; 
animal_color 
-------------- 
black 
(1 row) 

とそうしかし、PL/pgSQLにできるのと同じ形式を受け入れていない:

test=> CREATE OR REPLACE FUNCTION animal_func() 
RETURNS void AS $$ 
DECLARE 
    v_animal  animal_t; 
    v_zoo   zoo_t; 
BEGIN 
    v_animal.animal_name:='Chupacabras'; 
    (v_zoo).bear_object.animal_name='Mishka'; 
END; 
$$ LANGUAGE PLPGSQL; 
ERROR: syntax error at or near "(" 
LINE 8:  (v_zoo).bear_object.animal_name='Mishka'; 

ので、私はそれがバグ/監視/制限だと思います。 pgsql-bugsでそれを上げることを検討してください。

一時変数にアンパックして変更して保存することでアクセスできますが、非効率的です。

CREATE OR REPLACE FUNCTION animal_func() 
RETURNS void AS $$ 
DECLARE 
    v_animal  animal_t; 
    v_zoo   zoo_t; 
BEGIN 
    v_animal := v_zoo.bear_object; 
    v_animal.animal_name := 'Mishka'; 
    v_zoo.bear_object := v_animal; 
END; 
$$ LANGUAGE PLPGSQL; 

私はplpgsqlを使ってこの種の擬似オブジェクトを行うことを推奨しません。 SQLはオブジェクト指向ではなく、入れ子になったユーザー定義の複合型ではうまく動作しません。物事を修正することは非常に効率が悪いです.SQLのほとんどのものは不変なので、値を変更すると新しいコピーが作成されます。反復的な変更と手続き型コードはうまく機能しません。

あなたはセットとリレーションを使って作業する必要があります。 1回のパスで新しい値を作成し、反復的に変更したり、フィールドを1つずつ設定したりしないでください。あるオブジェクトに別のオブジェクトが含まれるのではなく、関係を使用します。

また、にしてください。ハンガリー語表記を削除してください。ああ。

+0

ありがとう!私はそれを一時変数に解凍すると今はうまくいくと思います。 – Nulik

関連する問題