I m trying to get rid of the trailing comma my sql statemen using trim but it doesnt seem to work
if(isset($_POST['report'])){
//====
$sql = 'INSERT INTO weekly_repo ( hospnme, disease, week, under5, above5, dat) VALUES ';
$week = intval($_POST['current_week']);
$diseases = $_POST['diseases'];
foreach($diseases as $disease){
$sql .= ' ( "' . filterString($_POST['hospital']). '", "' . filterString($disease['disease']) . '", ' . $week . ', ' . intval($disease['under_5']) . ', ' . intval($disease['over_5']) . ', NOW()), ';
}
$sql = trim($sql, '\,');
// ended up doing this
//$sql = substr($sql, 0, strrpos($sql, ',')) . ';';
$stmt = $conn->query($sql);
}
You don't need to escape \ the comma. A better approach might be to construct an array and then implode():
foreach($diseases as $disease){
$sql[] = ' ( "' . filterString($_POST['hospital']). '", "' . filterString($disease['disease']) . '", ' . $week . ', ' . intval($disease['under_5']) . ', ' . intval($disease['over_5']) . ', NOW()), ';
}
$sql = implode(',', $sql);
Related
I have a form that uses a PHP for loop after it is submitted. The loop updates individual rows in the database one after the next based on the form data submitted. However, I've noticed that the loop stops working if there are more than 31 rows that need to be updated. It will update everything perfectly for the first 31 loops but then will not work after the 31st loop?
UPDATE: I've done some testing and it seems that the loop never finishes. It just refreshes the page in the browser instead of printing the results. What is causing this?
Is there a MYSQL query setting somewhere that is causing this?
Here is my loop's code:
for($i=1;$i<=$total_results2;$i++)
{
$strSQL = 'UPDATE timesheets_items SET ';
$strSQL .= 'time_1 = "' . convert_time($_POST['item_' . $i . '_time_1']) . '"';
$strSQL .= ', time_2 = "' . convert_time($_POST['item_' . $i . '_time_2']) . '"';
$strSQL .= ', time_3 = "' . convert_time($_POST['item_' . $i . '_time_3']) . '"';
$strSQL .= ', time_4 = "' . convert_time($_POST['item_' . $i . '_time_4']) . '"';
$strSQL .= ', time_5 = "' . convert_time($_POST['item_' . $i . '_time_5']) . '"';
$strSQL .= ', time_6 = "' . convert_time($_POST['item_' . $i . '_time_6']) . '"';
$strSQL .= ', time_7 = "' . convert_time($_POST['item_' . $i . '_time_7']) . '"';
$strSQL .= ', time_8 = "' . convert_time($_POST['item_' . $i . '_time_8']) . '"';
$strSQL .= ', time_9 = "' . convert_time($_POST['item_' . $i . '_time_9']) . '"';
$strSQL .= ', time_10 = "' . convert_time($_POST['item_' . $i . '_time_10']) . '"';
$strSQL .= ', time_11 = "' . convert_time($_POST['item_' . $i . '_time_11']) . '"';
$strSQL .= ', time_12 = "' . convert_time($_POST['item_' . $i . '_time_12']) . '"';
$strSQL .= ', time_13 = "' . convert_time($_POST['item_' . $i . '_time_13']) . '"';
$strSQL .= ', time_14 = "' . convert_time($_POST['item_' . $i . '_time_14']) . '"';
$strSQL .= ', time_total = "' . convert_time($_POST['item_' . $i . '_time_total']) . '"';
$strSQL .= ', ot_1 = "' . convert_time($_POST['item_' . $i . '_ot_1']) . '"';
$strSQL .= ', ot_2 = "' . convert_time($_POST['item_' . $i . '_ot_2']) . '"';
$strSQL .= ', ot_3 = "' . convert_time($_POST['item_' . $i . '_ot_3']) . '"';
$strSQL .= ', ot_4 = "' . convert_time($_POST['item_' . $i . '_ot_4']) .'"';
$strSQL .= ', ot_5 = "' . convert_time($_POST['item_' . $i . '_ot_5']) . '"';
$strSQL .= ', ot_6 = "' . convert_time($_POST['item_' . $i . '_ot_6']) . '"';
$strSQL .= ', ot_7 = "' . convert_time($_POST['item_' . $i . '_ot_7']) . '"';
$strSQL .= ', ot_8 = "' . convert_time($_POST['item_' . $i . '_ot_8']) . '"';
$strSQL .= ', ot_9 = "' . convert_time($_POST['item_' . $i . '_ot_9']) . '"';
$strSQL .= ', ot_10 = "' . convert_time($_POST['item_' . $i . '_ot_10']) . '"';
$strSQL .= ', ot_11 = "' . convert_time($_POST['item_' . $i . '_ot_11']) . '"';
$strSQL .= ', ot_12 = "' . convert_time($_POST['item_' . $i . '_ot_12']) . '"';
$strSQL .= ', ot_13 = "' . convert_time($_POST['item_' . $i . '_ot_13']) . '"';
$strSQL .= ', ot_14 = "' . convert_time($_POST['item_' . $i . '_ot_14']) . '"';
$strSQL .= ', ot_total = "' . convert_time($_POST['item_' . $i . '_ot_total']) . '"';
$strSQL .= 'WHERE week_start = "' . $week_start . '" AND employee_id = "' . $id . '" AND project_number = "' . $_POST['item_' . $i . '_project_number'] .'" AND task = "' . $_POST['item_' . $i . '_task'] .'"';
mysql_query($strSQL);
}
I have now solved the issue ! The problem was caused by my version of PHP (5.3) and the amount of input variables allowed by PHP on a form.
The problem ended up not being MySQL related at all. The bug found was limiting how many form variables were taken in by PHP thus not allowing MySQL to ever get to see those variables when it came time to run the repeated queries loop.
To resolve the issue, I had to update to PHP (5.4 or greater) and then set the "max_input_vars" setting to 3000. (The default setting only allows 1000.)
I hope this helps anyone who ever comes across this same problem.
I keep getting this error
Unknown column 'Hello' in 'field list'
when I execute this code
$sql = "INSERT INTO installs (date,addedBy,customer,reg,vehMake,vehModel,colour,mileage,location,tracker,serial,sim,extr as,satnav,input1,input2,output,comments) VALUES (" . $date . ", " . $addedBy . ", " . $customer . ", " . $reg . ", " . $vehMake . ", " . $vehModel . ", " . $colour . ", " . $mileage . ", " . $location . ", " . $tracker . ", " . $serial . ", " . $sim . ", " . $extras . ", " . $satnav . ", " . $input1 . ", " . $input2 . ", " . $output . ", " . $comments . ")";
$result = $connect->query($sql) or die($connect->error);
replace this
(' . "Hello" . ', ' . 2 . ', ' . 3 . ', ' . 4 . ', ' . 4 . ', ' . 5 . ', ' . 6 . ', ' . 7 . ', ' . 8 . ', ' . 9 . ', ' . 10 . ', ' . 11 . ', ' . 12 . ', ' . 13 . ', ' . 14 . ', ' . 15 . ', ' . 16 . ', ' . 17 . ')';
by
("Hello", 2 ,3, 4,4,5,6,7,8,9,10,11,12, 13,14,15,16,17)';
EDIT:
replace this
(" . $date . ", " . $addedBy . ",..........
by
('$date', '$addedBy',...........
or this
('" . $date . "', '" . $addedBy . "',..........
Hello needs to be enclosed in single quotes. Escape the quotes like this:
$sql = 'INSERT INTO installs
(date,addedBy,customer,reg,vehMake,vehModel,colour,
mileage,location,tracker,serial,sim,extras,satnav,
input1,input2,output,comments)
VALUES
(\'' . "Hello" . '\', ' . 2 . ', ' . 3 . ', ' . 4 . ', ' . 4 . ',
' . 5 . ', ' . 6 . ', ' . 7 . ', ' . 8 . ', ' . 9 . ',
' . 10 . ', ' . 11 . ', ' . 12 . ', ' . 13 . ', ' . 14 . ', ' . 15 . ',
' . 16 . ', ' . 17 . ')';
One likely explanation for this behavior is that sql_mode inclues (or enables) ANSI_QUOTES.
SELECT ##SESSION.sql_mode
If ANSI_QUOTES is enabled, then double quotes can't be used around string literals; whatever is between the double quotes will be interpreted as an identifier (e.g. column name). If ANSI_QUOTES is enabled, then string literals should be enclosed in single quotes.
For the love of all that is good and beautiful in this world, just use prepared statements with placeholders, to avoid issues with quotes and to thwart SQL injection vulnerabilities.
e.g.
$sql = "INSERT INTO installs (date,addedBy,customer, ...)
VALUES ( :date, :addedBy, :customer, ...)";
$sth = $connect->prepare($sql);
$sth->execute(array(':date' => $date, ':addedBy' => $addedBy, ':customer' => $customer, ... ));
I'm getting the error "SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens" when I try to run the below function:
public function find_products($string = '', $fields = array(), $sort_by = '', $sort_dir = 'ASC') {
$fields = empty($fields) ? '*' : ('' . implode(',', $fields) . '?');
$bindings = array('%' . $string . '%','%' . $string . '%','%' . $string . '%');
$and_where_checks = array('series','material');
$AND = '';
// Loop through the POST variables to see what is safe to play with
$allowed = array();
foreach ($and_where_checks as $awc)
if ( ! empty($_POST[$awc]))
$allowed = $awc;
if ( ! empty($allowed)) {
$tmp = array();
foreach ($allowed as $v)
$tmp = '' . $v . ' IN (' . str_pad('', count($v) * 2 - 1, '?,') . ')';
$AND = 'AND (' . implode(' AND ', $tmp) . ') ';
foreach ($allowed as $k)
foreach ($_POST[$k] as $v)
$bindings = $v;
}
$query =
"SELECT " . $fields . " FROM " . $this->product_table . " " .
"WHERE (" . $this->primary_key . " LIKE ? " .
$AND .
"ORDER BY " . $sort_by . " " . $sort_dir;
$sth = $this->$dbh->prepare($query);
$sth->execute($bindings);
return $sth->fetchAll(PDO::FETCH_ASSOC);
}
The $POST[$awc] variables are filled by checkboxes on this page http://ladd-dev.bitstormweb.com/products/interactive-product-finder/. When I choose one of each checkbox group (e.g. 1 Series and 1 Material) the results are fine, but when I choose multiple boxes in the same group, I get the PDOException.
Does anyone know why? I'm still learning this code so any help would be appreciated!
In your query, you only have one variable to be bound (the ?):
$query =
"SELECT " . $fields . " FROM " . $this->product_table . " " .
"WHERE (" . $this->primary_key . " LIKE ? " .
$AND .
"ORDER BY " . $sort_by . " " . $sort_dir;
Here, you must be either binding 0 or binding more than 1. Check how many values are in $bindings.
$sth = $this->$dbh->prepare($query);
$sth->execute($bindings);
You can check how many values are in $bindings by using print_r($bindings);
Update: Without knowing what your input is, your code seems to be using $bindings twice. It is set at the top with 3 values that are the same thing: $bindings = array('%' . $string . '%','%' . $string . '%','%' . $string . '%'); then at the bottom you have a foreach where you are not using an array at all:
foreach ($_POST[$k] as $v)
$bindings = $v;
I have a problem when trying to insert a new record into a database. The problem I think is with the bit field. When I assign the value True i get this error:
Failed: Array ( [0] => Array ( [0] => 22018 [SQLSTATE] => 22018 [1]
=> 245 [code] => 245 [2] => [Microsoft][SQL Server Native Client 10.0]
[SQL Server]Conversion failed when converting the varchar value ' 1 '
to data type bit. [message] => [Microsoft][SQL Server Native Client 10.0]
[SQL Server]Conversion failed when converting the varchar value ' 1 ' to
data type bit. ) )
but if i change it to false it works. I will show some of my code. I have cut out most of it as i have narrowed it down to this variable:
$active = True;
here is my insert query.
$sqlInsert = "INSERT INTO customers(
customerID,
registeredDate,
givenName,
familyName,
email,
password,
phone,
mobile,
property,
street,
locality,
town,
area,
postalCode,
active
)
VALUES(" .
$newUser . "," .
$date . ", ' " .
$given . " ', ' " .
$family . " ', ' " .
$email . " ', ' " .
$pwd . " ', ' " .
$phone . " ', ' " .
$mob . " ', ' " .
$property . " ', ' " .
$street . " ', ' " .
$locality . " ' , ' " .
$town . " ', ' " .
$area . " ', ' " .
$postalcode . " ', ' " .
$active . " ')";
$stmtInsert = sqlsrv_query($conn, $sqlInsert);
I assume that the active field is of bit data type.
You don't use any quotation marks around the value being passed for the active field like what you do for customerid field.
Also, I think you have to convert the value true / false to 1 / 0.
Modified code: Noticed that the single quotes surrounding " . $active . " have been removed.
$sqlInsert = "INSERT INTO customers(customerID, registeredDate, givenName,
familyName, email, password,
phone, mobile, property,
street, locality, town,
area, postalCode, active)
VALUES(" . $newUser . "," . $date . ", ' " . $given . " ',
' " . $family . " ', ' " . $email . " ', ' " . $pwd . " ',
' " . $phone . " ', ' " . $mob . " ', ' " . $property . " ',
' " . $street . " ', ' " . $locality . " ' , ' " . $town . " ',
' " . $area . " ', ' " . $postalcode . " ', " . $active . ")";
$stmtInsert = sqlsrv_query($conn, $sqlInsert);
I am not sure why it worked with False value. I would suggest you to find out how the INSERT statement evaluates to after setting all the values. Instead of executing the statement, print the INSERT statement to screen/page and run it manually in the SQL Server Management Studio against the database.
I use Zend Framework in my project. I need to insert multiple records and I found that Zend_Db suprisingly slower thatn my_sql query (several times), that made me think I did something wrong.
Here are two examples.
Zend_Db_Adapter:
$startTime = microtime(true);
$db = Zend_Db_Table::getDefaultAdapter();
$db->beginTransaction();
$dateAdded = date('Y-m-d H:i:s');
$lastChanged = $dateAdded;
foreach ($importDataNamespace->data as $subscriberNum => $subscriber)
{
foreach ($fieldsMap as $fieldNumber => $fieldTag) {
if (isset($subscriber[$fieldNumber])) {
$subscriberData[$fieldTag] = $subscriber[$fieldNumber];
} else {
$subscriberData[$fieldTag] = '';
}
}
$query = 'INSERT INTO subscribers (list_id, account_id, email_address, first_name, last_name, date_added, last_changed) ' .
'VALUES (' . 52 . ', ' . 29 . ', ' . $db->quote($subscriberData['EMAIL']) . ', ' . $db->quote($subscriberData['FNAME']) .
', ' . $db->quote($subscriberData['LNAME']) . ', ' . $db->quote($dateAdded) . ', ' . $db->quote($lastChanged) . ')';
$db->query($query);
}
$db->commit();
$this->view->time = microtime(true) - $startTime;
Example with mysql_query:
$startTime = microtime(true);
$user = 'root';
$password = 'password';
$db = 'database';
$connect = #mysql_connect('localhost',$user,$password) or die("Failed to connect database");
#mysql_select_db($db) or die("Failed to select database");
$dateAdded = date('Y-m-d H:i:s');
$lastChanged = $dateAdded;
$result = mysql_query('SET autocommit = 0');
foreach ($importDataNamespace->data as $subscriberNum => $subscriber)
{
foreach ($fieldsMap as $fieldNumber => $fieldTag) {
if (isset($subscriber[$fieldNumber])) {
$subscriberData[$fieldTag] = $subscriber[$fieldNumber];
} else {
$subscriberData[$fieldTag] = '';
}
}
$query = 'INSERT INTO subscribers (list_id, account_id, email_address, first_name, last_name, date_added, last_changed) ' .
'VALUES (' . 52 . ', ' . 29 . ', \'' . mysql_real_escape_string($subscriberData['EMAIL']) . '\', \'' . mysql_real_escape_string($subscriberData['FNAME']) .
'\', \'' . mysql_real_escape_string($subscriberData['LNAME']) . '\', \'' . $dateAdded . '\', \'' . $lastChanged . '\')';
mysql_query($query);
}
$result = mysql_query('SET autocommit = 1');
$result = mysql_query('COMMIT;');
$this->view->time = microtime(true) - $startTime;
In the first case it took 14.8 seconds, in the second 3.7.
Could you tell me why does it happend and what do you do wrong?
If I delete any quote for Zend_Db it took 12 seconds from 14 with quote, but it's still much more slower than with mysql_query:
$startTime = microtime(true);
$db = Zend_Db_Table::getDefaultAdapter();
$db->beginTransaction();
$dateAdded = date('Y-m-d H:i:s');
$lastChanged = $dateAdded;
foreach ($importDataNamespace->data as $subscriberNum => $subscriber)
{
foreach ($fieldsMap as $fieldNumber => $fieldTag) {
if (isset($subscriber[$fieldNumber])) {
$subscriberData[$fieldTag] = $subscriber[$fieldNumber];
} else {
$subscriberData[$fieldTag] = '';
}
}
$query = 'INSERT INTO subscribers (list_id, account_id, email_address, first_name, last_name, date_added, last_changed) ' .
'VALUES (' . 52 . ', ' . 29 . ', \'' . $subscriberData['EMAIL'] . '\', \'' . $subscriberData['FNAME'] .
'\', \'' . $subscriberData['LNAME'] . '\', \'' . $dateAdded . '\', \'' . $lastChanged . '\')';
$db->query($query);
}
$db->commit();
$this->view->time = microtime(true) - $startTime;
Thank you for any information about this issue.
This code takes about 0.065 seconds with mysql_query:
$dateAdded = date('Y-m-d H:i:s');
$lastChanged = $dateAdded;
$startTime = microtime(true);
$result = mysql_query('BEGIN');
for ($i = 0; $i < 100; $i++) {
$email = 'test_ ' . $i . '#gmail.com';
$query = 'INSERT INTO subscribers (list_id, account_id, email_address, first_name, last_name, date_added, last_changed) ' .
'VALUES (' . 52 . ', ' . 29 . ', \'' . mysql_real_escape_string($email) . '\', \'' . mysql_real_escape_string($firstName) .
'\', \'' . mysql_real_escape_string($lastName) . '\', \'' . mysql_real_escape_string($dateAdded) . '\', \'' . mysql_real_escape_string($lastChanged) . '\')';
mysql_query($query);
}
$result = mysql_query('COMMIT');
$time = microtime(true) - $startTime;
echo 'Using mysql_query: ' . $time . '<br />';
exit();
Code with benchmark of Zend_Db_Adapter (I didn't even use quote in this case):
$db = Zend_Db_Table::getDefaultAdapter();
$db->getProfiler()->setEnabled(true);
$profiler = $db->getProfiler();
$startTime = microtime(true);
$db->beginTransaction();
for ($i = 0; $i < 100; $i++)
{
$email = 'test_' . $i . '#gmail.com';
$query = 'INSERT INTO subscribers (list_id, account_id, email_address, first_name, last_name, date_added, last_changed) ' .
'VALUES (' . 52 . ', ' . 29 . ', \'' . $email . '\', \'' . $firstName .
'\', \'' . $lastName . '\', \'' . $dateAdded . '\', \'' . $lastChanged . '\')';
$db->query($query);
}
$db->commit();
$time = microtime(true) - $startTime;
echo 'Time of transaction Zend_Db_Adapter query: ' . $time . '<br />';
echo 'Total time ' . $profiler->getTotalElapsedSecs() . '<br />';
$count = 0;
$totalTime = 0;
foreach ($profiler->getQueryProfiles() as $query) {
$count++;
$elapsedTime = $query->getElapsedSecs();
$totalTime += $elapsedTime;
echo $count . ' ' . $elapsedTime . ' ' . $query->getQuery() . '<br />';
}
echo 'Sum time: ' . $totalTime . '<br />';
Here are some results:
Time of transaction Zend_Db_Adapter query: 0.23094701767
Total time 0.0949234962463
1 0.00199699401855 connect
2 0.000336885452271 begin
3 0.000540018081665 INSERT INTO subscribers (list_id, account_id, email_address, first_name, last_name, date_added, last_changed) VALUES (52, 29, 'test_0#gmail.com', 'John', 'Clinton', '2011-01-28 15:25:21', '2011-01-28 15:25:21')
4 0.000504016876221 INSERT INTO subscribers (list_id, account_id, email_address, first_name, last_name, date_added, last_changed) VALUES (52, 29, 'test_1#gmail.com', 'John', 'Clinton', '2011-01-28 15:25:21', '2011-01-28 15:25:21')
It's very strange. The time of transacation to insert 100 records is 2.5 times more than executing of all queries.
If I try to meach the time of forming strings in the loop it (if we delete query) doesn't take so much time.
I think that one reason is that you execute $db->quote() too many times, which is unnecessary. Do you know that $db->quote() can take an array as its argument and you can basically reduce calls to $db->quote() to only one. In addition in your mysql_query version you do not escape $dateAdded and $lastChanged, while in zend_db version you do.
EDIT: Added an example below
$db = Zend_Db_Table::getDefaultAdapter();
$input = array(
'a' => "asd'lfksd",
'b' => "asdlfk'sdfasdf",
'c' => "asd fds f saf'sdfsd",
'd' => "asd fds f saf'sdfsd"
);
// separate calls to quote
$startTime = microtime(true);
$db->quote($input['a']);
$db->quote($input['b']);
$db->quote($input['c']);
$db->quote($input['d']);
$totalTime1 = microtime(true) - $startTime;
// one call to quote
$startTime = microtime(true);
$db->quote($input);
$totalTime2 = microtime(true) - $startTime;
// show results
var_dump("Sperate calls are ". $totalTime1/$totalTime2 . " times slower");
//output: string 'Sperate calls are 3.0875831485588 times slower' (length=46)
mysql_* functions are natives to PHP , so they are very fast.
Zend_Db_Adapter is working with PDO so you have a first absraction layer with PDO and a second with Zend_DB_Adapter.
More layer abstraction you 've got , more the code is slowing down.
That why the MVC framework in general are more slower than procedural code.
Try again your benchmark with prepared statement and a cache mechanism and you should be close of the mysql_* functions
This looks like you don't have a metadata cache in Zend_Db.