coEmptyStrParam

zmars
2006-06-14
2013-05-01
  • zmars
    zmars
    2006-06-14

    Sybase ASA 9.0.2, driver v3.0.2.6
    connection string:
    coConnectionString=DRIVER={Adaptive Server Anywhere 9.0};UID=user;PWD=***;ServerName=test;DBN=test;links=shmem,tcpip();coCatPrefix=DBN;coSafeMode=0;coNullStrParam=0;coEmptyStrParam=0;coTrimChar=True;coLockMode=60

    ========================
    CREATE TABLE t1
    (
      ID            integer not null autoincrement,
      N1            VARCHAR(10) NULL,
      PRIMARY KEY ("ID")
    );

    CREATE UNIQUE INDEX N1_index ON t1 ("N1");

    insert into t1(n1) values('');
    commit;
    ========================
    Unique index are allowed to be NULL.

    When i save record from my app with N1 = '',
    i get error like
    ========================
    Index 'N1_index' for table 't1' would not be unique

    SQL:
    insert into "t1"
      ("N1")
    values
      (?)

    Parameters:
    1 INPUT VARCHAR: ''
    ========================

    i change function TSqlCommandOdbc.setParameter

                  if (bIsNull = 0) then
                  begin // NOT NULL DATA
                    if (fOwnerDbxConnection.fConnectionOptions[coEmptyStrParam] = osOff)
                      and ( not (eParamType in [paramINOUT, paramOUT, paramRET]) )
                      and
                      (  // unicode check
                         ( bUnicodeString and (PWideChar(pBuffer)^ = cNullWideChar) )
                         or
                         // ansi char check
                         ( PChar(pBuffer)^ = cNullAnsiChar )
                      ) then
                    begin
                      pBuffer := nil;
                      Length := 0;
                      bIsNull := 1;
                      //// new
                      fOdbcParamLenOrInd := OdbcApi.SQL_NULL_DATA;
                      //// new
                    end;
                  end
    ========================
    this it is correct?

     
    • Looked over all source code, where coEmptyStrParam is present. Alike everywhere intortus placed osOff and osOn. But because default value osOn, the slip of the pen is compensated. It will be touched up in a next release.

       
      • +
        Clean the parameter of connection of oEmptyStrParam and problem must go away. Now this parameter works vice versa.

         
        • The similar slip of the pen is present for coNullStrParam.

           
    • zmars
      zmars
      2006-06-14

      1. but change which I have done (see above, fOdbcParamLenOrInd := OdbcApi.SQL_NULL_DATA;) it is necessary to leave?
      2. for correction bug with query like "select str(connection_property('PrepStmt')) || str(connection_property('CursorOpen'))" I change

      function TSqlCursorOdbc.getColumnName(ColumnNumber: Word; pColumnName: PChar): SQLResult;
          -------------
        //???:StrLCopy(pColumnName, TOdbcBindCol(fOdbcBindList[ColumnNumber - 1]).fColName, SizeOf(DBXpress.DBINAME)-1);  //old
        //StrCopy(pColumnName, TOdbcBindCol(fOdbcBindList[ColumnNumber - 1]).fColName);                                   //old

        StrLCopy(pColumnName, TOdbcBindCol(fOdbcBindList[ColumnNumber - 1]).fColName, SizeOf(DBXpress.DBINAME)-1); //new
        //StrCopy(pColumnName, TOdbcBindCol(fOdbcBindList[ColumnNumber - 1]).fColName);                            //new

      this it is correct?

      thank you!

       
      • Yes, you are right

        DbxOpenOdbc.pas:
        ...
        implementation
        ...
        type
        ...
          EDbxInvalidParam = class(EDbxError);

        //NEW *****
          {$IFNDEF _D10UP_}
          DBINAME32 = DBINAME;
          {$ENDIF}
        //NEW********
        ...

        function TSqlCursorOdbc.getColumnName(...
          //OLD: StrCopy(pColumnName, TOdbcBindCol(fOdbcBindList[ColumnNumber - 1]).fColName);
          StrLCopy(pColumnName, TOdbcBindCol(fOdbcBindList[ColumnNumber - 1]).fColName, SizeOf(DBINAME32) - 1);
          Result := DBXERR_NONE;
        ...
        end;

        function TSqlCursorOdbc.getColumnNameLength(...
        begin
        ...
          pLen := StrLen(TOdbcBindCol(fOdbcBindList[ColumnNumber - 1]).fColName);
          if pLen >= SizeOf(DBINAME32) then
            pLen := SizeOf(DBINAME32) - 1;
          Result := DBXERR_NONE;
        ...
        end;

        It will be corrected in a next release.

        Thanks !

         
    • zmars
      zmars
      2008-02-07

      About fix from first post.
      Sybase ASA 9.0.2, driver v3.028

      function TSqlCommandOdbc.setParameter;
      ...
      begin
      pBuffer := nil;
      Length := 0;
      bIsNull := 1;
      fOdbcParamLenOrInd := OdbcApi.SQL_NULL_DATA; //coEmptyStrParam don't work without this line
      end;
      ...

      This fix is correct?

      Thanks.

       
    • You is absolutely right! I have taken into account your correction in version "Version 3.100, 2008-02-07: Alpha"