(oracle)テーブル結合で「レコードが選択されませんでした。」

お疲れ様です!
はるさらでございます。

 

oracleでテーブルを結合したかったが
「レコードが選択されませんでした。」が
表示されてしまう。

レコード自体はしっかり登録しているのになぜ!?

と悩んでしまった方へ向けての記事になります。
「こんな失敗パターンもあるのか~」
くらいで見ていただければ幸いです。

実行したSQL

【create文】
create table SHOP(SHOP_NAME VARCHAR2(10),
ID VARCHAR2(4));

create table FRUIT(FRUIT_NAME VARCHAR2(10),
ID CHAR(4),
PRICE NUMBER(6));

 

【select文】
SELECT SHOP_NAME,FRUIT_NAME,PRICE
FROM SHOP S, FRUIT F
WHERE S.ID = F.ID;

 

↓select文の実行結果

 

「レコードが選択されませんでした。」が

表示されてしまっています・・・。

SQL自体に誤りはありません。
では、なぜレコードが選択されなかったのでしょう?

 

 

原因

今回登録したテーブル定義に注目です!
・SHOPテーブル.ID→VARCHAR2(4)
・FRUITテーブル.ID→CHAR(4)

の様に、結合条件に指定したカラムに型の違いがあります。

 

 

CHAR型とVARCHAR型では
指定した最大文字数に達しなかった場合の
値の保持の仕方が変わります。

最大文字数4文字のカラムに1文字のレコードを登録した場合
VARCHAR型
・「1」が登録される

CHAR型
・「1___」が登録される。
※_は空白行だと思ってください。

最大桁数に満たなかった分は、空白で補われてしまいます。

その為、空白を除去してあげないと
正しい結合が出来ないのです。

 

かつ、格納されたデータを取得しようとすると
末尾についている空白は削除されて取得されるため
SELECTの結果では違いが分からないのですよ・・・

でも、結合の時は意識しないと
紐づかなくなってしまいます・・・。

うーん。ややこしい。

 

 

改めてテーブル結合!

結合の際は
trim関数を使用して
空白を取り除きましょう!!

✕-ダメなパターン
SELECT SHOP_NAME,FRUIT_NAME,PRICE
FROM SHOP S, FRUIT F
WHERE S.ID = F.ID;

○-良いパターン
SELECT SHOP_NAME,FRUIT_NAME,PRICE
FROM SHOP S, FRUIT F
WHERE S.ID = trim(F.ID);

 

これにより、想定通りの結果が表示されることが
確認できました!!

カテゴリー: DB