私は次の問題を抱えています:
名前付きの列Nameを持つテーブルTがあります。名前の構造は次のとおりです。
A \\ B\C
次のように自分で作成できます。
create table T ( Name varchar(10));
insert into T values ('A\\\\B\\C');
select * from T;
今私がこれを行う場合:
select Name from T where Name = 'A\\B\C';
それは機能しません、私は\(バックスラッシュ)をエスケープする必要があります:
select Name from T where Name = 'A\\\\B\\C';
結構です。
しかし、文字列Nameに対してこれを自動的に行うにはどうすればよいですか?
次のようなものはそれをしません:
select replace('A\\B\C', '\\', '\\\\');
私は得る:A\\\BC
助言がありますか?
よろしくお願いします。
"verbatim string"を使用する必要があります。その文字列を使用すると、Replace関数は次のようになります。
Replace(@"\", @"\\")
お役に立てば幸いです。
正規表現を使用すると、問題が解決します。
この以下のクエリは、与えられた例を解決します。
1) S\\D\B
select * from T where Name REGEXP '[A-Z]\\\\\\\\[A-Z]\\\\[A-Z]$';
与えられた例に複数の文字が含まれている可能性がある場合
2) D\\B\ACCC
select * from T where Name REGEXP '[A-Z]{1,5}\\\\\\\\[A-Z]{1,5}\\\\[A-Z]{1,5}$';
注:テーブルの作成クエリで言及されているように、フィールドサイズが10であることを考慮して、charの最大出現回数として5を使用しました。
それでも一般化することはできますが、それでも期待に応えられない場合は、遠慮なく助けを求めてください。
データベースの内容と、SQLステートメントでそのデータを表現する方法を混同しています。データベース内の文字列に\
のような特殊文字が含まれている場合、\\
はSQL構文の特殊文字であるため、その文字を表すには\
と入力する必要があります。これはINSERT
ステートメントで行う必要がありますが、REPLACE
関数のパラメーターでも行う必要があります。実際にはデータに二重スラッシュはありません。これらはUIの一部にすぎません。
SQL式のスラッシュを2倍にする必要があるのはなぜだと思いますか?クエリを入力する場合は、コマンドラインでスラッシュを2倍にする必要があります。プログラミング言語でクエリを生成する場合、最善の解決策はプリペアドステートメントを使用することです。 APIが適切なエンコーディングを処理します(プリペアドステートメントは通常、生データを処理するバイナリインターフェイスを使用します)。何らかの理由で文字列を作成してクエリを実行する必要がある場合、言語は文字列をエスケープする関数を提供する必要があります。たとえば、PHPでは、mysqli_real_escape_string
を使用します。
ただし、SQL自体でそれを行うことはできません。エスケープされていない文字列をSQLにフィードしようとすると、データが失われ、再構築できません。
リテラル_A\\B\C
_は_A\\\\A\\C
_としてコーディングする必要があり、replace()
のパラメーターもエスケープする必要があります。
_select 'A\\\\B\\C', replace('A\\\\B\\C', '\\', '\\\\');
_
出力( これはSQLFiddleで実行されています を参照):
_A\\B\C A\\\\B\\C
_
したがって、replaceを使用しても意味がありません。これらの2つのステートメントは同等です。
_select Name from T where Name = replace('A\\\\B\\C', '\\', '\\\\');
select Name from T where Name = 'A\\\\B\\C';
_