|
|
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
Всем доброго времени суток. Наткнулся давеча на интересную ситуацию. У меня есть несколько таблиц почти одинаковой структуры. В каждой из них есть одно и то же поле типа Boolean. Соответственно, в Дельфях я обрабатываю это поле как AsBoolean и до недавнего времени проблем не испытывал. До тех пор, пока мне не понадобилось написать представление, где идет выборка однотипных полей из трех таблиц, соединенных Union. Как только я попытался обработать это представление в Дельфях, мне тут же вылезла ошибка, что Дельфи не могут обработать это поле как Boolean. Пришлось работать с ним как AsInteger, сравнивая с 0 или 1. Эксперименты показали, что если во вьюхе закомментировать две любых таблицы и оставить выборку только из одной, проблема пропадает. Отсюда вопрос - за неимением в MySQL конструкции Cast [поле] As Boolean можно ли как-то скорректировать эту выборку? Я, конечно, могу выкрутиться, но в нескольких местах программы мне было бы очень удобно использовать это поле как булевское. Есть какие-нибудь идеи? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 07:11 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
Код: sql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 07:49 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
Разве Дельфи считает MySQL-вский Bit булевским полем? Вроде бы для MySQL Boolean - это TinyInt(1)? Но я попробую, спасибо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 07:52 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
Bit не катит однозначно. Он не воспринимается дельфями как Boolean, даже в гридах по умолчанию вместо галочки просто 0 или 1 рисуется. И AsBoolean, соответственно, не работает ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 08:12 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
S_Gur, наверное всё это зависит от того, какими компонентами доступа к БД вы пользуетесь. Вы какими пользуетесь? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 09:56 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
UniDAC-овскими. И - нет, это не зависит от компонент. Эксперименты показали, что при селекте из одной таблицы поле в датасете получает тип ftBoolean, а при селекте с юнионами - ftLargeInt. Это приколы MySQL ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 13:08 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
S_GurUniDAC-овскими. И - нет, это не зависит от компонент. Эксперименты показали, что при селекте из одной таблицы поле в датасете получает тип ftBoolean, а при селекте с юнионами - ftLargeInt. Это приколы MySQL Первый SELECT в UNION определяет имена и типы полей ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 14:03 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
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.(если типы выбираемых колонок не соответствует друг-другу, то результирующая колонка получает общий тип) Отсюда вывод - либо вы объединяете разные типы полей, либо дак не может поднять типы полей из сложного селекта ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 14:11 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
а fieldbyname('').Value, т.е. без явного приведения к типу - то же падает? Порой выручало, в юнидаках именно, но порой и наоборот усугубляло. Понимаю, что не совсем по делу, по сколько Вы сказали, что было бы удобно использовать - но я фактически отказался от boolean из за таких вот приколов, то компонент, то СУБД... То дэвекспресс в неадеквате, то вьюшка , то приведение к типу... smallint фарева ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 14:14 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
_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`" или разные типы полей? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 17:54 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
kill_zdmа fieldbyname('').Value, т.е. без явного приведения к типу - то же падает? Порой выручало, в юнидаках именно, но порой и наоборот усугубляло. Падает только на обращении к этому полю как к Boolean. Value и AsInteger работает без проблем. Я тут уже писал: если я делаю селект только из одной таблицы, то при открытии набора данных поле получает тип ftBoolean, а если подключаю хоть один Union, то уже ftLargeInt. Видимо - неизвестно почему - MySQL считает, что поля всех трех селектов разнотипные и приводит их к общему типу, а и Cast и Convert могут работать только с двумя целочисленными типами - Signed и Unsigned. Вопрос в том, почему он это делает - поля во всех таблицах абсолютно одинаковые ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 18:00 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
S_GurЕсть какие-нибудь идеи?Переходи везде с Boolean на Integer. Надежней будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 18:09 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
rgreat, этот вариант от меня никогда не уйдет. Лишних телодвижений много будет, пока хочу поиграться с Boolean, может, что-нибудь накопаю. Ситуация уж больно абсурдная ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 18:22 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
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 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 18:26 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
s62, я это знаю. И что? В чем проблема? TinyInt(1) прекрасно преобразовывается дельфовыми датасетами в Boolean, Int или LargeInt, естественно, нет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 18:29 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
S_Gur, Можно еще извратиться и переопределить TIntegerField добвив туда function GetAsBoolean: Boolean; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 18:41 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
rgreat, можно, но очень не хочется перестраивать программу под глюки MySQL. В данном конкретном случае я обошелся переработкой структуры, но на будущее хотелось бы понимать, можно ли что-то сделать на уровне базы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 20:15 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
S_Gurна будущее хотелось бы понимать, можно ли что-то сделать на уровне базыНе использовать типы данных у которых проблемы с совместимостью. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 20:28 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
rgreatS_Gurна будущее хотелось бы понимать, можно ли что-то сделать на уровне базыНе использовать типы данных у которых проблемы с совместимостью. Нет никаких проблем с совместимостью. Есть конкретный глюк MySQL, который, почему-то не проверив типы полей в таблицах, ни с того ни с сего взялся за приведение типов. А уж выполняет он вышеописанное приведение правильно и строго в рамках своих возможностей. Хочется надеяться, что в следующих версиях эта проблема будет исправлена ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 20:38 |
|
||
|
MySQL, Boolean и Union
|
|||
|---|---|---|---|
|
#18+
S_GurНет никаких проблем с совместимостью. Есть конкретный глюк MySQL, который, почему-то не проверив типы полей в таблицах, ни с того ни с сего взялся за приведение типов. А уж выполняет он вышеописанное приведение правильно и строго в рамках своих возможностей. Хочется надеяться, что в следующих версиях эта проблема будет исправлена http://lurkmore.to/Взаимоисключающие_параграфы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2019, 20:47 |
|
||
|
|

start [/forum/topic.php?fid=58&fpage=62&tid=2039021]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
37ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
| others: | 209ms |
| total: | 332ms |

| 0 / 0 |
