Чтение GUID в виде строки из таблицы Sybase с использованием JDBC

#sql #guid #uuid #sap-ase

#sql #guid #uuid #sap-ase

Вопрос:

В моей базе данных Sybase 12.0 ASE у меня есть таблица at, которая содержит столбец, определенный как двоичный (16) и используемый для хранения идентификаторов GUID / UUID. Когда я запускаю запрос select с использованием SQL client ansi SQL для этой таблицы, все выглядит нормально .. я вижу значение guid, как я ожидаю, в результирующем наборе (идентификатор guid выглядит примерно так: «1ae5608d12311de123d001185135a13» в выводе sql)

Однако в коде при попытке сделать это через JDBC (я использую драйвер Sybase «com.sybase.jdbc3.jdbc.SybDriver»), когда я перебираю результирующий набор и пытаюсь прочитать этот столбец, он возвращается в основном как мусор. если я создаю ResultSet.GetObject(col), где col — двоичный индекс столбца в моем результирующем наборе, я вижу, что тип — byte[] . Я пытался преобразовать это в строку и кодировать как Base64, но безрезультатно.

Есть идеи, как это сделать?

Спасибо

Комментарии:

1. Подсказка: вы можете пометить вопрос с помощью Java ; это скорее вопрос Java, чем Sybase.

Ответ №1:

byte[] Вы получаете именно то, что и должно быть: последовательность из 16 байт или меньше, в соответствии с определением столбца.

Какое представление UID вы пытаетесь создать? — Обычно они представлены не как Base64, а как Hex.

Попытка прямого преобразования byte[] в a String , безусловно, не то, что вы хотите.
Если вы выполняете итерацию по массиву, преобразуя каждый байт в его (2-значный!) шестнадцатеричное представление (строка) и объединение этих строк в строку длиной 32, результат, вероятно, будет выглядеть намного больше, чем вам нужно.

Если вы хотите использовать java.util.UUID , вы должны создать два long значения из первого и второго набора из восьми байтов соответственно, которые будут переданы конструктору.

Редактировать:

В java.util.UUID вы можете найти:

 /*
 * Private constructor which uses a byte array to construct the new UUID.
 */
private UUID(byte[] data) {
    long msb = 0;
    long lsb = 0;
    assert data.length == 16;
    for (int i=0; i<8; i  )
        msb = (msb << 8) | (data[i] amp; 0xff);
    for (int i=8; i<16; i  )
        lsb = (lsb << 8) | (data[i] amp; 0xff);
    this.mostSigBits = msb;
    this.leastSigBits = lsb;
}
 

Я понятия не имею, почему это не public так…

Учитывая ваш byte[] , вы можете создать два long значения, необходимые для UUID(long,long конструктора, именно с этим кодом.

Вам нужно будет только обратить внимание на порядок байтов в массиве, который вы получаете из БД; какой из них является наименее значимым байтом, который является наиболее значимым байтом. (Вероятно, либо [0] и [15], либо [15] и [0].)

Как только у вас есть экземпляр UUID , вы можете использовать его toString() для получения общего представления.

Если вы не хотите использовать UUID , вам придется самостоятельно преобразовывать байты в шестнадцатеричные для вывода и, возможно, вставлять некоторые тире для удобства чтения.

Комментарии:

1. Я считаю, что представление, которое мне нужно создать, является шестнадцатеричным. у вас случайно нет каких-либо примеров / примеров того, как это сделать?