JDBC ничего не возвращает

Я создаю API с помощью Spring и JDBC. Однако теперь я столкнулся с проблемой, когда запрос JDBC ничего не возвращал, хотя тот же запрос в SQL Developer возвращает данные.

Это мой метод в Java:

public Standardtexte getStandardtexte(String kurztext)
    {
        Standardtexte standardtexte = new Standardtexte();
        standardtexte.kurztext = kurztext;
        standardtexte.schluessel = jdbc.query("select schluessel, langtext from hb_standardtexte where kurztext = ?", (rs, rowNum) -> {
            Schluessel s = new Schluessel();
            s.schluessel = StringUtils.trimToEmpty(rs.getString(1));
            s.langtext = StringUtils.trimToEmpty(rs.getString(2));
            return s;
        }, kurztext);
        return standardtexte;
    }

Я пробую этот запрос в Postman: localhost:8080/standardtexte?kurztext=KOELUNG, но не получаю полезного результата:

{
    "kurztext": "KOELUNG",
    "schluessel": []
}

Когда я пытаюсь тот же запрос в SQL Developer:

select schluessel, langtext from hb_standardtexte where kurztext = 'KOELUNG';

Я получаю такой результат: Изображение таблицы результатов

Пожалуйста, может кто-нибудь помочь мне/объяснить, почему это происходит.

Я также пробовал это с другими параметрами для kurztext: Странная вещь: другие параметры работают....

🤔 А знаете ли вы, что...
Java обеспечивает механизм сериализации объектов для сохранения и передачи данных.


78
3

Ответы:

Убедитесь, что вы COMMIT свои данные.

В Oracle, если вы этого не сделаете COMMIT, то только сеанс, в котором были созданы данные, сможет видеть незафиксированные данные, а другие сеансы, даже принадлежащие одному и тому же пользователю, никогда не увидят эти незафиксированные данные.

Например, поведение можно объяснить:

  1. Если вы создаете данные в SQL Developer, но не COMMIT вводите данные и не закрываете сеанс.
  2. Затем, если вы запросите данные из Java, он подключится к базе данных и создаст новый сеанс (даже если вы подключитесь от имени того же пользователя), и тогда вы никогда не увидите незафиксированные данные.
  3. Но если вы вернетесь к открытому сеансу в SQL Developer, вы увидите, что данные существуют в незафиксированной форме в этом сеансе.
  4. Чтобы увидеть это в других сеансах, COMMIT данные в SQL Developer.

Решено

Резюме: не используйте тип данных CHAR для строк переменной длины. Используйте VARCHAR2.


Если таблица:

CREATE TABLE hb_standardtexte (
  kurztext CHAR(10)
);

С данными:

INSERT INTO hb_standardtexte (kurztext) VALUES ('KOELUNG')

Затем, когда вы используете:

select kurztext
from   hb_standardtexte
where  kurztext = 'KOELUNG';

Результат:

КУРЦТЕКСТ КЁЛУНГ

В документации Oracle Literal говорится:

Текстовые литералы обладают свойствами обоих типов данных: CHAR и VARCHAR2:

  • В выражениях и условиях Oracle обрабатывает текстовые литералы так, как будто они имеют тип данных CHAR, сравнивая их с использованием семантики сравнения с заполнением пробелами.

Правила сравнения типов данных гласят:

Семантика сравнения с пробелами и без дополнений

При использовании семантики с заполнением пробелами, если два значения имеют разную длину, Oracle сначала добавляет пробелы в конец более короткого значения, чтобы их длины были равны. Затем Oracle сравнивает значения посимвольно до первого отличающегося символа. Значение с большим символом в первой отличающейся позиции считается большим. Если два значения не имеют различающихся символов, они считаются равными. Это правило означает, что два значения равны, если они отличаются только количеством завершающих пробелов. Oracle использует семантику сравнения с заполненными пробелами только тогда, когда оба значения в сравнении являются выражениями типа данных CHAR, NCHAR, текстовыми литералами или значениями, возвращаемыми функцией USER.

При использовании семантики без дополнений Oracle сравнивает два значения посимвольно до первого отличающегося символа. Значение с большим символом в этой позиции считается большим. Если два значения разной длины идентичны до конца более короткого, то большее значение считается большим. Если два значения одинаковой длины не имеют разных символов, то значения считаются равными. Oracle использует семантику сравнения без дополнений всякий раз, когда одно или оба значения в сравнении имеют тип данных VARCHAR2 или NVARCHAR2.

Если вы передаете значение так, чтобы оно имело тип данных VARCHAR2. Например, это можно принудительно сделать в SQL, используя CAST:

select kurztext
from   hb_standardtexte
where  kurztext = CAST('KOELUNG' AS VARCHAR2(10));

Тогда семантика сравнения с заполнением пробелами не используется, и запрос выводит ноль строк.

Вероятно, вы обнаружите, что Java передает значение как VARCHAR2, а не как CHAR.


Нормальное решение:

  1. Исправьте свою таблицу и не используйте типы данных CHAR, всегда используйте VARCHAR2 для столбца и удалите все отступы.

    ALTER TABLE hb_standardtexte MODIFY kurztext VARCHAR2(10);
    
    UPDATE hb_standardtexte
    SET   kurztext = RTRIM(kurztext)
    WHERE kurztext LIKE '% ';
    

    Тогда ваш запрос должен работать.

  2. Если вам необходимо использовать CHAR, дополните строку пробелами до нужной длины (т. е. передайте строку "KOELUNG ", предполагая, что длина столбца составляет 10 символов, а не "KOELUNG").

рабочий пример


Запустите это, чтобы проверить правильность вашего SQL.

select schluessel, langtext from hb_standardtexte where kurztext = 'KOELUNG';