views:

109

answers:

2

I think that (the title) is the problem I am having. I set up a MySQL connection, I read an XML file, and then I insert those values into a table by looping through the elements. The problem is, instead of inserting only 1 record, sometimes I insert 2 or 3 or 4. It seems to depend on the previous values I have read. I think I am reinitializing the variables, but I guess I am missing something -- hopefully something simple.

Here is my code. I originally had about 20 columns, but I shortened the included version to make it easier to read.

$ctr = 0;
$sql =  "insert into csd (id,type,nickname,hostname,username,password) ".
        "values (?,?,?,?,?,?)";
$cur = $db->prepare($sql);

for ($ctr = 0; $ctr < $expected_count; $ctr++) {
    unset($bind_vars,$dat);

    $lbl = "csd_{$ctr}";

    $dat['type']      = (string) $ref->itm->csds->$lbl->type;
    $dat['nickname']  = (string) $ref->itm->csds->$lbl->nickname;
    $dat['hostname']  = (string) $ref->itm->csds->$lbl->hostname;
    $dat['username']  = (string) $ref->itm->csds->$lbl->username;
    $dat['password']  = (string) $ref->itm->csds->$lbl->password;

    $bind_vars = array( $id,$dat['$type'], $dat['$nickname'], $dat['$hostname'], 
                        $dat['$username'], $dat['$password']);
    print_r ($bind_vars);
    $res = $db->execute($cur, $bind_vars);
}

P.S. I also tagged this SimpleXML because that is how I am reading the file, though that code is not included above. It looks like this:

$ref = simplexml_load_file($file);

UPDATE: I've changed the code around as per suggestions, and now it is not always the same pattern, but it is equally broken. When I display the bind array before inserting, it looks like this. Note that I also count the rows before and after, so there are 0 rows, then I insert 1, then there are 2:

0 CSDs on that ITEM now.
Array
(
    [0] => 2
    [1] => 0
    [2] =>
    [3] => X
    [4] => XYZ
    [5] =>
    [6] =>
    [7] =>
    [8] => audio
    [9] =>
    [10] => 192.168.0.50
    [11] => 192.168.0.3
    [12] => 255.255.255.0
    [13] => 255.255.255.0
    [14] =>
    [15] =>
    [16] =>
    [17] => 21
    [18] => 5
    [19] => Y
    [20] => /dir
)
2 CSDs on that ITEM now.
A: 

not sure the exact answer but this maybe help

$ctr = 0;
$sql =  "insert into csd (id,type,nickname,hostname,username,password) ".
        "values (?,?,?,?,?,?)";
$cur = $db->prepare($sql);

for ($ctr = 0; $ctr < $expected_count; $ctr++) {

    //list (  $lbl, $type, $nickname, $hostname, $username, $password) = "";
    //$bind_vars = array();
    // use unset
    unset($bind_vars,$dat);

    $lbl = "csd_{$ctr}";

    $dat['type']      = $ref->itm->csds->$lbl->type;
    $dat['nickname']  = $ref->itm->csds->$lbl->nickname;
    $dat['hostname']  = $ref->itm->csds->$lbl->hostname;
    $dat['username']  = $ref->itm->csds->$lbl->username;
    $dat['password']  = $ref->itm->csds->$lbl->password;

    $bind_vars = array($id,$dat['$type'],$dat['$nickname'],$dat['$hostname'],$dat['$username'],$dat['$password']);
    $res = $db->execute($cur, $bind_vars);

    # this is a separate function which works, but which only 
    # does SELECTS and cannot be the problem.  I include it because I 
    # want to count the total rows.

    printf ("%d CSDs on that ITEM now.\n",  CountCSDs($id_to_sync));
}

or maybe you should check/echo $expected_count value first to determine correct count

apis17
I checked the expected count and it was correct. So I loop the correct number of times -- it is just that I insert too many records each time. Does your answer imply that unset works better than just setting the values to "" ? I'll try it.
MJB
Exact same behavior. I have an XML file with expected_count of 5, and the count after each insert goes 2, 4, 5, 8, 9. It should go 1, 2, 3, 4, 5.
MJB
just an idea. i'm not sure but if it fails maybe there are another way if you could give me another clue on what happen and result should be.
apis17
maybe 2, 4, 5, 8, 9 is CD number. :)
apis17
I changed the code how you recommended, and then I cast them all as strings, for example $dat['fldname'] = (string) $ref->itm->csds->$lbl->type; and now the pattern is slightly different. On the first pass, it inserts 2, on the second, it inserts 2, the third pass inserts 1, the fourth pass inserts 1, and the fifth pass inserts 1, for a total of 7 instead of the expected 5. So my CD number is now 2, 4, 5, 6, 7 ?
MJB
A: 

Turns out that the script was being run by a cron job, but SOMEONE ELSE was running my script with another cron job, and therefore it was sometimes creating twice as many records, and sometimes it was not. And the more I looked at it, and the more I created code to troubleshoot it, the slower it got, so the worse it got.

In other words, when I didn't look at it, it worked better than when I did look at it.

Darn all those people trying to help me!

MJB
This was the correct answer, but I accepted the one above because doing it that way allowed me to see what was going on better, which allowed me to find out that it was running twice. Since the other user was writing to a different log file, I didn't notice right away.
MJB
apis17
Yeah, I looked where the scripts are stored, but it was in a different area than the other cron jobs, so I missed it.
MJB