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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PL/SQL

PL/SQL (Procedural Language/Structured Query Language) はOracle CorporationによるSQL(非手続き型言語)を手続き型言語に拡張させるために開発されたプログラミング言語です。

SQL

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

Q&A

解決済

2回答

1368閲覧

PL/SQL の条件分岐について

UDKKI

総合スコア7

PL/SQL

PL/SQL (Procedural Language/Structured Query Language) はOracle CorporationによるSQL(非手続き型言語)を手続き型言語に拡張させるために開発されたプログラミング言語です。

SQL

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

0グッド

0クリップ

投稿2016/09/12 12:23

編集2016/09/12 15:29

###前提・実現したいこと
PL/SQL の条件分岐についての質問です。
やりたいのは DB1からDB2のデータ取得です。
DB1.学籍番号番号があって、学籍番号の末尾2桁が00の場合、
00を消して、DB2にセットする(00が無くなるまで、最後の3桁そのまま)
例10101000 の場合 末尾00の消し、101010をセット
1010000 → 101をセット
1000000 → 100をセット

###該当のソースコード
Select case when substr(ID,-2,2) = '00' and length(ID)>3 以下のロジックを教えて頂きたいです。

宜しくお願い致します。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Panzer_vor

2016/09/12 12:28

丸投げと捉えられかねない内容ですので、 現段階で試したこと、検討していることがあれば追記するようお願い致します。
UDKKI

2016/09/12 14:05 編集

申し訳ございません 携帯環境ですので Select case when substr(ID,-2,2) = '00' and length(ID)>3 以下のロジックを教えて頂きたいです。
Panzer_vor

2016/09/12 14:33

> UDKKIさん 可能でしたら質問文の方にコードを追記して下さいね。 後、確認ですがPL/SQLということはデータベースはOracleで間違いないでしょうか?
UDKKI

2016/09/12 15:30

ORACLEです 宜しくお願い致します。
退会済みユーザー

退会済みユーザー

2016/09/12 22:21

質問するときは携帯環境はやめた方がいいです。 携帯から質問すると確実に情報不足です。
guest

回答2

0

ベストアンサー

やりたいのは DB1からDB2のデータ取得です。

DB1, DB2 って何ですか?テーブル?インスタンス?

とりあえず、
文字列を入力、結果も文字列とするFUNCTIONで、結果を3桁以上で後ろ2桁が'00'なら後ろ2桁を削る、って作業をLOOPで。

CREATE FUNCTION, LOOP,IF(今回の案件はEXIT WHENかな?) はPL/SQL言語リファレンスに載っています。
丸投げするのではなく、
自分でここまで作れたけどどこが間違っているのでしょうか?って成果を提示して、後からPL/SQLを学ぶ人たちの道しるべになる内容にしたいものです。

投稿2016/09/12 17:39

編集2016/09/12 18:21
Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

すでに解決済のようですが、
質問をする際は、自身の試したことを掲示することを心がけてください。

それが合っていようとずれていようと、
試行錯誤したとわかる質問であれば、
回答側も力になろうと言う心理が働きますし、
回答側もより無駄のない回答が掲示できます。
(今回のケースだと掲示がないままだとSUBSTR(ID, -2, 2)の箇所が回答側でもダブル可能性がありましたよね?)

さて以下は蛇足ですが、
Oracleでも確か正規表現をサポートしていた記憶があるので、
当方でしたらDB2に登録するIDの導出は下記のようなアプローチをとります。
0. DB1.IDのIDを先頭3桁(部分文字列1)と、残りの桁(部分文字列2)で分割(SUBSTRなどで可能)
0. 部分文字列2より文字末尾が「00」の繰り返しパターンに該当するものを空文字に置き換え
0. 部分文字列1と上記でリプレイス処理後の部分文字列を再結合

以下コードのイメージ(変数定義は割愛)

SQL

1/* 場合によっては最初にIDの長さを見なければならないかも */ 2vStr1 := SUBSTR(A.ID, 1, 3); 3vStr2 := SUBSTR(A.ID, 4); 4 5vStr2 := REGEXP_REPLACE(vStr2, '(0{2})+$',''); 6 7vNewID := vStr1 || vStr2;

ただし王道はOrlofskyさんの掲示されている方法かなと思います。
後、興味があれば正規表現についても調べてみてくださいね。

投稿2016/09/12 23:37

編集2016/09/12 23:46
Panzer_vor

総合スコア1636

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Orlofsky

2016/09/13 02:42

元筆問者は本当に解決できたのか不安もありますが、正規表現で処理できればLOOPもFUNCTIONも不要ですからシンプルで良いですね。 SQL> SELECT REGEXP_REPLACE('1010000', '(0{2})+$','') FROM DUAL ; REGEXP ------ 101 SQL> SELECT REGEXP_REPLACE('1000000', '(0{2})+$','') FROM DUAL ; RE -- 1 と頭の3桁は残すって機能が足りません。
Panzer_vor

2016/09/13 03:11

> Orlofskyさん 何かコードのハイライトが崩れてて見にくいかもしれませんが、 頭の3桁を残すという要件に備えて最初の3桁とそれ以外をSUBSTRで切り出してたりします。 多分これでいけるはずなんですが、動かしてはないので確証はなしです^^;
Orlofsky

2016/09/13 07:38

おっと、 >vStr1 := SUBSTR(A.ID, 1, 3); の部分が抜けていましたね。 SQL> SELECT SUBSTR(A.ID, 1, 3) || REGEXP_REPLACE(ID, '(0{2})+$', '') AS ANS 2 FROM( 3 SELECT '1010000' AS ID FROM DUAL UNION ALL 4 SELECT '1000000' AS ID FROM DUAL 5 ) A ; ANS ----------------------------------------------------------------------------- 101101 1001 となり、ちょっと違います。
Panzer_vor

2016/09/13 10:31

> Orlofskyさん 度々ご確認いただきありがとうございます。 ただ2つ目のREGEXP_REPLACEをかけている箇所ですが、 こいつはID列の4桁目以降を対象にしております(vStr2の変数を参照)。 ハイライトが見にくくなってるので、直したいところですね。 PL/SQLの場合を上手く表示する方法ってありましたっけ・・・
Orlofsky

2016/09/13 22:04

結局、PL/SQLにしないと正常に動作しませんでした。 SQL> CREATE OR REPLACE FUNCTION FUNC1 2 ( 3 I_ID VARCHAR2 4 ) 5 RETURN VARCHAR2 6 IS 7 vStr1 VARCHAR2(3) := SUBSTR(I_ID, 1, 3) ; 8 vStr2 VARCHAR2(128) := SUBSTR(I_ID, 4) ; 9 BEGIN 10 RETURN(vStr1 || REGEXP_REPLACE(vStr2, '(0{2})+$', '')) ; 11 END FUNC1 ; 12 / ファンクションが作成されました。 SQL> COLUMN ANS FORMAT A10 SQL> SELECT FUNC1('1010000') AS ANS FROM DUAL ; ANS ---------- 101 SQL> SELECT FUNC1('1000000') AS ANS FROM DUAL ; ANS ---------- 100 SQL> 正規表現の勉強になりました。ありがとうございます。 [コメント]はコードを見やすく表示できません。[回答]なら</>でコードをくくれば良いのですが。1年以上前からteratail 側に改善を要望しているのですが、遅々として進みませんね。どこか使いやすい掲示板があると良いのですが。
Panzer_vor

2016/09/14 03:15

> Orlofskyさん REGEXP_REPLACEの中にSUBSTR関数などをネストできない等の制約はなかったはずなので、 SQL単体でも表現できそうな気はします。 以下のSQLでもダメそうでしょうかね? SELECT SUBSTR(A.ID, 1, 3) || REGEXP_REPLACE(SUBSTR(A.ID, 4), '(0{2})+$', '') AS ANS FROM( SELECT '1010000' AS ID FROM DUAL UNION ALL SELECT '1000000' AS ID FROM DUAL ) A
Orlofsky

2016/09/14 03:51

SQL> SELECT SUBSTR(A.ID, 1, 3) || REGEXP_REPLACE(SUBSTR(ID, 4), '(0{2})+$', '') AS ANS 2 FROM( 3 SELECT '1010000' AS ID FROM DUAL UNION ALL 4 SELECT '1000000' AS ID FROM DUAL 5 ) A ; ANS ---------- 101 100 でうまくいきました。お手数かけてすみません。(_ _);
Panzer_vor

2016/09/14 10:41

> Orlofskyさん ご確認いただきありがとうございます。 無事動作したとのことで何よりです。 (デマ回答だとそのまま残しておく訳にはいかないので^^;) 正規表現は当方もそこまで深い知識はありませんが、 パターンマッチング系では威力を発揮するので、 頭の片隅に入れておくと良いかと思われます。 記載コード量が減るのは、 メリットとしては捨てがたいですしね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問