0

Oracle オブジェクト タイプの使用に関して少し問題が発生しています。メンバー関数のコンパイルでエラーが発生しました。

タイプは次のとおりです。

 CREATE OR REPLACE TYPE t_Customer as OBJECT
 (custID NUMBER 
  ,fname varchar2(50)
  ,lname varchar2(50)
  ,MEMBER FUNCTION getHighest RETURN INTEGER
 );

 CREATE OR REPLACE TYPE t_Order AS OBJECT
 (OrderID NUMBER, custID REF t_Customer, quantity INTEGER);

 CREATE TABLE Order_Tbl of t_Order; 
 CREATE TABLE Customer_Tbl of t_Customer;

 CREATE OR REPLACE TYPE BODY t_Customer AS
  MEMBER FUNCTION getHighest RETURN INTEGER IS
   v_max integer;
   BEGIN
      SELECT Max(Order.quantity) INTO v_max FROM Order WHERE Order.CustID = self.custID;
       return v_max;
  end;

SELECT INTO が機能しません。無効な識別子があると言っています。顧客の最高数量注文を返すメンバ関数を書きたい場合、Order テーブルをクエリする必要がありますか?それともオブジェクト参照を使用できますか? また、無駄にビューを作成しようとしました。

これは私が単純化できる最も簡単な方法です。他の方法もいくつか書く必要がありますがSELECT INTO、今のところ作業する必要がある方法はありません。

エラーはSELF.custid INVALID IDENTIFIERあり、Component 'custid' must be declared. ありがとう

編集:SELECT INTOオブジェクト型とそのビューにアクセスするための pl/sql クエリは、エイリアスを設定する必要があります。エイリアスを追加した後、私の問題は解決しました。助けてくれてありがとう - 私は解決策といくつかの例を投稿しました.

4

4 に答える 4

2

まず、テーブルに「Order」という名前を付けないでください。これは Oracle の予約語です。

次に、メンバー関数は、型仕様で getHighestOrder という名前が付けられ、型本体で getHighest という名前が付けられます。

第三に、'end;' がありません。t_Customer 型本体の末尾。

第 4 に、SQL では custID に参加していますが、型には一貫性がありません。あなたがすべきことは、DEREF を使用してから、結果を自己と比較することです。

以下のコードは、これらの修正を示しています。

CREATE OR REPLACE TYPE t_Customer as OBJECT
(custID NUMBER 
,fname varchar2(50)
,lname varchar2(50)
,MEMBER FUNCTION getHighest RETURN INTEGER
);

CREATE OR REPLACE TYPE t_Order AS OBJECT
(OrderID NUMBER, cust REF t_Customer, quantity INTEGER);

CREATE TABLE OrderA of t_Order; 
CREATE TABLE Customer of t_Customer;

CREATE OR REPLACE TYPE BODY t_Customer AS

MEMBER FUNCTION getHighest RETURN INTEGER IS
v_max integer;
BEGIN
  SELECT Max(OrderA.quantity) 
  INTO   v_max 
  FROM   OrderA 
  WHERE  DEREF(OrderA.cust) = self;

   return v_max;

end;
end;

これは、必要なものに近いはずです。以下のコードを使用してテストします。

declare

    cust t_customer := t_customer (1, 'John','Smith');

begin

    insert into customer values (cust);

    insert into orderA (OrderID, cust, quantity)
    select 10, ref(c) , 7
    from customer c
    where custID = 1;

    insert into orderA (OrderID, cust, quantity)
    select 11, ref(c) , 15
    from customer c 
    where custID = 1;

    dbms_output.put_line(cust.getHighest);

end;
/
于 2013-05-04T07:53:51.713 に答える
1

ヘッダーと本文に異なる関数名があります:

getHighestOrder

getHighest
于 2013-05-04T07:24:29.813 に答える
1

ORDERは予約語なので、

CREATE TABLE Order of t_Order; 

... 取得:

CREATE TABLE Order of t_Order
             *
ERROR at line 1:
ORA-00903: invalid table name

二重引用符で囲むこともできますが、問題を回避して別の名前を使用することをお勧めします。テーブルを and に変更するorderscustomers(そしてメソッド名に一貫性を持たせると)、次のようになります。

LINE/COL ERROR
-------- -----------------------------------------------------------------
5/6      PL/SQL: SQL Statement ignored
5/79     PL/SQL: ORA-00932: inconsistent datatypes: expected REF got
         NUMBER

投稿しているエラーがどのように発生しているのかわかりません。そのため、さまざまなバージョンのコードとエラーを何らかの形で混同しているとしか思えません。ともかく...

オブジェクトを DEREF する必要がありt_customerます。これを少し明確にするためCustIDに、一貫性のないことを意味するために使用しないことをお勧めします。

CREATE OR REPLACE TYPE t_Order AS OBJECT
(OrderID NUMBER, custRef REF t_Customer, quantity INTEGER);
/

CREATE TABLE Orders of t_Order; 
CREATE TABLE Customers of t_Customer;

CREATE OR REPLACE TYPE BODY t_Customer AS
  MEMBER FUNCTION getHighestOrder RETURN INTEGER IS
    v_max INTEGER;
  BEGIN
    SELECT Max(Orders.quantity)
    INTO v_max
    FROM Orders
    WHERE DEREF(Orders.custRef) = self;
    RETURN v_max;
  END getHighestOrder;
END;
/

Type body created.

No errors.

これを行うこともできます:

WHERE DEREF(Orders.custRef).custID = self.custID;

...しかし、これは、同じ ID を持つ異なる顧客がいて、それらすべてをカウントに含めたい場合にのみ意味があります。

于 2013-05-04T07:56:40.893 に答える