tags:

views:

106

answers:

1

Hi,

I don't know much about delphi win 32 programming, but I hope someone can answer my question.

I get duplicate l_sGetUniqueIdBuffer saved into the database which I want to avoid.

The l_sGetUniqueIdBuffer is actually different ( the value of l_sAuthorisationContent is xml, and I can see a different value generated by the call to getUniqueId) between rows. This problem is intermittant ( duplicates are rare...) There is only milliseconds difference between the update date between the rows.

Given:

( unnesseary code cut out)

var
    l_sGetUniqueIdBuffer: PChar;
    FOutputBufferSize : integer;

begin
    FOutputBufferSize := 1024;
    ...
    while( not   dmAccomClaim.ADOQuClaimIdentification.Eof ) do
    begin

        // Get a unique id for the request
        l_sGetUniqueIdBuffer := AllocMem (FOutputBufferSize);

        l_returnCode := getUniqueId (m_APISessionId^, l_sGetUniqueIdBuffer, FOutputBufferSize);

        dmAccomClaim.ADOQuAddContent.Active := False;
        dmAccomClaim.ADOQuAddContent.Parameters.ParamByName('pContent').Value := (WideString(l_sAuthorisationContent));
        dmAccomClaim.ADOQuAddContent.Parameters.ParamByName('pClaimId').Value := dmAccomClaim.ADOQuClaimIdentification.FieldByName('SB_CLAIM_ID').AsString;
        dmAccomClaim.ADOQuAddContent.Parameters.ParamByName('pUniqueId').Value := string(l_sGetUniqueIdBuffer);
        dmAccomClaim.ADOQuAddContent.ExecSQL;

        FreeMem( l_sAuthorisationContent, l_iAuthoriseContentSize );

        FreeMem( l_sGetUniqueIdBuffer, FOutputBufferSize );
    end;
end;

I guess i need to know, is the value in l_sGetUniqueIdBuffer being reset for every row??

A: 

AllocMem is implemented as follows

function AllocMem(Size: Cardinal): Pointer;
begin
  GetMem(Result, Size);
  FillChar(Result^, Size, 0);
end;

so yes, the value that l_sGetUniqueBuffer is pointing to will always be reset to an empty string.

Debugging

var
    l_sGetUniqueIdBuffer: PChar;
    FOutputBufferSize : integer;
    list: TStringList;
begin
    FOutputBufferSize := 1024;
    ...

    list := TStringList.Create;
    try
      list.Sorted := True;
      while( not   dmAccomClaim.ADOQuClaimIdentification.Eof ) do
      begin

          // Get a unique id for the request
          l_sGetUniqueIdBuffer := AllocMem (FOutputBufferSize);

          l_returnCode := getUniqueId (m_APISessionId^, l_sGetUniqueIdBuffer, FOutputBufferSize);

          dmAccomClaim.ADOQuAddContent.Active := False;
          dmAccomClaim.ADOQuAddContent.Parameters.ParamByName('pContent').Value := (WideString(l_sAuthorisationContent));
          dmAccomClaim.ADOQuAddContent.Parameters.ParamByName('pClaimId').Value := dmAccomClaim.ADOQuClaimIdentification.FieldByName('SB_CLAIM_ID').AsString;
          dmAccomClaim.ADOQuAddContent.Parameters.ParamByName('pUniqueId').Value := string(l_sGetUniqueIdBuffer);

          if list.IndexOf(l_sGetUniqueIdBuffer) <> - 1 then
            write; //***** Place a breakpoint here.
          list.Add(l_sGetUniqueIdBuffer);

          dmAccomClaim.ADOQuAddContent.ExecSQL;

          FreeMem( l_sAuthorisationContent, l_iAuthoriseContentSize );

          FreeMem( l_sGetUniqueIdBuffer, FOutputBufferSize );
      end;
    finally
      list.Free;
    end;
end;
Lieven
Hello Lieven, thanks for reply.The duplicates are actual id's in the form of WEB201171a5f498869529300 stored in the db, however the actual xml saved into l_sAuthorisationContent ( and into the db) its different.The session is only set the once before processing all rows outside of the while loop:l_returnCode := createSessionEasyclaim( m_APISessionId, PChar( l_crypto_path ), PChar( l_location_pwd ) );I guess theoretically it could be done on a row by row basis but the additional elements a session requires prohibits this i would think.
maybe the string cast has somethign to do with it?? dmAccomClaim.ADOQuAddContent.Parameters.ParamByName('pUniqueId').Value := string(l_sGetUniqueIdBuffer);
Personally, I would blame the getUniqueID method. For debugging purposes, I would create a stringlist and add each l_sGetUniqueIdBuffer to it with a check if it already exists. If it already exists, you can set a breakpoint.
Lieven