powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Firebird 3.0 + VFP9 + поля UUID(GUID)
16 сообщений из 16, страница 1 из 1
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916579
Sergej_S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Жил-не тужил, пока БД была MSSQL. Ключевые поля типа были типа uniqueidentifier, они автоматом преобразовывались на стороне фокса в Char(36).

Пытаюсь безуспешно перейти на Firebird. Поставил драйвер Firebird ODBC.
В FireBird типа uniqueidentifier нет, вместо него рекомендуют CHAR(16) в кодировке OCTETS (hex-строка).

Я и в строках плаваю и в Firebird, если кто-то рубит в этом, буду признателен.

Создаем таблицу в Firebird:
Код: sql
1.
2.
3.
CREATE TABLE MyTable (id_ CHAR(16) CHARACTER SET OCTETS NOT NULL);

INSERT into MyTable (id_) VALUES (gen_uuid())


вставилось 37314641-4431-3546-2D44-3236422D3434


Из VFP, так работает, 1 запись вытягивается:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
TEXT TO cCmd TEXTMERGE NOSHOW PRETEXT 7			
	SELECT id_ FROM MyTable
ENDTEXT

SQLEXEC(nMyConnection, cCmd, 'MyCursor')

?id_            && Выдаёт 0h37314641443135462D443236422D3434, т.е. 16-ричную строку.
?VARTYPE(id_) + TRAN(LEN(id))  && Выдаёт Q 16, т.е. Varbinary(16), что имхо правильно.




Так тоже работает (x' - префикс Fb для binary, как в фоксе 0h):
Код: sql
1.
2.
3.
4.
TEXT TO cCmd TEXTMERGE NOSHOW PRETEXT 7			
	SELECT id_, KodTip, NazTip FROM MyTable
	WHERE id_ = x'37314641443135462D443236422D3434'	
ENDTEXT



Но мне надо значение id_ передавать через параметр:
Код: sql
1.
2.
3.
4.
5.
6.
7.
qId = 0h37314641443135462D443236422D3434
?VARTYPE(qId) + TRAN(LEN(qId))  && Выдаёт те же Q 16, т.е. Varbinary(16).

TEXT TO cCmd TEXTMERGE NOSHOW PRETEXT 7			
	SELECT id_, KodTip, NazTip FROM MyTable
	WHERE id_ = ?qId
ENDTEXT



курсор приходит пустым, трассировка на Firebird показывает входящий запрос:
SELECT id_ FROM MyTable WHERE id_ = ?
param0 = varchar(16), ""
0 records fetched

Не понимаю, почему Varbinary фокса переходит в Varchar (пустой) на сервере и как с этим бороться? М.б. надо как-то ODBC указать нужную трансляцию типов VFP-FB? Как?
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916613
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй так
Код: sql
1.
2.
3.
4.
5.
6.
lcId = trans(qId)

TEXT TO cCmd TEXTMERGE NOSHOW PRETEXT 7			
	SELECT id_, KodTip, NazTip FROM MyTable
	WHERE id_ = ?lcId
ENDTEXT


или так
Код: sql
1.
2.
3.
4.
TEXT TO cCmd TEXTMERGE NOSHOW PRETEXT 7			
	SELECT id_, KodTip, NazTip FROM MyTable
	WHERE id_ = x'<<trans(qId)>>'
ENDTEXT
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916670
Sergej_S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, оператавно, спасибо. Я так уже пробовал, работает, но мне надо научаться значение id_ передавать через параметр [?] ибо основная работа идет через курсорадаптер, а там команды CAD.DeleteCmd, etc формируются автоматически из CAD.KeyFieldList. Очень хотелось бы это сохранить. А проблема в CAD такая же.

Pass-through метод я привел для упрощения вопроса. Решу здесь, решу и в CAD.
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916674
Sergey Sizov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergej_S,
попробуйте так:
Код: sql
1.
2.
3.
4.
TEXT TO cCmd TEXTMERGE NOSHOW PRETEXT 7			
	SELECT id_, KodTip, NazTip FROM MyTable
	WHERE id_ = x?trans(qId)
ENDTEXT
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916678
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergej_S
мне надо научаться значение id_ передавать через параметр [?]

Мой первый вариант был с параметром.
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916685
Sergey Sizov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Sergej_S
мне надо научаться значение id_ передавать через параметр [?]

Мой первый вариант был с параметром.
И в результате на сервере получалось
Код: sql
1.
WHERE id_ = '37314641443135462D443236422D3434'


а надо
Код: sql
1.
WHERE id_ = x'37314641443135462D443236422D3434'
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916691
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Погуглил. У FB есть UUID_TO_CHAR() и CHAR_TO_UUID() . Можно с их помощью конвертировать в строку и обратно чтобы фокс работал со строкой.

PS FB не разу не использовал
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916695
Sergey Sizov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Погуглил. У FB есть UUID_TO_CHAR() и CHAR_TO_UUID() . Можно с их помощью конвертировать в строку и обратно чтобы фокс работал со строкой.
То есть в нашем случае напрашивается
Код: sql
1.
WHERE id_ = char_to_uuid(?qId)



PS FB не разу не использовалТака ж фигня :)
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916712
Sergej_S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T

Мой первый вариант был с параметром.


Сорри, пропустил.
Код: sql
1.
2.
3.
4.
5.
6.
lcId = trans(qId)

TEXT TO cCmd TEXTMERGE NOSHOW PRETEXT 7			
	SELECT id_, KodTip, NazTip FROM MyTable
	WHERE id_ = ?lcId
ENDTEXT



выдает 0 строк, т.к. на сервер приходит: param0 = varchar(16), "3731464144313546", т.е. обрезанным до 16 симв.
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916791
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey Sizov
Dima T
Погуглил. У FB есть UUID_TO_CHAR() и CHAR_TO_UUID() . Можно с их помощью конвертировать в строку и обратно чтобы фокс работал со строкой.
То есть в нашем случае напрашивается
Код: sql
1.
WHERE id_ = char_to_uuid(?qId)


Не совсем так. qId это бинарные данные, их надо предварительно преобразовать в строку.
Т.е. изначально получаем из БД так
Код: sql
1.
2.
3.
TEXT TO cCmd TEXTMERGE NOSHOW PRETEXT 7			
	SELECT UUID_TO_CHAR(id_) as cId FROM MyTable
ENDTEXT


а дальше
Код: sql
1.
WHERE id_ = char_to_uuid(?cId)
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916810
Sergej_S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey Sizov

Код: sql
1.
WHERE id_ = char_to_uuid(?qId)




Как и сказал Dima T, не катит:
Connectivity error: [ODBC Firebird Driver][Firebird]expression evaluation not supported
Human readable UUID argument for CHAR_TO_UUID must be of exact length 36

Сейчас еще остальные варианты от Dima T попробую.
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916823
Sergej_S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
Код: sql
1.
2.
3.
4.
5.
TEXT TO cCmd TEXTMERGE NOSHOW PRETEXT 7			
	SELECT UUID_TO_CHAR(id_) as cId FROM MyTable
ENDTEXT
-- и дальше
WHERE id_ = char_to_uuid(?cId)



наверное имелось в виду
Код: sql
1.
2.
3.
4.
5.
TEXT TO cCmd TEXTMERGE NOSHOW PRETEXT 7			
	SELECT UUID_TO_CHAR(id_) as cId FROM MyTable
ENDTEXT
-- и дальше
WHERE cId = ?lcId     /* где на фоксе было lcId = trans(qId)*/


но Firebird не видит поле cId. Я не помню, на mssql такое м.б. и прокатывает, но это не столь важно, т.к. из CAD все-равно не получится это вычисляемое поле cId исользовать как ключ.
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916839
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergej_S
Код: sql
1.
2.
-- и дальше
WHERE cId = ?lcId     /* где на фоксе было lcId = trans(qId)*/


но Firebird не видит поле cId.

Firebird не должен видеть cId, его только фокс будет видеть. Firebird работает с id_

Идея в том что ты получаешь ID от сервера сконвертированным в строку
Код: sql
1.
SELECT UUID_TO_CHAR(id_) as cId FROM MyTable


т.е. конвертация бинарного id_ в строковый cId и далее в фоксе работаешь как со строкой
Код: sql
1.
lcMyId = MyTable.cId


при передаче как параметра обратная конвертация внутри запроса
Код: sql
1.
select * from MyTable where id_ = char_to_uuid(?lcMyId)


Sergej_S
Я не помню, на mssql такое м.б. и прокатывает, но это не столь важно, т.к. из CAD все-равно не получится это вычисляемое поле cId исользовать как ключ.

Про это я не подумал, надо проверять, может проглотит. С MSSQL такой проблемы нет, т.к. он выдает GUID`ы как строки и по сути сам делает то, что я выше написал. Поспрашивай в форуме по FB: может как-то можно переключить драйвер или сервер чтобы он выдавал GUID`ы как строки, а не как бинарники.
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39916843
Sergej_S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИдея в том что ты получаешь ID от сервера сконвертированным в строку
Код: sql
1.
SELECT UUID_TO_CHAR(id_) as cId FROM MyTable


т.е. конвертация бинарного id_ в строковый cId и далее в фоксе работаешь как со строкой

Ну это все строки вытянутся на фокс, WHERE в запрос на сервер не попадает.

Поспрашиваю на ветке Firebird. А с Postgree кто-то заботал?
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39919236
Sergej_S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, я вроде разобрался. Докладываю.

Итак, на Firebird:
Код: sql
1.
2.
CREATE TABLE Tip3 (id_ CHAR(16) CHARACTER SET OCTETS NOT NULL);
INSERT into Tip3 (id_) VALUES (gen_uuid();



Я дико извиняюсь, что ввел общественность в заблуждение: поле id_ по по-дефолту переходит в фокс не как Varbinary [Q(16)], а как Char [C(16)]. И в курсорадаптере и в pass-through. Не понимаю, как я так лажанулся, наверное d CAD.CursorSchema прописал.

Итак, на стороне фокса эти 16-битные id_ имеют вид кракозябл, включая управляющие ACSCII символы с кодом < 32. Сделаем всякие преобразования:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SQLEXEC(gnCH, 'SELECT TOP 1 id_ FROM Tip3', 'MyCursor')

SELECT MyCursor

cId16 = id_	
* C(16): chr(36)+&#184;&#711;&#223;‘&#201;@T—&#144;&#197;W&&#281;R+chr(9)  сорри, иначе тут разметку ломает 

cId32 = STRCONV(id_, 15)
* C(32): 278F8EDF91C940549790C55726E65209

cId36 = LEFT(cId32, 8) + '-' + SUBSTR(cId32, 9,4) + '-' + SUBSTR(cId32, 13,4) ; 
        + '-' +  SUBSTR(cId32, 17,4) + '-' +  SUBSTR(cId32, 21) 
* для красоты: C(36): 278F8EDF-91C9-4054-9790-C55726E65209

qId16 = CREATEBINARY(id_)
* Q(16): 0h278F8EDF91C940549790C55726E65209


? TRANSFORM(qId16)	
* 278F8EDF91C940549790C55726E65209, т.е. =  cId32 
...
Рейтинг: 0 / 0
Firebird 3.0 + VFP9 + поля UUID(GUID)
    #39919242
Sergej_S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Теперь вытянем ту же строку.

Самый очевидный вариант не годится, т.к. если в cId16 будет символ кавычек или вопр.знак, то вылетит ошибка.
Код: sql
1.
cCmd = "SELECT * FROM Tip3 where id_ = '" + cId16 + "'"  



Этот выдаст 0 строк. Трассировка на сервере показывает, что приходит пустой ("") параметр, видимо из-за несоответствия varbinary и char:
Код: sql
1.
cCmd = "SELECT * FROM Tip3 where id_ = ?qId16" && 



Это работает. Но думаю, что стоит искать по индекcному полю id_, а не по его функции
Код: sql
1.
cCmd = "SELECT * FROM Tip3	where uuid_to_char(id_) = '" + cId36 + "'" 




Теперь imho правильные варианты:

Код: powershell
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
cCmd = 'SELECT * FROM Tip3 WHERE id_ = ?cId16'

cCmd = 'SELECT * FROM Tip3 where id_ = ?STRCONV(TRANSFORM(qId16), 16)'  

cCmd = "SELECT * FROM Tip3 where id_ = x'" + TRANSFORM(qId16) + "'"   && меняем hex-префикса 0h (VFP) на x' ' (Firebird)

cCmd = "SELECT * FROM Tip3 where id_ = ?STRCONV(cId32, 16)"   && StrConv переводит в cId16


IF SQLEXEC(gnCH, cCmd, 'MyCursor2') < 0
	AERROR(aSqlErr)
	MESSAGEBOX(aSqlErr(2))
	RETURN 
ENDIF 
SELECT MyCursor2
BROWSE




Про CAD.
В CAD.CursorSchema для id_ пишу: 'id_ C(16) NOCPTRANS'. Хотя и без NOCPTRANS вроде работает, и вообще без определения CursorSchema.
Поскольку в CAD запросы с параметрами (child-таблицы) у меня формируются при помощи параметров (ч/з вопр.знак), то проблем нет.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Firebird 3.0 + VFP9 + поля UUID(GUID)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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