Как установить GUID в качестве параметров запроса ADO из Delphi?
Вопрос
MS Access допускает использование GUID числового типа (по-немецки он называется «Replikations-ID», поэтому я думаю, что по-английски это будет «идентификатор репликации»), который хранится в базе данных в виде 16-байтового двоичного поля.
Я нашел, как получить доступ к этим полям в Delphi с помощью ТАДОЗапрос/ТАДОТаблица с использованием
(TheQuery.FieldByName('SomeGuidField') as TGUIDField).AsGuid;
Но теперь я хочу выполнить SQL-запрос следующим образом:
SELECT * FROM SomeTable WHERE SomeGuidField=:AGuid
Я попробовал установить TADOQuery.SQL свойство к приведенному выше утверждению, но не нашел способа фактически установить AGuid
параметр, позволяющий открыть запрос.Что бы я ни пробовал, это приводило к ошибке (ADO/COM).
Не указано значение для одного или нескольких обязательных параметров.
Например:
TheQuery.ParamByName('AGuid').Value := QuotedString(GuidToStr(AGuid));
TheQuery.Open; // <<== crashes here
Это тоже не работает:
TheQuery.ParamByName('AGuid').Value := GuidToStr(AGuid);
TheQuery.Open; // <<== crashes here
Я посмотрел, как TGuidField(...).AsGuid
работает и обнаружил, что сначала преобразует GUID в строку, а затем строку в вариант (и наоборот).
Это работает нормально, если я всегда генерирую оператор SQL следующим образом:
SELECT * FROM SomeTable WHERE SomeGuidField='<a guid goes here>'
Когда я прохожу это ТАДОЗапрос объект вокруг в программе, я хотел бы изменить только AGuid
-Параметр, позволяющий сохранить независимость большинства методов от фактического SQL-оператора.
Есть ли другой способ установить параметр GUID, кроме как всегда изменять весь оператор SQL?
(Это должен быть GUID, поскольку мне нужен глобальный уникальный идентификатор для синхронизации с другими базами данных на основе MS SQL или MS Access.)
РедактироватьВрадмилович прав, это работает:
TheQuery.ParamByName('AGuid').Value := GuidToStr(AGuid);
TheQuery.Open;
Я не понимаю, почему это не сработало в первый раз, когда я попробовал.
Решение
Это правильный способ установки параметров с помощью ADO.Сообщение, которое вы получаете, скорее всего, связано с опечаткой в некоторых полях (вы получите такое же сообщение, если поле не существует).
Другие советы
Чего стоит, я использую GUID, но сохраняю их в БД в виде строк.
Не следует сохранять их как строки.Вы должны использовать уникальный идентификатор.Две функции, которые нужно использовать, — это GUIDToString и StringToGUID (а не str-ones).
Если вы копируете значения из активного каталога (поставляется как ftVarBytes), вы можете использовать функцию Assign, которая творит чудеса для вас:
QueryIns.Parameters.ParamByName('GUID').Assign(Query.FieldByName('objectGUID'));
Если вы хотите извлечь objectGUID из AD, вам необходимо привести objectGUID к uniqueidentifier:
Query.SQL.Add('select cast(objectGUID as uniqueidentifier) as objectGUID');
Query.SQL.Add('from vwADGroups');
Query.Open;
while not Query.Eof do begin
Index := List.IndexOfName(Query.FieldByName('objectGUID').AsString);
//...
end;
Если вы уверены, что параметр является TGuid, то должно работать следующее:
TGuidField(TheQuery.ParamByName('AGuid')).AsGuid
Хотя это создает GuidToString внутри, так что проблема может быть той же.Стоит попробовать!