Oracle のオブジェクト リレーション機能を使用して階層データを作成しようとしています。
「投稿」を次のように定義しました。
create type Post as object (title varchar(20), body varchar(2000),
author varchar(200), parent REF Post,
MEMBER FUNCTION numReplies RETURN NUMBER,
PRAGMA RESTRICT_REFERENCES(numReplies, WNDS)
);
/
create table Posts of Post;
ここで、関数 numReplies を作成して、"self" 投稿を親として持つ投稿の数を調べたいと思います。
create or replace type body Post AS
MEMBER FUNCTION numReplies RETURN number IS
i INT;
BEGIN
SELECT COUNT(*) INTO i FROM Posts p WHERE p.parent = SELF;
RETURN i;
END;
END;
/
しかし、コンパイルエラーが発生します:
Warning: Type Body created with compilation errors.
SQL> show errors;
Errors for TYPE BODY POST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
6/3 PL/SQL: SQL Statement ignored
6/56 PL/SQL: ORA-00932: inconsistent datatypes: expected TSTER123.POST
got REF TSTER123.POST
where 句で REF(SELF) を実行しようとしましたが、同じエラー メッセージが表示されます。私も REF(p.parent) を試しましたが(とにかく意味がありません)、エラーが発生しました:
LINE/COL ERROR
-------- -----------------------------------------------------------------
6/3 PL/SQL: SQL Statement ignored
6/49 PL/SQL: ORA-00904: "P"."PARENT": invalid identifier
OR 機能 (クラス プロジェクト) を使用したいので、投稿する ID 列を追加してそれを使用することに頼りたくありません。どうすればこれを達成できますか?
注: 次のクエリは機能しますが、SELF を使用する関数で機能させることはできません。
SELECT title, (select count(*) from Posts p2 where p2.parent = REF(p))
FROM Posts p;
編集:
OK、コンパイルできましたが、期待するデータが得られません。
ここに私が使用したいくつかのダミーデータがあります:
insert into Posts values ('foo', 'bar', 'tyler', null);
insert into Posts values ('hello world', 'bar', 'jatin', (select REF(p) FROM Posts p where p.title = 'foo'));
insert into Posts values ('bark', 'asd', 'tom', (select REF(p) FROM Posts p where p.title = 'hello world'));
insert into Posts values ('friendly', 'hgfags', 'tyler', (select REF(p) FROM Posts p where p.title = 'foo'));
そして、ここにコンパイルされたものがあります:
create or replace type body Post AS
MEMBER FUNCTION numReplies RETURN number IS
i INT;
BEGIN
SELECT COUNT(*) INTO i FROM Posts p WHERE DEREF(p.parent) = SELF;
RETURN i;
END;
END;
/
しかし、正しい結果が得られません:
SQL> SELECT title, (select count(*) from Posts p2 where p2.parent = REF(p)) From Posts p;
TITLE (SELECTCOUNT(*)FROMPOSTSP2WHEREP2.PARENT=REF(P))
-------------------- ------------------------------------------------
foo 2
hello world 1
bark 0
friendly 0
SQL> select title, p.numReplies() from Posts p;
TITLE P.NUMREPLIES()
-------------------- --------------
foo 0
hello world 1
bark 0
friendly 0
私がこれを使用する場合:
create or replace type body Post AS
MEMBER FUNCTION numReplies RETURN number IS
i INT;
BEGIN
SELECT COUNT(*) INTO i FROM Posts p WHERE DEREF(p.parent).title = SELF.title;
RETURN i;
END;
END;
/
期待どおりの結果が得られますが、各投稿に一意のタイトルを付ける必要があります。