Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / MySQL, Boolean и Union / 20 сообщений из 20, страница 1 из 1
23.09.2019, 07:11
    #39865368
S_Gur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
Всем доброго времени суток. Наткнулся давеча на интересную ситуацию. У меня есть несколько таблиц почти одинаковой структуры. В каждой из них есть одно и то же поле типа Boolean. Соответственно, в Дельфях я обрабатываю это поле как AsBoolean и до недавнего времени проблем не испытывал. До тех пор, пока мне не понадобилось написать представление, где идет выборка однотипных полей из трех таблиц, соединенных Union. Как только я попытался обработать это представление в Дельфях, мне тут же вылезла ошибка, что Дельфи не могут обработать это поле как Boolean. Пришлось работать с ним как AsInteger, сравнивая с 0 или 1. Эксперименты показали, что если во вьюхе закомментировать две любых таблицы и оставить выборку только из одной, проблема пропадает. Отсюда вопрос - за неимением в MySQL конструкции Cast [поле] As Boolean можно ли как-то скорректировать эту выборку? Я, конечно, могу выкрутиться, но в нескольких местах программы мне было бы очень удобно использовать это поле как булевское. Есть какие-нибудь идеи?
...
Рейтинг: 0 / 0
23.09.2019, 07:49
    #39865372
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
Код: sql
1.
Cast [поле] As bit
...
Рейтинг: 0 / 0
23.09.2019, 07:52
    #39865373
S_Gur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
Разве Дельфи считает MySQL-вский Bit булевским полем? Вроде бы для MySQL Boolean - это TinyInt(1)? Но я попробую, спасибо
...
Рейтинг: 0 / 0
23.09.2019, 08:12
    #39865381
S_Gur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
Bit не катит однозначно. Он не воспринимается дельфями как Boolean, даже в гридах по умолчанию вместо галочки просто 0 или 1 рисуется. И AsBoolean, соответственно, не работает
...
Рейтинг: 0 / 0
23.09.2019, 09:56
    #39865419
s62
s62
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
S_Gur,
наверное всё это зависит от того, какими компонентами доступа к БД вы пользуетесь. Вы какими пользуетесь?
...
Рейтинг: 0 / 0
23.09.2019, 13:08
    #39865578
S_Gur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
UniDAC-овскими. И - нет, это не зависит от компонент. Эксперименты показали, что при селекте из одной таблицы поле в датасете получает тип ftBoolean, а при селекте с юнионами - ftLargeInt. Это приколы MySQL
...
Рейтинг: 0 / 0
23.09.2019, 14:03
    #39865631
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
S_GurUniDAC-овскими. И - нет, это не зависит от компонент. Эксперименты показали, что при селекте из одной таблицы поле в датасете получает тип ftBoolean, а при селекте с юнионами - ftLargeInt. Это приколы MySQL
Первый SELECT в UNION определяет имена и типы полей
...
Рейтинг: 0 / 0
23.09.2019, 14:11
    #39865639
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
S_GurЭто приколы MySQВ MySQL нет типа BOOLEAN. Вообще. А то, что есть - это алиас для типа TINYINT(1). Т.е. однобайтовое число из одной цифры.

То, что какой-то дак к такому и только такому полю позволяет обращаться как AsBoolean - так это проблемы конкретного дака.

Правило преобразования типов у MySQL простые
https://dev.mysql.com/doc/refman/8.0/en/union.html If the data types of corresponding SELECT columns do not match, the types and lengths of the columns in the UNION result take into account the values retrieved by all of the SELECT statements.(если типы выбираемых колонок не соответствует друг-другу, то результирующая колонка получает общий тип)

Отсюда вывод - либо вы объединяете разные типы полей, либо дак не может поднять типы полей из сложного селекта
...
Рейтинг: 0 / 0
23.09.2019, 14:14
    #39865643
kill_zdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
а fieldbyname('').Value, т.е. без явного приведения к типу - то же падает? Порой выручало, в юнидаках именно, но порой и наоборот усугубляло.


Понимаю, что не совсем по делу, по сколько Вы сказали, что было бы удобно использовать - но я фактически отказался от boolean из за таких вот приколов, то компонент, то СУБД... То дэвекспресс в неадеквате, то вьюшка , то приведение к типу... smallint фарева )))
...
Рейтинг: 0 / 0
23.09.2019, 17:54
    #39865815
S_Gur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
_Vasilisk_S_GurЭто приколы MySQВ MySQL нет типа BOOLEAN. Вообще. А то, что есть - это алиас для типа TINYINT(1). Т.е. однобайтовое число из одной цифры.

То, что какой-то дак к такому и только такому полю позволяет обращаться как AsBoolean - так это проблемы конкретного дака.

Правило преобразования типов у MySQL простые
https://dev.mysql.com/doc/refman/8.0/en/union.html If the data types of corresponding SELECT columns do not match, the types and lengths of the columns in the UNION result take into account the values retrieved by all of the SELECT statements.(если типы выбираемых колонок не соответствует друг-другу, то результирующая колонка получает общий тип)

Отсюда вывод - либо вы объединяете разные типы полей, либо дак не может поднять типы полей из сложного селекта

Очень хороший вывод. Жаль, что скороспелый и неверный

Таблица 1:

Create Table If Not Exists `tbVoucherTypeVPNServiceLinks`
(`biID` BigInt UnSigned Not Null Primary Key Auto_Increment Comment 'Уникальный идентификатор',
`biVoucherTypeID` BigInt UnSigned Default 0 Not Null Comment 'Идентификатор типа ваучера',
`biVPNServiceID` BigInt UnSigned Default 0 Not Null Comment 'Идентификатор услуги VPN',
`vcRemark` VarChar(2000) Default '…' Not Null Comment 'Комментарий',
`bIsDeletable` Boolean Default 0 Not Null Comment 'Признак запрещения удаления записи',
Foreign Key (`biVoucherTypeID`) References `tbVoucherTypes` (`biID`),
Foreign Key (`biVPNServiceID`) References `tbVPNServices` (`biID`))
ENGINE=InnoDB Default CharSet=utf8 Auto_Increment=0 Encryption = 'Y' Comment='Список связок типов ваучеров с услугами VPN';

Таблица 2:

Create Table If Not Exists `tbVoucherTypeEMailServiceLinks`
(`biID` BigInt UnSigned Not Null Primary Key Auto_Increment Comment 'Уникальный идентификатор',
`biVoucherTypeID` BigInt UnSigned Default 0 Not Null Comment 'Идентификатор типа ваучера',
`biEMailServiceID` BigInt UnSigned Default 0 Not Null Comment 'Идентификатор услуги VPN',
`vcRemark` VarChar(2000) Default '…' Not Null Comment 'Комментарий',
`bIsDeletable` Boolean Default 0 Not Null Comment 'Признак запрещения удаления записи',
Foreign Key (`biVoucherTypeID`) References `tbVoucherTypes` (`biID`),
Foreign Key (`biEMailServiceID`) References `tbEMailServices` (`biID`))
ENGINE=InnoDB Default CharSet=utf8 Auto_Increment=0 Encryption = 'Y' Comment='Список связок типов ваучеров с услугами электронной почты';

Таблица 3:

Create Table If Not Exists `tbVoucherTypeFSServiceLinks`
(`biID` BigInt UnSigned Not Null Primary Key Auto_Increment Comment 'Уникальный идентификатор',
`biVoucherTypeID` BigInt UnSigned Default 0 Not Null Comment 'Идентификатор типа ваучера',
`biFSServiceID` BigInt UnSigned Default 0 Not Null Comment 'Идентификатор услуги VPN',
`vcRemark` VarChar(2000) Default '…' Not Null Comment 'Комментарий',
`bIsDeletable` Boolean Default 0 Not Null Comment 'Признак запрещения удаления записи',
Foreign Key (`biVoucherTypeID`) References `tbVoucherTypes` (`biID`),
Foreign Key (`biFSServiceID`) References `tbFSServices` (`biID`))
ENGINE=InnoDB Default CharSet=utf8 Auto_Increment=0 Encryption = 'Y' Comment='Список связок типов ваучеров с услугами файлового хранилища';

Представление:

Create Or Replace View `vwVoucherTypeServiceLinks`

As
Select
A.`biID`,
0 As tiServiceType,
A.`biVoucherTypeID`,
A.`biVPNServiceID` As biServiceID,
A.`vcRemark`,
A.`bIsDeletable`,
B.`vcName` As vcVoucherTypeName,
C.`vcName` As vcServiceName
From
`tbVoucherTypeVPNServiceLinks` A,
`tbVoucherTypes` B,
`tbVPNServices` C
Where
A.`biID` > 0
And B.`biID` = A.`biVoucherTypeID`
And C.`biID` = A.`biVPNServiceID`
Union All
Select
A.`biID`,
1 As tiServiceType,
A.`biVoucherTypeID`,
A.`biEMailServiceID` As `biServiceID`,
A.`vcRemark`,
A.`bIsDeletable`,
B.`vcName` As vcVoucherTypeName,
C.`vcName` As vcServiceName
From
`tbVoucherTypeEMailServiceLinks` A,
`tbVoucherTypes` B,
`tbEMailServices` C
Where
A.`biID` > 0
And B.`biID` = A.`biVoucherTypeID`
And C.`biID` = A.`biEMailServiceID`
Union All
Select
A.`biID`,
2 As tiServiceType,
A.`biVoucherTypeID`,
A.`biFSServiceID` As `biServiceID`,
A.`vcRemark`,
A.`bIsDeletable`,
B.`vcName` As vcVoucherTypeName,
C.`vcName` As vcServiceName
From
`tbVoucherTypeFSServiceLinks` A,
`tbVoucherTypes` B,
`tbFSServices` C
Where
A.`biID` > 0
And B.`biID` = A.`biVoucherTypeID`
And C.`biID` = A.`biFSServiceID`;

Программа валится на поле`bIsDeletable`. И какой из ваших "либо" тут мог сработать? Сложный селект "Select * From `vwVoucherTypeServiceLinks`" или разные типы полей?
...
Рейтинг: 0 / 0
23.09.2019, 18:00
    #39865816
S_Gur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
kill_zdmа fieldbyname('').Value, т.е. без явного приведения к типу - то же падает? Порой выручало, в юнидаках именно, но порой и наоборот усугубляло.

Падает только на обращении к этому полю как к Boolean. Value и AsInteger работает без проблем. Я тут уже писал: если я делаю селект только из одной таблицы, то при открытии набора данных поле получает тип ftBoolean, а если подключаю хоть один Union, то уже ftLargeInt. Видимо - неизвестно почему - MySQL считает, что поля всех трех селектов разнотипные и приводит их к общему типу, а и Cast и Convert могут работать только с двумя целочисленными типами - Signed и Unsigned. Вопрос в том, почему он это делает - поля во всех таблицах абсолютно одинаковые
...
Рейтинг: 0 / 0
23.09.2019, 18:09
    #39865821
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
S_GurЕсть какие-нибудь идеи?Переходи везде с Boolean на Integer.

Надежней будет.
...
Рейтинг: 0 / 0
23.09.2019, 18:22
    #39865832
S_Gur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
rgreat, этот вариант от меня никогда не уйдет. Лишних телодвижений много будет, пока хочу поиграться с Boolean, может, что-нибудь накопаю. Ситуация уж больно абсурдная
...
Рейтинг: 0 / 0
23.09.2019, 18:26
    #39865834
s62
s62
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
rgreatS_GurЕсть какие-нибудь идеи?Переходи везде с Boolean на Integer.

Надежней будет.Так в MySQL, сегодня почитал, нет булевского поля. Есть TINYINT, а типы BOOL и BOOLEAN - это синонимы TINYINT(1). Вот тут приведен пример, когда создается таблица, в запросе create table указан тип BOOL, а фактически создается поле TINYINT(1).
https://dev.mysql.com/doc/refman/8.0/en/other-vendor-data-types.html
...
Рейтинг: 0 / 0
23.09.2019, 18:29
    #39865835
S_Gur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
s62, я это знаю. И что? В чем проблема? TinyInt(1) прекрасно преобразовывается дельфовыми датасетами в Boolean, Int или LargeInt, естественно, нет
...
Рейтинг: 0 / 0
23.09.2019, 18:41
    #39865842
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
S_Gur,

Можно еще извратиться и переопределить TIntegerField добвив туда function GetAsBoolean: Boolean;
...
Рейтинг: 0 / 0
23.09.2019, 20:15
    #39865875
S_Gur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
rgreat, можно, но очень не хочется перестраивать программу под глюки MySQL. В данном конкретном случае я обошелся переработкой структуры, но на будущее хотелось бы понимать, можно ли что-то сделать на уровне базы
...
Рейтинг: 0 / 0
23.09.2019, 20:28
    #39865881
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
S_Gurна будущее хотелось бы понимать, можно ли что-то сделать на уровне базыНе использовать типы данных у которых проблемы с совместимостью.
...
Рейтинг: 0 / 0
23.09.2019, 20:38
    #39865885
S_Gur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
rgreatS_Gurна будущее хотелось бы понимать, можно ли что-то сделать на уровне базыНе использовать типы данных у которых проблемы с совместимостью.

Нет никаких проблем с совместимостью. Есть конкретный глюк MySQL, который, почему-то не проверив типы полей в таблицах, ни с того ни с сего взялся за приведение типов. А уж выполняет он вышеописанное приведение правильно и строго в рамках своих возможностей. Хочется надеяться, что в следующих версиях эта проблема будет исправлена
...
Рейтинг: 0 / 0
23.09.2019, 20:47
    #39865889
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL, Boolean и Union
S_GurНет никаких проблем с совместимостью. Есть конкретный глюк MySQL, который, почему-то не проверив типы полей в таблицах, ни с того ни с сего взялся за приведение типов. А уж выполняет он вышеописанное приведение правильно и строго в рамках своих возможностей. Хочется надеяться, что в следующих версиях эта проблема будет исправлена
http://lurkmore.to/Взаимоисключающие_параграфы
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / MySQL, Boolean и Union / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]