Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 30.06.2022
Сообщений: 47
1

Поиск среди всех полей в FireBird на Delphi

29.02.2024, 01:10. Показов 668. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть таблица с полями key0 INTEGER (PK), service VARCHAR(15), username VARCHAR(15), userpassword VARCHAR(15). Хочу выполнить поиск (выборку, реализовано в качестве живого поиска) по всей таблице. Если искать числовые значения, то всё ок, но если искать символы (кириллица), то ругается на то, что не тот тип данных. Можно ли как-то это осуществить? Поможет ли метод CAST?
Ниже запрос (уже сформированный в SQL.Text):
SQL
1
2
3
4
SELECT * FROM test_table WHERE id LIKE UPPER('%а%') OR
 UPPER(service) LIKE UPPER('%а%') OR
 UPPER(username) LIKE UPPER('%а%') OR
 UPPER(userpassword) LIKE UPPER('%а%');
('%а%') - "а"это кириллица.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.02.2024, 01:10
Ответы с готовыми решениями:

Firebird + Delphi 7. Вывод всех данных из поля
Добрый день, у меня такая просьба. Как создать список всех данных одного поля? что бы в Listbox...

Поиск информации по запросу для всех типов полей
Здравствуйте дорогие форумчане. задался вопросом про поиск информации. делал фильтр на...

Поиск максимума среди всех локадьных минимумов
Элемент двухмерного массива называется локальным минимумом, если он строго меньше всех имеющихся у...

Матрица n x m, поиск определенного числа среди всех строк
Итак, сел писать код, суть которого заключена в том, чтобы создать матрицу n на m, и затем среди...

Поиск среди всех массивов такого, у которого значение максимального элемента наибольшее
Дано L вещественных одномерных массивов X1, X2, …, XL, каждый размером N. Составить программу...

17
Модератор
9270 / 6048 / 2380
Регистрация: 21.01.2014
Сообщений: 25,828
Записей в блоге: 3
29.02.2024, 06:48 2
А поле id тоже текстовое? Если нет - то вот Вам и несовпадение типов
0
0 / 0 / 0
Регистрация: 30.06.2022
Сообщений: 47
29.02.2024, 07:58  [ТС] 3
ID это key0, забыл сменить имя field, т.е. это цифровое поле, можно ли как то в запросе игнорировать числовые поля, если строка поиска содержит не цифровые символы?

Добавлено через 2 минуты
БД в WIN1251.
0
5787 / 4529 / 1431
Регистрация: 14.04.2014
Сообщений: 20,160
Записей в блоге: 20
29.02.2024, 09:38 4
запрос сам не делает ничего, соответственно и ничего "игнорировать" не может
какой запрос составили, тот и выполняется
а вы, если знаете тип поля, вполне можете не включать его в запрос

чтобы проверить, что происходит
вам достаточно провести два теста вообще без программирования, просто запустив в IBExpert
SQL
1
SELECT * FROM TABLE WHERE SomeNumericField LIKE UPPER('%и%')
SQL
1
SELECT * FROM TABLE WHERE UPPER(SomeTextField) LIKE UPPER('%и%')
оба выражения на мой взгляд вполне верны
если это так, то ваша ошибка должна относиться к какому-то конкретному полю и типу
найдите его, а потом уже можно думать
1
0 / 0 / 0
Регистрация: 30.06.2022
Сообщений: 47
29.02.2024, 10:21  [ТС] 5
Если выполнить:
SQL
1
SELECT * FROM TEST_TABLE WHERE id LIKE UPPER('%f%');
То всё ок, т.е. dataset будет пустым, т.к. искомые значения не найдены.

Если выполнить:
SQL
1
SELECT * FROM TEST_TABLE WHERE id LIKE UPPER('%а%');
То выдаёт ошибку:
Поиск среди всех полей в FireBird на Delphi


id имеет Field Type - Integer.
0
5787 / 4529 / 1431
Регистрация: 14.04.2014
Сообщений: 20,160
Записей в блоге: 20
29.02.2024, 11:18 6
Лучший ответ Сообщение было отмечено DobryaKaktus как решение

Решение

1. пробовать кастовать id
2. пробовать upper ('%a%' collate <тут название коллейта>)
1
0 / 0 / 0
Регистрация: 30.06.2022
Сообщений: 47
29.02.2024, 13:06  [ТС] 7
Цитата Сообщение от krapotkin Посмотреть сообщение
пробовать upper ('%a%' collate <тут название коллейта>)
На этот запрос уже не ругается:
SQL
1
SELECT * FROM test_table WHERE id LIKE UPPER('%a%' COLLATE PXW_CYRL);
Ещё одна проблема, если ввести такой запрос:
SQL
1
SELECT * FROM test_table WHERE UPPER(service) LIKE UPPER('%П%');
или такой
SQL
1
SELECT * FROM test_table WHERE UPPER(service) LIKE UPPER('%п%');
Найдётся строка со словом "Привет".

А если ввести такой:
SQL
1
SELECT * FROM test_table WHERE UPPER(service) LIKE UPPER('%привет%');
SQL
1
SELECT * FROM test_table WHERE UPPER(service) LIKE UPPER('%Привет%');
То ничего не находит, подскажите почему?
0
5787 / 4529 / 1431
Регистрация: 14.04.2014
Сообщений: 20,160
Записей в блоге: 20
29.02.2024, 13:20 8
Лучший ответ Сообщение было отмечено DobryaKaktus как решение

Решение

думаю нужно вдумчиво изучить
на странице
https://www.ibase.ru/ibrusfaq/
Ctrl+F PXW_CYRL

а потом взять и перевести базу в UTF-8 ))
1
0 / 0 / 0
Регистрация: 30.06.2022
Сообщений: 47
29.02.2024, 15:07  [ТС] 9
Прочёл статью.
Я создал базу в WIN1251, разумеется CHARACTER SET WIN1251 добавляется к объявлению ко всем строковым полям, также WIN1251 не имеет таблицы uppercase. Ок, пробую добавить к одному из полей COLLATE PXW_CYRL:
SQL
1
2
3
4
CREATE TABLE  TABLE  (key0 INTEGER generated BY DEFAULT AS IDENTITY PRIMARY KEY,
 service VARCHAR(15) COLLATE PXW_CYRL,
 username VARCHAR(15),
 userpassword VARCHAR(15));
Не создаёт таблицу, ошибка:
Код
Undefined name.
unsuccessful metadata update.
CREATE TABLE TESTCHAR failed.
Dynamic SQL Error.
SQL error code = -204.
COLLATION PXW_CYRL for CHARACTER SET NONE is not defined.
---------------------------------------------------------
Окей, допустим есть таблица в WIN1251, такой запрос тоже не работает:
SQL
1
SELECT * FROM TABLE WHERE UPPER(NAME1 COLLATE PXW_CYRL) = 'А'
Та же ошибка.

Далее создал тестовую таблицу в самом IBExpert:
Поиск среди всех полей в FireBird на Delphi

Как видно, я указал charset win1251 и collate pxw_cyrl.
Так что запрос можно сформировать так:
SQL
1
SELECT * FROM new_table WHERE FIELD1 LIKE UPPER('%п%');
Так строка находится, но если изменить на ('%пр%')/('%приВет%')/('%Привет%'), то строки не находятся, т.е. типо работает только 1 буква в поиске...
0
0 / 0 / 0
Регистрация: 30.06.2022
Сообщений: 47
29.02.2024, 18:19  [ТС] 10
По поводу UTF8, я создал БД в UTF8, как нормализовать запрос:
SQL
1
2
3
4
CREATE TABLE  TABLE  (key0 INTEGER generated BY DEFAULT AS IDENTITY PRIMARY KEY,
 service VARCHAR(15),
 username VARCHAR(15),
 userpassword VARCHAR(15));
Чтобы было без всяких сюрпризов в кодировках ? плиз подскажите

Добавлено через 2 часа 44 минуты
Создал таблицу в UTF8.
Теперь осталось составить нормальный запрос:
SQL
1
SELECT * FROM test_table WHERE id LIKE UPPER('%а%');
Ругается на кириллицу, какой коллейт использовать?
0
115 / 99 / 16
Регистрация: 23.05.2015
Сообщений: 563
29.02.2024, 18:45 11
Цитата Сообщение от DobryaKaktus Посмотреть сообщение
Ругается на кириллицу, какой коллейт использовать?
Цитата Сообщение от krapotkin Посмотреть сообщение
а потом взять и перевести базу в UTF-8 ))
Такой вариант не рассматриваете?
И проблемы как не бывало..
0
0 / 0 / 0
Регистрация: 30.06.2022
Сообщений: 47
29.02.2024, 19:24  [ТС] 12
В смысле? Я ведь сейчас уже создал заново, и базу и таблицы в utf8.
0
115 / 99 / 16
Регистрация: 23.05.2015
Сообщений: 563
01.03.2024, 11:38 13
DobryaKaktus, А вы что, в поле id что русские буквы используете вместо цифр?

Добавлено через 31 минуту
Если нет, то почему вы пытаетесь искать буквы, там где цифры?
SQL
1
SELECT * FROM test_table WHERE id LIKE UPPER('%а%');
0
0 / 0 / 0
Регистрация: 30.06.2022
Сообщений: 47
01.03.2024, 12:44  [ТС] 14
Цитата Сообщение от SeGun Посмотреть сообщение
Если нет, то почему вы пытаетесь искать буквы, там где цифры?
У меня общее поле поиска для всех столбцов, и например варианты поиска, (все, столбец1(число), столбец2 и т.д), я не хочу ограничивать поле методом NumbersOnly.
0
5787 / 4529 / 1431
Регистрация: 14.04.2014
Сообщений: 20,160
Записей в блоге: 20
01.03.2024, 15:48 15
Лучший ответ Сообщение было отмечено DobryaKaktus как решение

Решение

у нас в детском саду тоже были общие туалеты, но сейчас везде хожу в раздельные
я в первом ответе написал про то, что если вы хотите иметь ID как строку по своим правилам, надо явно кастовать

как написано везде, поиск сильно зависит от COLLATE
его можно указать прямо в описании поля либо в SELECT

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE TABLE1 (
    ID  INTEGER,
    F1  VARCHAR(50),
    F2  VARCHAR(50)
);
CREATE TABLE TABLE2 (
    ID  INTEGER,
    F1  VARCHAR(50) COLLATE UNICODE_CI,
    F2  VARCHAR(50) COLLATE UNICODE_CI
);
 
INSERT INTO table1 (id, f1, f2) VALUES(1, 'Василий', 'Петров');
INSERT INTO table1 (id, f1, f2) VALUES(10, 'Ольга13', 'Иванова');
INSERT INTO table1 (id, f1, f2) VALUES(121314, 'Василиса', 'Кузнецова');
 
INSERT INTO table2 (id, f1, f2) VALUES(1, 'Василий', 'Петров');
INSERT INTO table2 (id, f1, f2) VALUES(10, 'Ольга13', 'Иванова');
INSERT INTO table2 (id, f1, f2) VALUES(121314, 'Василиса', 'Кузнецова');
IDF1F2
1ВасилийПетров
10Ольга13Иванова
121314ВасилисаКузнецова

проведите селект на table1 и table2.
сравните
SQL
1
2
3
4
5
SELECT * FROM table2 t
WHERE
CAST(t.id AS VARCHAR(200))  LIKE '%васи%'
OR t.f1 LIKE '%васи%'
OR t.f2 LIKE '%васи%'
на table1 - пусто. на table2 - результат

теперь другой
SQL
1
2
3
4
5
SELECT * FROM table1 t
WHERE
CAST(t.id AS VARCHAR(200))  LIKE '%васи%'
OR t.f1 COLLATE UNICODE_CI LIKE '%васи%'
OR t.f2 COLLATE UNICODE_CI LIKE '%васи%'
сейчас на table1 и table2 - результат одинаковый

замените %васи% на %13%
оба запроса на обеих таблах будут давать одинаковый результат, потому что 13 не отличается в кодировках и коллейтах

Добавлено через 1 минуту
если что, это FB3. База ессн UTF-8
1
173 / 23 / 7
Регистрация: 14.04.2019
Сообщений: 181
02.03.2024, 13:24 16
А может быть вам вообще без запросов проще будет? Например, делать проверку в OnFilterRecord?
0
5787 / 4529 / 1431
Регистрация: 14.04.2014
Сообщений: 20,160
Записей в блоге: 20
02.03.2024, 13:57 17
отличное решение - закачать к себе гугл, а потом отфильтровать найденное)
хотя для нескольких записей может иметь смысл
0
0 / 0 / 0
Регистрация: 30.06.2022
Сообщений: 47
02.03.2024, 20:22  [ТС] 18
Цитата Сообщение от krapotkin Посмотреть сообщение
я в первом ответе написал про то, что если вы хотите иметь ID как строку по своим правилам, надо явно кастовать
До этого я кастовал, но неправильно.
Цитата Сообщение от krapotkin Посмотреть сообщение
как написано везде, поиск сильно зависит от COLLATE
Я принцип понял, также я понял почему возникали другие ошибки, в том числе и с win1251.
Спасибо.
0
02.03.2024, 20:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.03.2024, 20:22
Помогаю со студенческими работами здесь

Имена полей русскими буквами в firebird
Доброго вечера всем! кто пользовался Firebird или MySql. Как сделать псевдонимы столбцов русскими...

Дан каталог книг, реализовать показ всех книг и поиск по каждому из полей
Дан каталог книг. Про книгу известно: уникальный номер, автор, название, год издания. Реализовать...

Дан каталог книг. Реализовать показ всех книг на экран и поиск по каждому из полей
Задание: Дан каталог книг. Про книгу известно: уникальный номер, автор, название, год издания....

Firebird. Получение имён полей и типов данных
cur.execute(&quot;CREATE TABLE MYTABLE (ID INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, FYEAR...

Firebird как написать запрос со множеством полей
Как построить запрос у которого число полей зависит от содержимого другой таблицы (т.е....

Псевдонимы полей в Firebird сделать русскими буквами
Всем привет. БД firebird можно ли псенвдонимы полей делать русскими буквами select accounts AS...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru