質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.45%

  • SQL

    3092questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

  • Oracle

    703questions

    Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

  • Oracle Database 11g

    225questions

    Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。

Oracleでの重複チェック

受付中

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,219
退会済みユーザー

退会済みユーザー

Oracle 11gにて,あるデータの登録をSPを用いて行いたいと考えています.
その際に登録するデータに重複が無いかを調べ,重複があれば
その時点でSPを終了させる動作を行いたいのですが,その方法がわかりません.

下記のようなSQLを書いていますが,重複チェックの部分でエラーが出てしまいます.
実施したい内容としては次の通りです.

  1. SPが呼びだされた際に引数としてi_no1~i_no5に0~9999のいずれかの値が渡される
  2. i_no1~5を配列に格納し,'0'が入っている行は無視し,'1'以上の値が  
    入っている行を対象に重複しているかをチェックする
  3. 重複している場合にはユーザー定義例外(user_define_err)にてSPを終了させる
    重複が検出されなかった場合には処理を継続させる
CREATE OR REPLACE PROCEDURE **
(
    i_no1      IN VARCHAR2, 
    i_no2      IN VARCHAR2,
    i_no3      IN VARCHAR2,
    i_no4      IN VARCHAR2,
    i_no5      IN VARCHAR2,
)
IS
--引数格納用配列
    TYPE w_type_no_array IS TABLE OF VARCHAR2(5); 
    w_no_array w_type_no_array;
BEGIN
    w_no_array(0) := i_no1;
    w_no_array(1) := i_no2;
    w_no_array(2) := i_no3;
    w_no_array(3) := i_no4;
    w_no_array(4) := i_no5;

--重複チェックを行う
    FOR i IN 0..5 LOOP
        SELECT COUNT(DISTINCT w_no_array(i)),
               CASE
                   WHEN COUNT > 1 THEN
                       RAISE user_define_err
               END
        FROM (
            SELECT * 
            FROM w_no_array
            WHERE w_no_array <> '0'
        )
    END LOOP;

 エラー内容

Error(237,9): PL/SQL: SQL Statement ignored
Error(240,30): PL/SQL: ORA-00905: キーワードがありません。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • takyafumin

    2016/05/13 17:08

    > 下記のようなSQLを書いていますが,重複チェックの部分でエラーが出てしまいます.
    どのようなエラーが発生しているのか、エラーメッセージ等を具体的に記載できますか?

    キャンセル

回答 4

0

TYPE w_type_no_array IS TABLE OF VARCHAR2(4);

「TYPE w_type_no_array IS TABLE OF VARCHAR2(5);」ではなくて?

FOR i IN 0..5 LOOP

「w_no_array(4) := i_no5;」が最後なのでi=5の時におかしくなりません?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/13 17:21

    ご指摘ありがとうございます.
    実際のコードは引数がもっと有り,貼り付けているコードはVARCHAR(5)の間違いです.

    キャンセル

0

手元にoracle環境がすぐには作れないので、気づいた点をいくつか。

  • ストアドプロシージャ内では、select文はそのまま使えません。必要であればselect intoを使いましょう。
  • PL/SQL表に対してselect文って利用できるんでしたっけ?(私が無知なだけかもしれません)
  • そもそもselect文ではなく、配列を使った重複の検出ではだめでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

何かいろいろとごっちゃになってる気がします。

TYPE w_type_no_array IS TABLE OF VARCHAR2(5); 
w_no_array w_type_no_array;

定義したこれはネステッド・テーブルな訳ですが、要するに一次元配列です。
このまま「SELECT」しても無理かと。

RAISE user_define_err

例外の呼び出しはPL/SQL内で行うもので、SQL文の途中ではできません。

まずは、この辺りを参考にしてみてはいかがでしょうか?
PL/SQLの配列=コレクション型
コレクション変数について
PL/SQL入門
PL/SQLを使ってみよう

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

自分だったら、ということで。
まず、ストアドのFUNCTION作ります。

CREATE OR REPLACE FUNCTION HOGE (
  P1 IN VARCHAR2, 
  P2 IN VARCHAR2,
  P3 IN VARCHAR2,
  P4 IN VARCHAR2,
  P5 IN VARCHAR2) RETURN NUMBER IS
BEGIN
  -- 実際の処理
  -- RETURN 0 -> OK
  -- RETURN 1 -> NG
END;
/


これを使って

SELECT HOGE(P1,P2,P3,P4,P5) INTO RES FROM DUAL;
  IF RES = 0 THEN
    -- 登録処理実行
  ELSE
    -- エラー処理
  END IF;


こんな感じで処理を作る感じかなあ。
他の方も書かれているように、本当にこんな書き方で
処理を実装した実績があるのか心配ですな~
あと、なにがしかのプログラムからよばれるものなら、
そのプログラムでやっちゃった方が格段に楽だと思う。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.45%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • SQL

    3092questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

  • Oracle

    703questions

    Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

  • Oracle Database 11g

    225questions

    Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。