0

単語に文字列が存在するかどうかを調べて抽出しようとしています。私はinstr()この関数を使用しましたが、これはLIKE関数として機能します。単語の一部または全体が存在する場合は、それを返します。

ここでは、文字列「Services」を取得したいのですが、「Services」を「Service」に変更しても機能します。私はそれを望んでいません。「サービス」が入力された場合、「サービス」ではなくnullを返す必要があります

変更:

ここで私がやろうとしているのは、会社名の特定の部分を省略したものです。

これは私のデータベーステーブルがどのように見えるかです:

Word     | Abb
---------+-----  
Company  | com
Limited  | ltd
Service  | serv
Services | servs

コードは次のとおりです。

Declare 

    Cursor Words Is

    SELECT word,abb
    FROM abbWords


    processingWord VARCHAR2(50);
    abbreviatedName VARCHAR(120);
    fullName = 'A.D Company Services Limited';

BEGIN

    FOR eachWord IN Words LOOP


      --find the position of the word in name
       wordPosition := INSTR(fullName, eachWord.word);

       --extracts the word form the full name that matches the database
       processingWord := Substr(fullName,instr(fullName,eachWord.word), length(eachWord.word));

      --only process words that exist in name
      if wordPosition > 0 then
           abbreviatedName = replace(fullName, eachWord.word,eachWord.abb);
       end if;

    END lOOP;

END;

したがって、ユーザーが「サービス」と入力した場合、「サービス」が返されることは望ましくありません。つまり、「サービス」という単語の位置を返す代わりに、「サービス」という単語が見つからない場合は、単語の位置を0にする必要があります。

4

4 に答える 4

4

それを行う1つの方法:

DECODE(INSTR('A.D Company Seervices Limited','Services'),
              0,
              NULL,
              SUBSTR('A.D Company Services Limited',
                  INSTR('A.D Company Services Limited','Services'),
                  length('Services')))

INSTR()テキストが見つからない場合は 0 を返します。DECODE()最初の引数を評価し、2 番目の引数と比較し、一致する場合は 3 番目の引数を返し、一致しない場合は 4 番目の引数を返します。( sqlfiddle リンク)

おそらく最もエレガントな方法ではありませんが、要件に一致します。

于 2012-09-04T15:03:56.783 に答える
3

私はあなたがこれを過度に複雑にしていると思います。正規表現ですべてを行うことができます。例えば; 次の表が与えられます。

create table names ( name varchar2(100));
insert into names values ('A.D Company Services Limited');
insert into names values ('A.D Company Service Limited');

このクエリは名前のみを返します'A.D Company Services Limited'

select *
  from names
 where regexp_like( name
                  , '(^|[[:space:]])services($|[[:space:]])'
                  , 'i' )

^これは、文字列の先頭、またはスペースの後にサービスが続き、文字列の末尾 、またはスペースと一致することを意味し$ます。これが、正規表現を etc の使用と区別するものinstrです。他の要因で簡単に条件付きの一致を作成できます。

ただし、これはあなたの質問のようですが、これがあなたがやろうとしていることではないと思います。または'serv'を置き換えずに、より広い文字列の文字列を置き換えようとしています。これには、 を使用する必要があります。'services''service'regexp_replace()

次の行をテーブルに追加すると:

insert into names values ('A.D Company Serv Limited');

次のクエリを実行します。

select regexp_replace( name
                     , '(^|[[:space:]])serv($|[[:space:]])'
                     , ' Services '
                     , 1, 0, 'i' )
  from names

唯一変更されるのは' Serv 'で、この最新行では に置き換えられ' Services 'ます。スペースに注意してください。これらに置き換えたくないので、非常に重要'Services'です。'ServServices'

これは、デモンストレーションする小さな SQL Fiddleです。

于 2012-09-04T18:21:37.537 に答える
2

INSTR数値を返します: 一致する文字列が最初に出現したインデックスです。代わりに使用する必要がありますregexp_substr(10g+):

SQL> select regexp_substr('A.D Company Services Limited', 'Services') match,
  2         regexp_substr('A.D Company Service Limited', 'Services') unmatch
  3  from dual;

MATCH    UNMATCH
-------- -------
Services
于 2012-09-04T15:01:32.607 に答える
2

別の代替手段は、次のようなものを使用することです。

select replace(name,' serv ', ' Services ')
from names;

これにより、2 つのスペースの間にある「Serv」という単語のみが置き換えられます。

ありがとう、アレックス。

于 2012-09-13T14:26:37.137 に答える