0

PL/SQL を使用しています。テーブルにレコードが存在するかどうかを確認したいのですが、存在する場合または存在しない場合を使用してみましたが、例外が発生します。

Select name from nameTable where name = nameFromArgument;

手順が開始され、データベースにない間違った名前を入力すると、エラーが発生し、処理することさえできません

私はこのようなことを試しました:

クエリが空を返すかどうかの PL/SQL チェック

編集:

申し訳ありませんが、前に置いた選択は単なる例であり、コード全体 [変数の名前については申し訳ありません...] は次のとおりです。

CREATE OR REPLACE
PROCEDURE SELLSTOCKS
( IloscAkcji IN NUMBER
, NazwaAkcji IN VARCHAR2
, IdRachunkuMaklerskiego IN NUMBER
)  AS
Bledna_ilosc EXCEPTION;
Bledna_nazwa EXCEPTION;
amount NUMBER;
stocksCash number;
idRachunku number;
stocksOnDealerSide number;
temp number;
tempus akcje_uzytkownika.nazwa % type;
BEGIN

--Select nazwa into tempus from akcje_uzytkownika where nazwa = nazwaakcji;
--dbms_output.put_line(tempus);

  dbms_output.put_line('pre');
 select nazwa into tempus from akcje_uzytkownika where nazwa = nazwaakcji;
 dbms_output.put_line('pre2');
 if tempus!=null then
    if ( iloscakcji> amount) THEN
  raise Bledna_ilosc;
  else
  select ilosc, cena_sztuki into amount, stockscash from akcje_uzytkownika where nazwa= NazwaAkcji and id_rachunku_maklerskiego= IdRachunkuMaklerskiego;
 dbms_output.put_line(amount);
 dbms_output.put_line(stockscash);
  amount :=amount - iloscakcji;
  dbms_output.put_line(amount);
  update akcje_uzytkownika set ilosc= amount  where nazwa=NazwaAkcji and  id_rachunku_maklerskiego= idrachunkumaklerskiego;
  stockscash:= iloscAkcji * stocksCash;
  dbms_output.put_line(stockscash);
  select id_rachunku into idrachunku from rachunek_maklerski where id_rachunku_maklerskiego= idrachunkumaklerskiego; 
  temp:=SALDOUPDATE(stockscash, idrachunku);
  select ilosc into stocksOnDealerSide from akcje where nazwa = nazwaAkcji;
  stocksOnDealerSide := stocksondealerside+ iloscakcji;
  dbms_output.put_line(stocksOnDealerSide);
  update akcje set ilosc = stocksondealerside where nazwa = nazwaAkcji;
  end if;
  else
  dbms_output.put_line('post');
  end if;
EXCEPTION

  when Bledna_ilosc then
  dbms_output.put_line('Bledna ilosc');
  when Bledna_nazwa then
  dbms_output.put_line('Bledna nazwa');

END SELLSTOCKS;

私はオラクルSQL開発者1.5.5を使用しています

BEGIN

--Select nazwa into tempus from akcje_uzytkownika where nazwa = nazwaakcji;
--dbms_output.put_line(tempus);

  dbms_output.put_line('pre');
  select nazwa into tempus from akcje_uzytkownika where nazwa = nazwaakcji;
  dbms_output.put_line('pre2');
  exception when no_data_found then
  raise no_data_found;

-- is this the right place?

  select ilosc, cena_sztuki into amount, stockscash from akcje_uzytkownika where nazwa= NazwaAkcji and id_rachunku_maklerskiego= IdRachunkuMaklerskiego;
  dbms_output.put_line(amount);
  dbms_output.put_line(stockscash);
  amount :=amount - iloscakcji;
  dbms_output.put_line(amount);
  if ( iloscakcji> amount) THEN
  raise Bledna_ilosc;
  else
  update akcje_uzytkownika set ilosc= amount  where nazwa=NazwaAkcji and  id_rachunku_maklerskiego= idrachunkumaklerskiego;
  stockscash:= iloscAkcji * stocksCash;
  dbms_output.put_line(stockscash);
  select id_rachunku into idrachunku from rachunek_maklerski where id_rachunku_maklerskiego= idrachunkumaklerskiego; 
  temp:=SALDOUPDATE(stockscash, idrachunku);

.........

4

1 に答える 1

3

主に間違っている点が 4 つあります (私にはわかります)。

まず、決してtempus!=null機能しません。null は情報の不在であるため、null をチェックするときに (in) 等値演算子を使用することはできません。存在しない != 存在しない。正しい構文は、またはあなたの場合は使用することです。is nulltempus is not null

次に、if ( iloscakcji> amount) THENvalue を初期化しないため、true と評価されることはありませんamount。存在しないため、数値を超えることnullはできません。変数を初期化する必要がありますamount。たぶん、次のselectステートメントがこれより上にあることを意味していましたか?

第三に、すべてのselect ... into ...ステートメントは、ユーザー定義のテーブル型ではなく、単一の変数になっています。これは、クエリによって 0 行が返された場合、no_data_found例外が発生することを意味します。複数の行が返された場合、too_many_rows例外が発生します。

多くても 1 行だけを期待している場合は、あまり心配する必要はありませんtoo_many_rows。これは、可能であれば、テーブルの一意の制約によって実際に実施する必要があります。たとえば、nazwaで一意である必要がありますakcje_uzytkownika

no_data_foundはわずかに異なり、あなたが意図したものだと思いますtempus != null。が値に初期化されていると仮定すると、amountこれは次のように書き直すことができます。

begin

    -- do some stuff    
    begin

       select nazwa into tempus from akcje_uzytkownika where nazwa = nazwaakcji;

    -- If there-s no data catch the exception.
    exception when no_data_found then
       if ( iloscakcji > amount) then
          raise Bledna_ilosc;
       end if;

    end;        
    -- do some more stuff

end;

最後に、これは間違いではありませんが、あなたのコードはかなり読みにくいものです。何が起こっているのかを確認できるように、より多くの空白を使用することを検討します。

PS By Oracle バージョンは 11gr2 や 10g などを意味していましたが、この場合は違いはありません。

于 2012-05-20T10:31:33.183 に答える