Question

MS Access allows the numeric type GUID (in German it's called 'Replikations-ID', so I guess in English that would be 'replication id') which is stored as a 16 byte binary field in the database.

I found how to access these fields in Delphi with TADOQuery/TADOTable using

(TheQuery.FieldByName('SomeGuidField') as TGUIDField).AsGuid;

But now I want to execute an SQL-Query like this:

SELECT * FROM SomeTable WHERE SomeGuidField=:AGuid

I tried setting a TADOQuery.SQL property to the above statement, but found no way to actually set the AGuid parameter such that the query can be opened. Whatever I tried resulted in the (ADO/COM) error

No value given for one or more required parameters

For example:

TheQuery.ParamByName('AGuid').Value := QuotedString(GuidToStr(AGuid));
TheQuery.Open; // <<== crashes here

This doesn't work either:

TheQuery.ParamByName('AGuid').Value := GuidToStr(AGuid);
TheQuery.Open; // <<== crashes here

I had a look at how TGuidField(...).AsGuid works and found that it first converts the GUID to a string and then the string to a variant (and vice versa).

It works fine, if I always generate the SQL-Statement like this:

SELECT * FROM SomeTable WHERE SomeGuidField='<a guid goes here>'

As I am passing that TADOQuery object around in the program I would like to only change the AGuid-Parameter to keep most methods agnostic on the actual SQL-Statement.

Is there any other way to set a GUID-Parameter than always change the complete SQL-Statement?

(It must be a GUID because I need a globally unique identifier to synchronize with other databases which are MS SQL or MS Access based.)

Edit vradmilovic is right, this works:

TheQuery.ParamByName('AGuid').Value := GuidToStr(AGuid);
TheQuery.Open;

I don't understand why it didn't work the first time I tried it.

Was it helpful?

Solution

That's correct way to set parameters with ADO. The message you get is most probably due to typo with some of fields (you get same message if field does not exist).

OTHER TIPS

For what is worth I'm using GUIDs but I save them in DB as strings.

You should not save them as strings. You should use uniqueidentifier. The two functions to use are GUIDToString and StringToGUID (not the str-ones).

If you copy values from the active directory (comes as ftVarBytes) you can use assign which does the magic for you:

QueryIns.Parameters.ParamByName('GUID').Assign(Query.FieldByName('objectGUID'));

If you want to extract the objectGUID from AD you need to cast the objectGUID to 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;

If you are sure the parameter is a TGuid, then the following should work :

TGuidField(TheQuery.ParamByName('AGuid')).AsGuid

Although this does a GuidToString internally, so the problem maybe the same. Worth a try!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top