sql >> データベース >  >> RDS >> Mysql

MySQLワイルドカードのエスケープ

    _ および% 一般にMySQLのワイルドカードではないため、通常の文字列リテラルに入れる目的でエスケープしないでください。 mysql_real_escape_string この目的には正しく、十分です。 addcslashes 使用しないでください。

    _ および% LIKEのコンテキストでのみ特別です -マッチング。 LIKEでリテラルとして使用する文字列を準備する場合 ステートメント、つまり100% 100%に一致し、100で始まる文字列だけでなく、2つのレベルのエスケープについて心配する必要があります。

    1つ目はLIKEエスケープです。 LIKE処理は完全にSQL内で行われ、リテラル文字列をリテラルLIKE式に変換する場合は、パラメータ化されたクエリを使用している場合でも、この手順を実行する必要があります。

    このスキームでは、_ および% 特別であり、エスケープする必要があります。エスケープ文字もエスケープする必要があります。 ANSI SQLによると、これら以外の文字はすべきではありません エスケープされる:\' 間違っているでしょう。 (ただし、MySQLは通常、それを回避することができます。)

    これを実行したら、エスケープの2番目のレベルに進みます。これは、単純な古い文字列リテラルのエスケープです。これはSQLの外部で行われ、SQLを作成するため、LIKEエスケープステップの後に実行する必要があります。 MySQLの場合、これはmysql_real_escape_stringです。 従来通り;他のデータベースには別の機能があります。パラメータ化されたクエリを使用するだけで、それを実行する必要がなくなります。

    ここで混乱を招く問題は、MySQLでは、ネストされた両方のエスケープステップのエスケープ文字としてバックスラッシュが使用されていることです。したがって、文字列をリテラルのパーセント記号と照合する場合は、ダブルバックスラッシュエスケープしてLIKE 'something\\%'と言う必要があります。 。または、それがPHPの場合" バックスラッシュエスケープも使用するリテラル、"LIKE 'something\\\\%'" 。ああ!

    ANSI SQLによると、これは正しくありません。文字列リテラルでは、バックスラッシュはリテラルのバックスラッシュを意味し、一重引用符をエスケープする方法は''です。; LIKE式では、デフォルトではエスケープ文字はまったくありません。

    したがって、移植可能な方法でLIKEエスケープする場合は、デフォルトの(間違った)動作をオーバーライドし、LIKE ... ESCAPE ...を使用して独自のエスケープ文字を指定する必要があります。 構築します。正気のために、私たちはいまいましいバックスラッシュ以外のものを選びます!

    function like($s, $e) {
        return str_replace(array($e, '_', '%'), array($e.$e, $e.'_', $e.'%'), $s);
    }
    
    $escapedname= mysql_real_escape_string(like($name, '='));
    $query= "... WHERE name LIKE '%$escapedname%' ESCAPE '=' AND ...";
    

    またはパラメータ付き(例:PDO):

    $q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
    $q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);
    

    (ポータビリティパーティーの時間をもっと増やしたい場合は、MSSQLServerとSybaseを説明することもできます。[ 間違って、文字はLIKEでは特別です ステートメントとエスケープする必要があります。 argh。)



    1. 挿入されたレコードのIDを取得します:Php&MS SQL SERVER

    2. 照合の競合を解決できません

    3. ActiveRecordrawSQLから型指定された結果を取得する

    4. OraclePLSQLでの任意の年のイースターの日付の決定