2

文字列を指定してテーブルに値をクエリする必要があります。テーブルでは大文字と小文字が区別されますが、比較でToLower()を実行したいと思います。

次のデータを含むクラステーブルがあるとします。

class    teacher
-----------------
Mat101   Smith
MAT101   Jones
mat101   Abram
ENG102   Smith

私のクエリは次のようになります

Select teacher From classes where lower(class) = 'math101'

これは比較を行うための最良の方法ですか?

アップデート

私はデータベースやデータを管理できません。私は読み取り専用の消費者です。

4

6 に答える 6

2

この方法では、10gr2以上を実行する必要があります。

セッションを変更する前に:

SQL> WITH LETTERS AS
  2  (SELECT 'a' LETTER FROM DUAL UNION ALL
  3   SELECT 'b' LETTER FROM DUAL UNION ALL
  4   SELECT 'A' LETTER FROM DUAL UNION ALL
  5   SELECT 'B' LETTER FROM DUAL) 
  6  SELECT LETTER FROM LETTERS 
  7  WHERE LETTER = 'A';

L
-
A

SQL> 

セッションを変更できる場合は、次のようにすることができます。

SQL> ALTER SESSION SET NLS_SORT=BINARY_CI;

Session altered.

SQL> ALTER SESSION SET NLS_COMP=LINGUISTIC;

Session altered.

SQL> WITH LETTERS AS
  2  (SELECT 'a' LETTER FROM DUAL UNION ALL
  3   SELECT 'b' LETTER FROM DUAL UNION ALL
  4   SELECT 'A' LETTER FROM DUAL UNION ALL
  5   SELECT 'B' LETTER FROM DUAL) 
  6  SELECT LETTER FROM LETTERS 
  7  WHERE LETTER = 'A';

L
-
a
A

上記のようにセッションを変更すると、データベースは、同等のオブジェクトと同じ文字の大文字と小文字のバージョンを並べ替えて比較します。詳細については、http://www.orafaq.com/node/91を参照してください。

HTH、Gabe

于 2008-12-23T19:02:57.453 に答える
2

関数ベースのインデックスに関する詳細情報は次のとおりです (上記で Dave が参照していたもの)。

于 2008-12-23T17:56:18.430 に答える
1

データベースの読み取り専用ユーザーであることを追加したため、最善の方法は、最初に行った方法に近いものです。

Select teacher From classes where lower(class) = LOWER('math101')

入力パラメーターに LOWER() を追加したことに注意してください。これも小文字であることを確認するためです。それを「ベルトとサスペンダー」(別名冗長)と呼ぶ人もいます。私はそれを優れた防御的プログラミングと呼んでいます。

于 2009-01-02T18:19:01.347 に答える
0

あなたが話している種類のクエリの欠点は、クラスでインデックスを使用できないことです(つまり、インデックスルックアップとして、つまり、インデックスの高速フルスキャンで使用できる可能性があります)。

ただし、Oracleの最新バージョンでは、LOWER(class)にインデックスを作成して、このクエリで使用することができます。

于 2008-12-23T17:40:46.480 に答える
0

いいえ; データを改善することをお勧めします。これらの一見無意味なクラスのバリエーションを表す数値IDを作成します(おそらく、IDを取得するための関連するルックアップテーブル)。where句でID列を使用すると、インデックス付きの数値列にヒットするはずです。

それが選択肢にない場合は、lower(class)の関数ベースのインデックスを検討してください。

それがオプションではなく、「最良」の質問が厳密にパフォーマンスに関連している場合は、非正規化して、おそらくトリガーが設定されたlower(class)を含む列を追加することを検討してください。

それが不可能な場合は、すべて小文字になるようにデータを更新します(そして、小文字のクラスデータのみを挿入/更新するための対策を講じます)。

そのようにデータを更新できない場合、答えは「たぶん」です。

いずれにせよ、列のインデックス作成をテストしていない場合は、これを最適に呼び出すことはできません。

于 2008-12-23T18:15:06.973 に答える
0

バリアント (Mat101、MAT101、mat101) が同じものを参照する場合、同じ識別子を持つ必要があります。

データの量、更新の頻度、クエリなどに応じて、レプリケーションに組み込まれたクレンジング/標準化ステージで制御するデータベースにデータをレプリケートすることを検討できます。

「私はデータベースを制御できない」と言っていますが、クエリを実行できれば、データベースに影響を与えることができます。誰かがデータベースを制御しており、その列に lower() インデックスを追加すると、クエリがデータベースに与える影響が軽減されるというメールや電話をする価値があるかもしれません。

最後に、バリアントが十分に単純な場合は、試すことができます

Select teacher From classes where class in (lower('mat101'), upper('mat101'), initcap('mat1010')). 
于 2008-12-23T21:51:57.487 に答える