2

私はこのような素敵なMySQLテーブルを持っています:

CREATE TABLE IF NOT EXISTS BLOBTest(Id INT PRIMARY KEY AUTO_INCREMENT,

    Data BLOB);

そしてその中に私は次のものを持っています:

SELECT HEX(Data) from BLOBTest;

+----------------------------------+
| HEX(Data)                        |
+----------------------------------+
| E764DF04463B55E9E2305934266227A1 |
+----------------------------------+

翻訳すると、1行2列(IdとData)のテーブルがあります。この行はbyte[]データを保持し、格納されるbyte []配列は次のとおりです。[-25、100、-33、4、70、59、85、-23、-30、48、89、52、38、98 、39、-95]

クエリを実行して全体を取得するにはどうすればよいですか?最初に試しました:

SELECT * FROM BLOBTest WHERE Data='[-25, 100, -33, 4, 70, 59, 85, -23, -30, 48, 89, 52, 38, 98, 39, -95]';

ただし、このアプローチはまったく機能せず、常に空のセットを返します。その行のすべての情報を取得する必要があり、私が持っているのはbyte[]値だけです。どうすればいいのですか?

可能であれば助けてくれてありがとうplz。

編集:

これがJavaアプリのコードとその機能です。

public Map<Integer, String> queryAuthor(String author) throws Exception{

    //encrypts the name of the author
    byte[] cipheredName = cryptManager.encrypt(keyBytes, 
                author.getBytes());

    //queries db for encrypted name
    pst = con.prepareStatement("SELECT * FROM BLOBTest WHERE DATA='" + cipheredName+"'");

    //builds a map for clients to use with the information from the query. 
    ResultSet rs =  pst.executeQuery();
    Map<Integer, String> result = new HashMap<Integer, String>();
    while (rs.next()) {

        byte[] recoveredBytes = rs.getBytes(2);

        byte[] recoveredName = cryptManager.decrypt(keyBytes, 
                    recoveredBytes);

        result.put(rs.getInt(1), new String(recoveredName));

    }

    return result;
}

問題は、次のことを行うことです。

SELECT * FROM BLOBTest WHERE Data='[-25, 100, -33, 4, 70, 59, 85, -23, -30, 48, 89, 52, 38, 98, 39, -95]';

空のセットを返すため、変数「rs」は空になり、返されるマップは空になります。私は初心者で、このような単純なクエリを作成できないため、誰もが悲しいです=(

4

1 に答える 1

5

生のバイトを文字列リテラルとしてMySQLに送信できます。

SELECT * FROM BLOBTest WHERE Data = '????????????????'

(すべてのバイトを印刷可能な文字で表すことができるわけではないので、私は試したことさえありません)。

これは、パラメーターを介してプリペアドステートメントにデータを渡す場合に特に簡単です(これは、どのような場合でも実際に行う必要があります)。

pst = con.prepareStatement("SELECT * FROM BLOBTest WHERE DATA = ?");
pst.setBytes(1, cipheredName);

それ以外の場合は、MySQLが文字列終了引用符として解析するバイトをエスケープするように注意する必要があります。そうしないと、クエリが破損します。


(以下は、OPの編集で提供された追加情報よりも前のものです)

BLOBそれが不可能だった場合は、データを-type列に格納するべきではないことを示している可能性があります。たとえば、16TINYINT SIGNED列の方が適切だった可能性があります。

それでも、まだ可能性があります。

  • MariaDBまたはMySQLで16進リテラルを使用できる場合は、16進文字列を2進形式に解釈します。

      SELECT * FROM BLOBTest WHERE Data = x'E764DF04463B55E9E2305934266227A1'
    

sqlfiddleでそれを参照してください。

  • UNHEX()また、上記の16進リテラルで説明されているのと同じことを行います。

    SELECT * FROM BLOBTest WHERE Data = UNHEX('E764DF04463B55E9E2305934266227A1')
    
  • 各バイトを符号なしの値に変換できる場合:

      SELECT * FROM BLOBTest WHERE Data = CHAR(
        231,100,223,4,70,59,85,233,226,48,89,52,38,98,39,161
      )
    

sqlfiddleでそれを参照してください。

  • CHAR()それ以外の場合、MySQLは各入力を4バイト整数として扱うため、最上位ビットを削除する必要があります。

      SELECT * FROM BLOBTest WHERE Data = CHAR(
        -25 & 0xff,
        100 & 0xff,
        -33 & 0xff,
          4 & 0xff,
         70 & 0xff,
         59 & 0xff,
         85 & 0xff,
        -23 & 0xff,
        -30 & 0xff,
         48 & 0xff,
         89 & 0xff,
         52 & 0xff,
         38 & 0xff,
         98 & 0xff,
         39 & 0xff,
        -95 & 0xff
      )
    

sqlfiddleでそれを参照してください。

于 2013-01-23T15:14:53.433 に答える