DrDamnit
asked on
Why is num_rows 0?
For some reason, this query is returning 0 rows when it should be returning 33 rows for a given address that is duplicated 33 times. I must have a syntax error somewhere that I am not seeing. Does anyone see what I a missing here?
function createIfNew()
{
$this->logger->log(print_r($this,true));
$s = $this->db->prepare('SELECT * FROM mcdb2.addresses
WHERE
addresses_street1 = ?
AND addresses_street2 = ?
AND addresses_city = ?
AND addresses_state = ?
AND addresses_zip = ?');
$s->bind_param('ssssi',$this->addresses_street1,$this->addresses_street2,$this->addresses_city,$this->addresses_state,$this->addresses_zip);
//Show SQL statement for logs since we can't dump prepared statements.
$sql = sprintf('SELECT * FROM mcdb2.addresses
WHERE
addresses_street1 = "%s"
AND addresses_street2 = "%s"
AND addresses_city = "%s"
AND addresses_state = "%s"
AND addresses_zip = "%s"',$this->addresses_street1,$this->addresses_street2,$this->addresses_city,$this->addresses_state,$this->addresses_zip);
$this->logger->log($sql);
if($s->execute())
{
$this->logger->log("Query successful");
$result = $s->get_result();
$this->logger->log(print_r($result,true));
if($result->num_rows == 0)
{
$this->logger->log("This address does not exist. Inserting it now.");
return $this->insert_me();
} else {
$this->logger->log("This address already exists in the database. Loading it instead.");
$row = $result->fetch_assoc();
$this->addresses_id = $row['addresses_id'];
$this->load_me();
return $this->addresses_id;
}
}
}
ASKER
@ray:
Here's the address table create statement.
Line 23 does create a log statement. I use this (http://svn.highpoweredhelp.com/logger/).
Here's the log entry:
Log lines are three column: timestamp - tab - class generating the message - tab - message.
You can see in the final lines of this excerpt, the num_rows = 0.
Here's the address table create statement.
CREATE TABLE `addresses` (
`addresses_id` int(11) NOT NULL AUTO_INCREMENT,
`addresses_label` varchar(45) DEFAULT NULL COMMENT 'Identifies the address.',
`addresses_street1` varchar(45) DEFAULT NULL,
`addresses_street2` varchar(45) DEFAULT NULL,
`addresses_city` varchar(45) DEFAULT NULL,
`addresses_state` varchar(2) DEFAULT NULL,
`addresses_zip` varchar(10) DEFAULT NULL,
PRIMARY KEY (`addresses_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10190 DEFAULT CHARSET=latin1;
Line 23 does create a log statement. I use this (http://svn.highpoweredhelp.com/logger/).
Here's the log entry:
2014-03-29 17:29:51 user Loading contact
2014-03-29 17:29:51 user Setting contacts_company = 12605
2014-03-29 17:29:51 user Adding email for contact
2014-03-29 17:29:51 user Adding email to contact
2014-03-29 17:29:51 email Email added successfully.
2014-03-29 17:29:51 user Contact is the primary contact for A C Inc. setting them as primary contact.
2014-03-29 17:29:51 type Address class staring up...
2014-03-29 17:29:51 phone This type does exist. I'm loading it now.
2014-03-29 17:29:51 phone Type is loaded. Moving on...
2014-03-29 17:29:51 phone Type set to: 1
2014-03-29 17:29:51 phone Checking: CPHONE1
2014-03-29 17:29:51 phone Checking: CPHONE2
2014-03-29 17:29:51 phone Checking: CPHONE3
2014-03-29 17:29:51 phone Checking: CPHONE4
2014-03-29 17:29:51 phone Checking: CPHONE5
2014-03-29 17:29:51 phone Checking: CPHONE6
2014-03-29 17:29:51 phone Checking: CPHONE7
2014-03-29 17:29:51 phone Checking: CPHONE8
2014-03-29 17:29:51 phone Checking: CPHONE9
2014-03-29 17:29:51 phone Checking Fax
2014-03-29 17:29:51 import-mcdb Query returned with results. There is at least one company with the M_ID in question
2014-03-29 17:29:51 import-mcdb This company already exists in the database. Company loaded.
2014-03-29 17:29:51 address Address class staring up...
2014-03-29 17:29:51 user addr Object
(
[__oldlabel] => import-mcdb
[addresses_id] =>
[addresses_label] => Primary
[addresses_street1] => 1665 Lakes Parkway Suite 108
[addresses_street2] =>
[addresses_city] => Lawrenceville
[addresses_state] => GA
[addresses_zip] => 30043
[db] => mysqli Object
(
[affected_rows] => 0
[client_info] => mysqlnd 5.0.10 - 20111026 - $Id: b0b3b15c693b7f6aeb3aa66b646fee339f175e39 $
[client_version] => 50010
[connect_errno] => 0
[connect_error] =>
[errno] => 0
[error] =>
[error_list] => Array
(
)
[field_count] => 0
[host_info] => Localhost via UNIX socket
[info] =>
[insert_id] => 0
[server_info] => 5.5.34-0ubuntu0.13.04.1
[server_version] => 50534
[stat] => Uptime: 1572439 Threads: 12 Questions: 1007913 Slow queries: 1 Opens: 3492 Flush tables: 1 Open tables: 195 Queries per second avg: 0.640
[sqlstate] => 00000
[protocol_version] => 10
[thread_id] => 206779
[warning_count] => 0
)
[logger] => logger Object
(
[logfile:logger:private] => import-mcdb.log
[handle] => Resource id #64
[logpath:logger:private] => /home/mcdb/log/
[mode:logger:private] => a+
[label] => user
[skipMessages] =>
[verbosity] => 1
)
)
2014-03-29 17:29:51 user SELECT * FROM mcdb2.addresses
WHERE
addresses_street1 = "1665 Lakes Parkway Suite 108"
AND addresses_street2 = ""
AND addresses_city = "Lawrenceville"
AND addresses_state = "GA"
AND addresses_zip = "30043"
2014-03-29 17:29:51 user Query successful
2014-03-29 17:29:51 user mysqli_result Object
(
[current_field] => 0
[field_count] => 7
[lengths] =>
[num_rows] => 0
[type] => 0
)
2014-03-29 17:29:51 user This address does not exist. Inserting it now.
2014-03-29 17:29:51 user Associating address id (10187) to company id: 12604
2014-03-29 17:29:51 user Address 10187 associated with company 12604
Log lines are three column: timestamp - tab - class generating the message - tab - message.
You can see in the final lines of this excerpt, the num_rows = 0.
This is a bit of a guess, but it should be easy enough to test. Try changing the types from ssssi to sssss. I am guessing this based on the way the CREATE TABLE handles the addresses_zip column. After that it's a data-dependent problem so we might need to see some test data that would let us load the table.
ASKER
Ah... Yes. It started out as sssss, but theni changed it to ssssi because i was to lazy to check the table definitions. When neither worked, I checked the definition to confirm. This code was copy pasted before I put it back to 'sssss'.
I wish that was the problem. It would be an easy fix.
I wish that was the problem. It would be an easy fix.
ASKER
Sample data is in the log where I dump the SQL statement.
I'll take a look at this again tomorrow. Gotta watch some roundball now.
Maybe try omitting addresses_street2 from the query (just for the test case)? These notes seems to imply there may be "interesting" issues with NULL.
http://php.net/manual/en/mysqli-stmt.bind-param.php#103144
http://php.net/manual/en/mysqli-stmt.bind-param.php#104935
http://php.net/manual/en/mysqli-stmt.bind-param.php#80118
Another possible approach would be to define the columns as NOT NULL DEFAULT ''
Maybe try omitting addresses_street2 from the query (just for the test case)? These notes seems to imply there may be "interesting" issues with NULL.
http://php.net/manual/en/mysqli-stmt.bind-param.php#103144
http://php.net/manual/en/mysqli-stmt.bind-param.php#104935
http://php.net/manual/en/mysqli-stmt.bind-param.php#80118
Another possible approach would be to define the columns as NOT NULL DEFAULT ''
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
That makes sense. How do we get around this problem? Street2 will be blank quite often, but, when it's not blank it's important. Change the table definition?
For example, when I import data, I want to check for duplicates, so I am looking for street 1 = "123 Happy Street", street 2 is blank, City = "Boston" State="MA" and zipcode = "123456".
Initially, this code was failing (and creating duplicates) because num_rows was coming back as 0 and that's what I was checking. The logic was: if num_rows==0, then the address doesn't exist yet.
But when this fails, num_rows==0 and it inserts a duplicate.
For example, when I import data, I want to check for duplicates, so I am looking for street 1 = "123 Happy Street", street 2 is blank, City = "Boston" State="MA" and zipcode = "123456".
Initially, this code was failing (and creating duplicates) because num_rows was coming back as 0 and that's what I was checking. The logic was: if num_rows==0, then the address doesn't exist yet.
But when this fails, num_rows==0 and it inserts a duplicate.
Michael, I would change the table definition. Instead of DEFAULT NULL, try NOT NULL DEFAULT '' where the '' is simply two apostrophes to indicate an empty string. There may be collateral changes needed elsewhere if you have code that depends on columns containing NULLs so tread carefully as you make the change.
ASKER
I'll try that, and report back.
$this->logger->log("Query successful");
Are you running with error_reporting(E_ALL) set?
Is there any chance that you have a ZIP+4 type of ZIP code? It might not work with binding as integer.