tags:

views:

2608

answers:

5

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 TGuidField(...).AsGuid, but now I want to execute an SQL-Query like this:

select * from SomeTable where SomeGuidField=:AGuid

I tried setting a TAdoQuery's SQL property to the above statement but found no way to actually set the AGuid-Parameter so the query can be opened. Whatever I tried resulted in the (ADO/COM) error "No value given for one or more required parameters", e.g.:

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.

+3  A: 

did you try

TheQuery.ParamByName('AGuid').AsGuid := AGuid;

????

DonOctavioDelFlores
TAdoQuery does not have a ParamByName method, TAdoQuery.Paramters does, but TParamater does not have a .AsGuid property
Thomas Mueller
A: 

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!

Steve
results in an access violation
Thomas Mueller
+1  A: 

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).

vrad
A: 

for what is worth i`m using GUIDs but I save them in DB as strings;

Alin Sfetcu
A: 

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;

henrik carlsen