9

文字列変数 (varchar、nvarchar、char) に基づいてデータを選択するためのストアド プロシージャを作成すると、次のようになります。

procedure dbo.p_get_user_by_username(
    @username      nvarchar(256)
as
begin
    select
        u.username
        ,u.email
        --,etc
    from
        sampleUserTable u
    where
        u.username = @username
end

つまり、私が持っているレコードと一致するように

u.username = @username

しかし、 =の代わりにLIK Eを使用するコードに出くわすことがあります。

u.username like(@username)

いつ使用しますか?ワイルドカードの一致が必要な場合にのみ使用するべきではありませんか?

編集

答えてくれてありがとう。

私が本当に尋ねようとしていたことを明確にする必要があると思います: 正確な文字列一致のために "=" の代わりに like を使用することが好まれる状況があるかどうか。答えから、私はそうではないだろうと言うことができました。私自身の経験から、大文字と小文字の区別や先頭と末尾のスペースなどを無視する必要がある状況でも、両方の文字列で ltrim、rtrim、lower を使用し、次に「=」を使用します。ご意見をお寄せいただきありがとうございます。

4

9 に答える 9

13

あなたは正しいです。ワイルド カード マッチングを行う場合を除き、LIKE を使用してもメリットはありません。さらに、ワイルドカードなしで使用すると、非効率的なクエリプランが使用される可能性があります。

于 2008-11-19T16:20:33.103 に答える
8

サニーはほとんどそれを正しくしました:)

SQL2005のデフォルトインストールのQAで以下を実行します

select * from sysobjects where name = 'sysbinobjs   '
-- returns 1 row
select * from sysobjects where name like 'sysbinobjs   '
-- returns 0 rows

したがって、LIKEは末尾のスペースでは一致しません。クエリプラン側では、どちらもほぼ同等のパフォーマンスを発揮しますが、「=」結合のパフォーマンスはわずかに向上します。

LIKEを使用するときに注意しなければならない追加のことは、文字列を適切にエスケープすることです。

declare @s varchar(40) 
set @s = 'escaped[_]_%'

select 1 where 'escaped[_]_%'  like @s 
--Return nothing = BAD 

set @s = '_e_s_c_a_p_e_d_[___]___%' 

select 1 where 'escaped[_]_%'  like @s escape '_'
--Returns 1 = GOOD

エスケープの問題はあらゆる種類の複雑さや微妙なバグを引き起こすため、一般的に人々は正確なマッチングにLIKEを使用しません。人々はエスケープを忘れ、苦痛の世界があります。

しかし...効率的な実際の完全一致が必要な場合は、LIKEで問題を解決できます。

たとえば、ユーザー名を「sam」に一致させ、「Sam」または「Sam」を取得したくない場合、残念ながら、列の照合では大文字と小文字が区別されません。

次のようなもの(エスケープが追加されたもの)が進むべき道です。

select * from sysobjects
WHERE name = 'sysbinobjs' and name COLLATE Latin1_General_BIN LIKE 'sysbinobjs'

ダブルマッチを行う理由は、テーブルスキャンを回避するためです。

でも ....

varbinaryキャストのトリックは、バグが発生しにくく、覚えやすいと思います。

于 2008-11-20T01:11:00.537 に答える
3

ワイルドカードが使用されていない場合の違いは、「=」は正確に一致しますが、LIKE は末尾にスペースがある文字列に一致します (SSBO から)。

LIKE を使用して文字列比較を実行する場合、パターン文字列内のすべての文字は、先頭または末尾のスペースを含めて重要です。クエリの比較で、文字列 LIKE 'abc ' (abc の後に 1 つのスペースが続く) を含むすべての行が返される場合、その列の値が abc (スペースなしの abc) である行は返されません。ただし、パターンが一致する式の末尾の空白は無視されます。クエリの比較で、文字列 LIKE 'abc' (スペースなしの abc) を含むすべての行が返される場合、abc で始まり、ゼロ個以上の末尾の空白があるすべての行が返されます。

于 2008-11-19T17:09:01.430 に答える
2

LIKEキーワードを使用すると、固定の「文字列」ではなく、指定したパターンに対してフィールドを照合できますu.username

于 2008-11-19T16:18:18.350 に答える
2

他の人のコードでこれを見ている場合は、パターンまたはワイルドカードを含む文字列を人が渡すことを許可することを意図していた可能性があります。

于 2008-11-19T18:54:01.483 に答える
1

はい、その通りです。ワイルドカード マッチングにのみ使用してください。クエリが非常に遅くなる可能性があるため、特にインデックスのないフィールドの非常に大きなテーブルでは控えめに使用する必要があります。

于 2008-11-19T16:22:59.883 に答える
1

私は同じ問題に遭遇しました。で同様のクエリを実行すると、約 1 分半かかりました=。クエリに変更=すると、はるかに高速になりました。like

  • 比較している列のインデックスを作成してみてください。これにより、クエリが大幅に高速化されました。
  • 実行してみてくださいsp_updatestats=私の場合、これにより、インデックスを使用せずに、ほぼ瞬時にインデックスを使用して、約 6 秒でクエリが実行されました。
于 2013-12-06T15:36:35.157 に答える
0

LIKEはワイルドカードマッチング用であり、as =(equals)は完全一致用です。

また、ハードコア文字列の比較のためにFULLTEXTCATALOGSによってカタログ化されたフィールドにも使用されたと思います。

于 2008-11-20T01:13:51.280 に答える
-1

はい、私の知る限り、ワイルドカードなしで like を使用することは、= 演算子を使用することと同じです。入力パラメーターにワイルドカードが含まれていませんか?

于 2008-11-19T16:21:54.333 に答える