This code works if i run in a browser. When i run the script via a cron, it doesn't get through the array and stops halfway? Why is this?
$url_array = array("eur-gbp","eur-aud","usd-chf","eur-usd","eur-jpy","gbp-jpy","eur-cad","eur-chf","usd-cad","usd-jpy","cad-chf","cad-jpy","gbp-usd","aud-usd","gbp-chf","chf-jpy","gbp-cad","aud-cad","aud-chf","aud-jpy","aud-nzd","eur-nzd","gbp-aud","gbp-nzd","nzd-chf","nzd-usd","nzd-cad","nzd-jpy");
$option_array = array(1,2,3,4,5,6,7);
$type_array = array(1,2,3,4,5,6);
foreach($url_array as $url_type) {
//code
foreach($option_array as $option) {
//code
foreach($duration_array as $duration) {
//code
foreach($type_array as $type) {
//mysql insert
$sql = "SELECT * FROM `data_analysis` WHERE date_time='".$date."' AND type='".$url_type."' LIMIT 1";
$query = $this->db->query($sql);
$result = $query->fetch_assoc();
if($result){
$sql = "UPDATE `data_analysis` SET value='".$percentage."', price_change='".$price."', parent='1' WHERE date_time='".$date."' AND type='".$url_type."'";
} else {
$sql = "INSERT IGNORE INTO `data_analysis` (date_time,value,price_change,type,parent) VALUES ('".$date."','".$percentage."','".$price."','".$url_type."','1')";
}
}
}
}
}
This isn't the exact code as it is too long to post but similar. The code works perfectly in the browser?? running via cron it stops at gbp-jpy? Why is this?
Is there a mysql query limit?
Add a unique index on (type, date_time) to the table. Then combine your two queries into 1. Also, use a prepared statement.
$stmt = $this->db->prepare("
INSERT INTO data_analysis (date_time, value, price_change, type, parent)
VALUES (?, ?, ?, ?, '1')
ON DUPLICATE KEY UPDATE value = VALUES(value), price_change = VALUES(price_change), parent = VALUES(parent)");
$stmt->bind_param("ssss", $date, $percentage, $price, $url_type);
foreach($url_array as $url_type) {
//code
foreach($option_array as $option) {
//code
foreach($duration_array as $duration) {
//code
foreach($type_array as $type) {
//mysql insert
$stmt->execute();
}
}
}
}
Related
I would appreciate if somebody could help me solve my problem with inserting data from xml file into the database. I want to prevent adding duplicate rows in my database after refreshing the page. Here is my code:
public function getAll() {
$xml = new DOMDocument();
$xml->load('newXMLDocument.xml');
$xmldata = $xml->getElementsByTagName('book');
$xmlcount = $xmldata->length;
for($i=0; $i< $xmlcount; $i++){
$author = $xmldata->item($i)->getElementsByTagName('author')->item(0)->childNodes->item(0)->nodeValue;
$name = $xmldata->item($i)->getElementsByTagName('name')->item(0)->childNodes->item(0)->nodeValue;
try {
$statement = self::$db->prepare("INSERT INTO `books`( `Author`, `Name`) values( ?, ?) ");
$statement->bindParam(1, $id);
$statement->bindParam(2, $author);
$statement->bindParam(3, $name);
$statement->execute(array(
$author,
$name
));
} catch (PDOException $e) {
echo $e->getMessage();
}
}
}
inside your for loop, and before insert data, run query to check if values exists before submitting, then run if statement to prevent running insert query if row exists
for loop
$query = 'SELECT `Author`,`Name` from `table` where `Author` = $author AND `Name` = $name';
if($query != null){
insert new row
}
end for loop
For example, I have a couple of tables in my database, e.g., user, product, etc. Fro every table, I have at least an associated class with a couple of methods, such as addUser, updateUserName, updateUserPassword, etc. For every method, I need to prepare the SQL when using PDO, which looks like this:
$sql = "INSERT INTO `user`
(`id`,`username`,`password`,`log`)
VALUES
(:id, :username, :password, :log)";
Then I store the values in an array like this:
$array = array('id'=>$id, 'username'=>$username, 'password'=>$password, 'log'=>$log);
Then I use the PDO thing:
$pdo = new PDO($dsn, $user, $password);
$mysql = $pdo->prepare($sql);
$mysql->execute($array);
So it seems that for all different methods inside the User class, I need to do this "prepare" thing. Isn't it too tedious? Is there a more efficient way to do so, especially the part where I store the values in an array considering there exist a table with many columns in which case I would end up with a very long prepare sentence?
Since Your own is insert and update try these
//to query the database with prepared statements
public function query ($sql, $parameters = array()) {
//setting error to false to prevent interferance from previous failed queries
$this->_error = false;
//prepare SQL statement
if ($this->_query = $this->_pdo->prepare ($sql)) {
//checking to see whether any parameters were submitted along
if (count($parameters)) {
//setting the initial position for the binding values
$position = 1;
//getting the individual parameters and binding them with their respective fields
foreach ($parameters as $param) {
$this->_query->bindValue ($position, $param);
$position++;
}
}
}
//executing the sql
if ($this->_query->execute()) {
//getting the number of rows returned
$this->_count = $this->_query->rowCount();
//keeping the results returned
$this->_results = $this->_query->fetchAll (PDO::FETCH_OBJ);
} else {
$this->_error = true;
}
//returning all values of $this
return $this;
}
//to insert data into a prescribed table
public function insert ($table, $parameters = array()) {
//checking if the $fields are not empty
if (count($parameters)) {
//making the keys of the array fields
$fields = array_keys ($parameters);
//creating the to-bind-values in the form (?, ?, ...)
$values = '';
$x = 1;
foreach ($parameters as $field => $value) {
//$value is different from $values
$values .= '?';
if ($x < count($parameters)) {
$values .= ', ';
$x++;
}
}
//generating $sql
$sql = "INSERT INTO `{$table}` (`".implode ('`, `', $fields)."`) VALUES ({$values})";
//executing the sql
if (!$this->query($sql, $parameters)->error()) {
return true;
}
}
return false;
}
//to update data in a prescribed table
public function update ($table, $id = null, $parameters = array()) {
//checking that $parameters is not an empty array
if (count($parameters)) {
$set = '';
$x = 1;
foreach ($parameters as $field => $value) {
$set .= "`{$field}` = ?";
if ($x < count($parameters)) {
$set .= ', ';
$x++;
}
}
if ($id) {
//generating query
$sql = "UPDATE `{$table}` SET {$set} WHERE `id` = {$id}";
} else {
$sql = "UPDATE `{$table}` SET {$set} WHERE 1";
}
//executing the query
if (!$this->query($sql, $parameters)->error()) {
return true;
}
}
return false;
}
Am trying to save the result of multiple check-boxes as separate records. my code is not functioning. please help!
<?php
session_start();
$id = $_SESSION['user_id'];
$db = new PDO('mysql:host=localhost;dbname=idp;charset=utf8','root', '');
foreach($_POST['comp'] as $val){
$tmp['user_id'] = $id;
$tmp['comp_id'] = $val;
$vars[] = $tmp;
}
$qry = "INSERT INTO compentency_result (user_id, result) VALUES (:user_id, :comp_id)";
try
{
$sql = $db->prepare($qry);
$numRows = 0;
foreach($vars as $insert){
$numRows += $sql->execute($insert);
}
print("<p>There were {$numRows} inserted into the database!</p>");
}
catch(PDOException $e)
{
print("<p>Oops! There was an issue - this is the message: {$e->getMessage()}</p>");
}
?>
The result is showing me that nothing is added to the database.
To bind the parameters individually you would do this:
try
{
$sql = $db->prepare($qry);
$numRows = 0;
foreach($vars as $insert){
$sql->bindParam(':user_id', $insert['user_id'], PDO::PARAM_STR);
$sql->bindParam(':comp_id', $insert['comp_id'], PDO::PARAM_STR);
$sql->execute();
$numRows += $sql->rowCount(); // get the rows affected this way
}
echo "<p>There were {$numRows} inserted into the database!</p>";
}
In addition, I added a more proper and reliable method of getting the affected rows, using rowCount().
If you don't want to bind the elements individually you can use execute() with an array as shown in Demystifying PDO
I insert data into a table called 'roster'. The first column (id_roster) is an id using mysql auto-increment.
I run a SELECT to find the id_roster
I use this id_roster to insert it into a table 'roster_par_membre' along with other data
if ($insert_stmt = $mysqli->prepare("INSERT INTO `roster`(`nom_roster`, `description_roster`, `id_organisation`, `created_by`, `creation_date`,`modified_by`) VALUES (?, ?, ?, ?, ?, ?)")) {
$insert_stmt->bind_param('ssiisi', $roster_name, $description_roster, $organisation_id, $user_id, $creation_date, $user_id);
if (!$insert_stmt->execute()) {
$reponse = 'Sorry, a database error occurred; please try later';
} else {
// if INSERT OK -> create a new line in roster_membre table
//1. get the roster_id
$sql = "SELECT r.id_roster
FROM roster r
WHERE r.nom_roster = ?
LIMIT 1";
$stmt = $mysqli->prepare($sql);
if ($stmt) {
$stmt->bind_param('s', $roster_name);
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
$stmt->bind_result($id_roster);
$stmt->fetch();
$level = 1;
//2. create a line with the roster_id and insert the membre as level 1
$insert_stmt = $mysqli->prepare("INSERT INTO `roster_par_membre`(`id_membre`, `id_roster`, `level`, `modified_by`) VALUES (?,?,?,?)");
$insert_stmt->bind_param('iiii', $user_id, $id_roster, $level, $user_id);
$insert_stmt->execute();
$reponse = 'success';
}
So far the code is working but it is not very nice.
Is there a way when we create a new line in a table to directly return a value (id with auto-increment) to be used in a sql query (to insert data into a second table)? or maybe to merge the two query (the two INSERT) in one statment?
short edit: it is an AJAX $response the return value (JSON)
Ok,solution:
//1. get the roster_id
$sql = "SELECT r.id_roster
FROM roster r
WHERE r.nom_roster = ?
LIMIT 1";
$stmt = $mysqli->prepare($sql);
if ($stmt) {
$stmt->bind_param('s', $roster_name);
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
$stmt->bind_result($id_roster);
$stmt->fetch();
Just need to replace all this part by
$id_roster = $mysqli->insert_id;
nice and easy. THANKS to albanx
these are the functions I used for query on projects that I do not want to use any framework (just php):
/**
*
* Executes query methods
* #param string $query the query string
* #param array $vals array of values
* #param bool $show show the query
* #return int/array/false
*/
function q($query, $vals=array(), $show_query=false)
{
$conn = new mysqli(...)
$offset = 0;
foreach ($vals as $v)
{
$cv = $conn->real_escape_string($v);//escape the value for avoiding sql injection
$fv = ($v===NULL) ? 'NULL':"'".$cv."'"; //if value is null then insert NULL in db
$qpos = strpos($query, '?', $offset);//replace the ? with the valeue
$query = substr($query, 0, $qpos).$fv.substr($query, $qpos+1);
$offset = $qpos+strlen($cv)+1;
}
$result = $conn->query($query);
if($show || $result===false) echo $query."<br>";
$rows = array();
if($result===true)
{
return $conn->affected_rows;
}
else if($result===false)
{
return false;
}
else
{
while ($row = $result->fetch_array(MYSQLI_ASSOC) )
{
$rows[]=$row;
}
}
return $rows;
}
function lastid()
{
return $this->qval("SELECT LAST_INSERT_ID()");
}
Usage example:
q('INSERT INTO USER(name, email) VALUES(?,?)', array('admin','admin#admin.com'));
$id = lastid();
i need somehow to check if field exist in db, and then if exist, just update price, if not, insert fields. I am using simplxml for parsing data to db from xml.
here is my code without if statement, just insert into two databese.
I need to check from db products if ident exist, so if not exist, do all that code down, if exist just update price in db products
foreach ($lib->product as $data) {
$manufacturer = (string) $data->manufacturer;
$ident = (string) $data->id;
$name = (string) $data->name;
$category = (string) $data->category;
$subcategory = (string) $data->subcategory;
$price = (int) ($data->price * 1.2 * 1.4 * 1.1);
$image = (string) $data->images->image[0];
$insert = $db->prepare('INSERT INTO products (ident, manufacturer,name,category,subcategory,price,image) VALUES (?, ?, ?, ?, ?, ?, ?)');
$insert->bind_param('sssssss', $ident, $manufacturer, $name, $category, $subcategory, $price, $image);
$insert->execute();
foreach($data->specifications->attribute_group as $group) {
$attribute_group = (string) $group->attributes()['name'];
foreach($group as $attr) {
$attribute = (string) $attr->attributes()['name'];
$value = (string) $attr->value;
$insert = $db->prepare('INSERT INTO spec (attr_group,attr_name, attr_value, product_id) VALUES (?, ?, ?, ?)');
$insert->bind_param('ssss', $attribute_group, $attribute, $value, $ident);
$insert->execute();
}
}
}
To do in one query, look up MySQL's ON DUPLICATE KEY UPDATE functionality for INSERT.
Then use $insert->rowCount() if you're using PDO or $insert->affected_rows for mysqli.
If the first insert tried to already insert a key that existed and updates a value, then rowCount()/affected_rows will be 2; if it just inserted a record then rowCount()/affected_rows will be 1. It will be 0 if the INSERT was unsuccessful.
e.g. for PDO:
switch($insert->rowCount()) {
case 2: // UPDATE occurred thanks to 'ON DUPLICATE UPDATE KEY'
// SOME CODE HERE IF YOU LIKE
break;
case 1: // INSERT occurred as no duplicate
// CODE TO INSERT INTO SECOND TABLE
break;
case 0:
default:
// NEITHER THE ABOVE OCCURRED SO CODE TO HANDLE ERROR
}
$query = "SELECT * name FROM yourtable";
$bool = true;
if($r = #mysql_query($query))
{
while($row = #mysql_fetch_array($r))
{
if( ($row['id'] == $id))
{
$bool = false;
break;
}
}
}
if($bool) {
UPDATE
}
else
{
INSERT
}