ADODB::RecordCount() crashes with empty recordset

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • code green
    Recognized Expert Top Contributor
    • Mar 2007
    • 1726

    ADODB::RecordCount() crashes with empty recordset

    I have been working with a script I have inherited that uses the ADODB class.
    I want to run a query that checks a record is unique across the primary key and date field in a MsSql DB before inserting, so I am using this function
    Code:
    ADODB::Execute()
    to run this query
    Code:
    SELECT 1 FROM table WHERE pk = 'code' AND eff_date = 'newdate'.
    Which hopefully returns an empty recordset. But when I call
    Code:
    ADODB::RecordCount()
    to confirm the count is zero the damn thing falls over with 'Fatal error: Call to a non undefined member function RecordCount() on a non object'.
    The call works fine if a non empty recordset is returned.
    I have written my own DB class because PEAR is awful and so is this idiotic ADODB by the looks of things.
    Anybody familiar with this class who can point a way out.
  • Motoma
    Recognized Expert Specialist
    • Jan 2007
    • 3236

    #2
    Originally posted by code green
    I have been working with a script I have inherited that uses the ADODB class.
    I want to run a query that checks a record is unique across the primary key and date field in a MsSql DB before inserting, so I am using this function
    Code:
    ADODB::Execute()
    to run this query
    Code:
    SELECT 1 FROM table WHERE pk = 'code' AND eff_date = 'newdate'.
    Which hopefully returns an empty recordset. But when I call
    Code:
    ADODB::RecordCount()
    to confirm the count is zero the damn thing falls over with 'Fatal error: Call to a non undefined member function RecordCount() on a non object'.
    The call works fine if a non empty recordset is returned.
    I have written my own DB class because PEAR is awful and so is this idiotic ADODB by the looks of things.
    Anybody familiar with this class who can point a way out.
    It may be more useful to us if you posted a small amount of the relevant code for us to look at.

    Comment

    • pbmods
      Recognized Expert Expert
      • Apr 2007
      • 5821

      #3
      Heya, Code Green.

      Ok, first off, take a few breaths. Computers aren't supposed to do what we *want* them to do; that's why they're computers!

      Now then.

      If you're getting this error, then your ADODB include file is probably not found. Try: [code=php]print(str_repla ce(';', "<br />", ini_get('includ e_path')));[/code] and make sure that your PEAR directory is included in the list.

      Comment

      • code green
        Recognized Expert Top Contributor
        • Mar 2007
        • 1726

        #4
        Sorry. I was angry with ADODB. Here is the problem block of code, edited to protect the innocent.
        [PHP]require_once("a dodb/adodb.inc.php") ;
        ** This section (removed) opens and reads a CSV file and places the data in $data

        $conn = &ADONewConnecti on("mssql://user:pass@nn.nn .nn.nn/name") or die ("Could not connect to database");

        foreach ($data as $k=>&$line) {
        // Loop over all records, checking for validity.

        $partcode = trim($line['part']);
        $effdate = trim($line['eff_date']);
        $cost = trim($line['cost']);

        (strlen($partco de) != 0) or die("<br>Part code missing at line <b>$k</b>");
        (strlen($effdat e) != 0) or die("<br>Effect ive date missing at line <b>$k</b>");

        //Now check the part exists before attemptng an UPDATE
        $checkQuery = 'SELECT 1 FROM part WHERE part LIKE '.$conn->Quote($partcod e);

        $recordset = $conn->Execute($check Query);
        if($recordset->RecordCount( ))
        {
        //Now check the part and effective date are not being duplicated
        $checkQuery = 'SELECT 1 FROM part_cost,part_ ccel
        WHERE part LIKE '.$conn->Quote($partcod e) 'AND eff_date LIKE '.$conn->Quote($effdate );
        $recordset = $conn->Execute($check Query);
        if(!$recordset->RecordCount( ))
        {
        **Fails here**[/PHP]
        The first query executes OK and the first call to RecordCount() works fine.
        The second query executes fine but the call to RecordCount() produces this error.
        Code:
        'Fatal error: Call to a member function RecordCount() on a non object'.
        I've looked at the ADODB manual, which says -1 may be returned from RecordCount "if the number of rows returned cannot be determined"
        This could be the problem, although the error indicates something else.
        Thanks in advance for help.

        Comment

        • pbmods
          Recognized Expert Expert
          • Apr 2007
          • 5821

          #5
          Heya, Code Green.

          Originally posted by code green
          I've looked at the ADODB manual, which says -1 may be returned from RecordCount "if the number of rows returned cannot be determined"
          This could be the problem, although the error indicates something else.
          Okiedokie. Here's what might be happening:
          • $conn->execute() runs, but there were no matching rows, so it returns -1;
          • $recordset gets set to -1 instead of a resultset object.
          • Your script attempts to call -1->RecordCount( ), which... well, doesn't work so well.


          The solution would be to check to make sure that $recordset has the proper type before calling $recordset->RecordCount( ).

          You could use either is_object(), or for better robustness, use the instanceof operator.

          Comment

          • ronnil
            Recognized Expert New Member
            • Jun 2007
            • 134

            #6
            $checkQuery = 'SELECT 1 FROM part_cost,part_ ccel WHERE part LIKE '.$conn->Quote($partcod e) 'AND eff_date LIKE '.$conn->Quote($effdate );

            Don't know much about the ADODB, but looking at this line there's a syntax error... I don't know if this comes from you modification, cause php should make a fatal error when a string is not concenated properly (i should mean)

            (there's a '.' (dot) missing before 'AND eff_date ....

            Comment

            • Motoma
              Recognized Expert Specialist
              • Jan 2007
              • 3236

              #7
              If you read through the ADODB documentation, you will see that the execute function will return false if there was an error executing your query. I assume that this is the case you are running in to.

              You can use short circuit evaluation in your if statement to get rid of this error:

              if($recordset && $recordset->RecordCount( ) == 0) should do just fine.


              With this in mind, I would suggest you correct the other conditionals that try and use your record set without checking its existence.


              P.S. Looking at the responses in this thread makes me tingly inside.

              Comment

              • code green
                Recognized Expert Top Contributor
                • Mar 2007
                • 1726

                #8
                Code:
                (there's a '.' (dot) missing before 'AND eff_date ....
                Sorry that was just a typo from editing directly in the post
                Your script attempts to call -1->RecordCount( ),
                The solution would be to check to make sure that $recordset has the proper type before calling $recordset->RecordCount( ).
                Yep. That makes a lot of sense.
                But I am running this test hoping that no records are returned, that is, there should be no duplicates.
                Sooo, obviously these are not the functions to use. I will have to go back to the manual and try and find another method. Thanks for the help.

                Comment

                • pbmods
                  Recognized Expert Expert
                  • Apr 2007
                  • 5821

                  #9
                  Heya, Code Green.

                  How about this:

                  [code=php]
                  $checkQuery = "SELECT IF(EXISTS(SELEC T * FROM `part_cost` INNER JOIN `part_ccel` WHERE `part` = '{$conn->Quote($partcod e)}' AND `eff_date` = '{$conn->Quote($effdate )}'), 1, 0)";
                  [/code]

                  Comment

                  Working...