0

The environment this is running in is as follows. It's an instance of Server2Go on a thumb drive.

Apache/2.2.15 (Win32),
PHP/5.3.2,
SQLite 2,
MySQL 5.1.46-community,
 and Perl 5.8.

The php script opens a file and loops through it line by line. A query is built and executed with the information in each line of the file.

The table structure is as follows:

CREATE TABLE `exp_report` (
  `b_unit` varchar(11) DEFAULT NULL,            //IMPORTANT TO THIS PROBLEM
  `b_unit_title` varchar(255) DEFAULT NULL,
  `act_code` varchar(11) DEFAULT NULL,
  `act_title` varchar(255) DEFAULT NULL,
  `adopted_bgt` varchar(20) DEFAULT NULL,
  `amended_bgt` varchar(20) DEFAULT NULL,
  `encumb` varchar(20) DEFAULT NULL,
  `ytd_exp` float(14,2) DEFAULT NULL,           //IMPORTANT TO THIS PROBLEM
  `encumb_ytdexp` float(14,2) DEFAULT NULL,     //IMPORTANT TO THIS PROBLEM
  `available_bgt` varchar(20) DEFAULT NULL,
  `percent` varchar(20) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

When the script is executed I echo the query statement that is generated before and after the query is executed in the php script. This is to ensure nothing strange is happening to the data in PHP.

Example output:

INSERT INTO exp_report (b_unit, b_unit_title, act_code, act_title, adopted_bgt, 
                        amended_bgt, encumb, ytd_exp, encumb_ytdexp, available_bgt,
                        percent
                       )
   VALUES('01000101', 'COUNCIL', '414000', 'SALARIES & WAGES', '259500','214500',
          '0', '2', '209296.72', '5203.28', '0.97574228'
         ); 

The Result in the database looks like this:

010001 | COUNCIL | 414000 | SALARIES & WAGES | 259500 | 214500 | 0 | 2.00 | 2.00 | 5203.28 | 0.97574228

Please note the first field and the last 4 fields of the above data.

The first field is b_unit varchar(11)` and the program attempts to insert 01000101 but the last two digits are cut off when it is stored in the database.

The next two fields are ytd_exp float(14,2) and encumb_ytdexp float(14,2). I attempt to insert '209296.72' in encumb_ytdexp and it is converted into 2.00.

The remaining two fields are varchars and they store the information properly.

If I copy the query that is echoed to the browser and run it within phpMyAdmin the data is stored properly and it looks exactly like what was passed through in the query statement.

I can't seem to figure out what is causing this behavior.

Any advice is appreciated.

Code for the php script:

<?php 
include('includes\db_fns.php');

$filename = "d2013expRep.xls";

$lines = file($filename);



foreach($lines as $key=>$current){
    $contents = explode("\t",$current);
    if($key=="0"){
        continue;
    }
    $actr = 0;
    //var_dump($contents);
    foreach($contents as $key2=>$c2){
        $la = trim($c2);

        if($actr==0){
            $finout .= "'".$la."'"; 
        }else{
            if($key2=="7"){
                $la = (float) $la;
                $finout .= ",'".$la."'";
            }else{
                $finout .= ",'".$la."'";
            }
        }

        $actr++;    
        unset($la);
    }

    $query = "INSERT INTO exp_report (b_unit,b_unit_title,act_code,act_title,adopted_bgt,amended_bgt,encumb,ytd_exp,encumb_ytdexp,available_bgt,percent) VALUES($finout); ";
    //echo($query."<BR><BR><BR>");
    $result =  mysqli_query($dc2a,$query) or trigger_error("Failed Query: " . mysqli_error($dc2a)); 
    $finout .= "\r\n";
    echo $query."<BR><BR><BR>";
    unset($finout);
    unset($actr);
}

//$query = "LOAD DATA LOCAL INFILE '/Library/WebServer/Documents/".$filename."' INTO TABLE exp_report FIELDS TERMINATED BY '\s\t' LINES TERMINATED BY '\n' IGNORE 1 LINES ";
//$result = mysqli_query($dc2a,$query) or trigger_error("Failed Query: " . mysqli_error($dc2a)); 
//echo $query;


?>

I have attempted all of respondents suggestions to no avail. Perhaps these shots will help shed some light on this question.

The data is inserted into the database once the script is executed. I'm using text/strings as opposed to numbers/decimals/floats. Now the database is telling me records do not exist when I know they do.

This is the image of the table results when I select browse.

When I execute a query using like the result is an empty set. The field I am searching is setup as a text field.

Why would the query return an empty result here.

Does this make sense to anyone or am I chasing a ghost?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
user2355051
  • 605
  • 1
  • 8
  • 26
  • I think you are looking at the wrong row after the insert. I cannot think of a way that two characters would be lopped off of a character field that is big enough to hold the value, unless there is a trigger on the table that is modifying the value when inserted. – Gordon Linoff Mar 15 '14 at 16:27
  • Gordon Linoff, This is what is puzzling me as it does not make sense. If I set all the fields to varchar, the columns that I want to treat as floats are stored with the proper values. What would the trigger possibly be in the table that you're mentioning and how can I check to see where it exists? – user2355051 Mar 15 '14 at 16:28
  • If the query is being executed correctly directly into the database, I suggest the issue is with the php rather than the query itself. – rc_luke Mar 15 '14 at 16:30
  • rc_luke, I'm echoing the query that I'm building dynamically before and after it is executed. Why would the output of the variable that contains the query string differ from what is being passed into the mysqli_query($db,$query) function? – user2355051 Mar 15 '14 at 16:32
  • That's no more absurd than the query being executed differently via php than via phpMyAdmin. Without seeing the php I'd be shooting in the dark. – rc_luke Mar 15 '14 at 16:38
  • 99% there is a bug in the php code you didn't posted. post the relevant code, please – Paolo Mar 15 '14 at 16:41
  • @rc_luke, php code is available here http://pastie.org/private/y9l9uufim23spx9cgbs5q – user2355051 Mar 15 '14 at 16:45
  • I can't see anything obvious. You could try not encapsulating the float values in quotes though. So it's clear that they are floats and not strings in the mysql statement. – rc_luke Mar 15 '14 at 16:57
  • Why cast as (float)? That may be the source of the problem, though I'm not sure how, as everything looks okay. But the casting seems like an unnecessary complication. Your file input and all SQL statements are always strings, and you can't add precision to a string by casting it as float. So what's the point of it? – BarryDevSF Mar 15 '14 at 17:52
  • @BarryDevSF I was casting as a float as an attempt to fix the problem. Prior to this the results were the same as described above. I thought it had something to do with how the numbers were being passed with php. – user2355051 Mar 15 '14 at 22:13
  • Another suggestion for circumventing rather than solving, but take a look at this: http://stackoverflow.com/a/5150345/2122474 – BarryDevSF Mar 16 '14 at 01:51
  • Edit your code to eliminate the dependency on the external XLS file and on the included php file. Paste a minimal version of *that* code into your question. Then we can all run the same code. – Mike Sherrill 'Cat Recall' Mar 16 '14 at 11:07
  • Also, if I select the little pencil to the left of a record, I am told there is no result that matches the query. The query string is searching each fields value against the field it is entered in. If I add a id field with an auto increment after insert and attempt to edit, it can retrieve the information from the database based on the unique id. – user2355051 Mar 18 '14 at 01:28

1 Answers1

0

Hard to see what's wrong from what you posted

Ensure the read file is a properly tab separated text file: maybe I'm wrong but from the extension .xls it seems you're trying to read a native Excel binary file (when I save from Excel as tab-separated values I get .txt as extension but I'm on Mac...)

I rewrote your code to be more clear

Also (that may fix the issue) I added 3 things:

  1. every value is escaped before inserting into the values string. This will save you if the value contains a single quote, for example

  2. I enclosed the field' names between backticks to avoid potential mysql reserved keywords conflicts.

EDIT:

  1. It seem you're parsing a UTF-16 file. After reading the line it's converted to UTF8.

Hope this helps

<?php 
include('includes\db_fns.php');

$filename = "d2013expRep.xls"; // <--- make sure you're importing properly tab separated text data (are you importing an xls file??)

$lines = file($filename);

foreach($lines as $lineNum => $line) {
    // It seem you're working with a UTF-16 text file: convert to UTF8
    $lineUTF8 = mb_convert_encoding( $line, "UTF-8", "UTF-16LE" );
    $contents = explode( "\t", $lineUTF8 );
    if($lineNum==0) {
        continue;
    }

    $queryValues = "";

    foreach( $contents as $valueNum => $value ) {
        // good practice to escape the string
        $queryValues .= ( $valueNum == 0 ? "" : ", " ) . "'" . mysql_escape_string( trim( $value ) ) . "'"; 
    }

    // backtick field names to avoid reserved keywords conflicts
    $query = "INSERT INTO `exp_report` ( `b_unit`,
                                         `b_unit_title`, 
                                         `act_code`, 
                                         `act_title`, 
                                         `adopted_bgt`, 
                                         `amended_bgt`, 
                                         `encumb`, 
                                         `ytd_exp`, 
                                         `encumb_ytdexp`, 
                                         `available_bgt`, 
                                         `percent` ) VALUES( $queryValues ); ";

    $result =  mysqli_query($dc2a,$query) or trigger_error("Failed Query: " . mysqli_error($dc2a)); 

    // echo $query . "<br /><br />";
}

?>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Paolo
  • 15,233
  • 27
  • 70
  • 91
  • Thanks for the input Paolo, unfortunately this does not solve the problem. As for your considerations, the file is tab delimited and some fields have spaces before the tab delimiter. To the best of my knowledge, none of the field names I'm using are reserved keywords. When I store these values as strings they work properly, when I specify that they are a decimal or float they cause the problem. I'll need to store them as a string and query the db and have php do the processing as opposed to generating a query for the math to summarize the table. – user2355051 Mar 16 '14 at 11:18
  • Although when I add mysqli_real_esacpe_string to the values of each field I get the following `INSERT INTO exp_report (b_unit,b_unit_title,act_code,act_title,adopted_bgt,amended_bgt,encumb,ytd_exp,encumb_ytdexp,available_bgt,percent) VALUES('0\01\00\00\00\01\00\01','C\0O\0U\0N\0C\0I\0L','4\01\04\00\00\00','S\0A\0L\0A\0R\0I\0E\0S\0 \0&\0 \0W\0A\0G\0E\0S','2\05\09\05\00\00','2\01\04\05\00\00','0','2\00\09\02\09\06\0.\07\02','2\00\09\02\09\06\0.\07\02','5\02\00\03\0.\02\08','0\0.\09\07\05\07\04\02\02\08'); ` This doesn't really make sense unless there's a bunch of hidden information in file. – user2355051 Mar 16 '14 at 11:25
  • It seem your text file is encoded as UTF16. I modified the code. See also my edit. – Paolo Mar 16 '14 at 18:37
  • I attempted to utilize the edited code you provided. I don't think the information is UTF16. Notice: Failed Qeury: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' ㄀   ㄀ ㄀        ऀ䌀伀唀一䌀䤀䰀  â' at line 11 in E:\server2go_a22_psmp\server2go\htdocs\hbg2.php on line 36 – user2355051 Mar 18 '14 at 00:12
  • there was a typo in my previuos posted ansewer. if you copy-pasted it that may be the issue. I fixed it. It was on that line: `$queryValues .= ( $valueNum == 0 ? "" : ", " ) . "'" . mysql_escape_string( trim( $value ) ) . "'";` – Paolo Mar 18 '14 at 20:44
  • btw: if the text encoding is the problem you may follow tho ways: 1) attemp to convert text to utf8 in your php code (as I first suggested). 2) read the text assuming it's utf8 BUT before ensure code passed to the script is ASCII or UTF8 inspecting and eventually converting with a good text editor. In any case ensure encoding of your DB is UTF8. You should be able to check/set this by phpmyadim, I think – Paolo Mar 18 '14 at 20:48