FOREACH and UPDATE mysql not working - php

I have a select query followed by a an update query inside a foreach loop.
I can get the data from the select and I use it as json to draw a chart, but for the other table that should be updated with the same data from select, the specified filed become 0 sometimes 1 or 2 !!
I tried to use a select for update and it OK (update .... (select ....)) but inside foreach it doesn't work.
I tried also to use other columns but the same result, always I get 0.
Any idea please ?
Many thanks in advance
this is my code
public function actionGetSensorsDataLive($beamId) {
header('Content-Type: application/json; charset="UTF-8"');
$sensorsIds = Sensor::model()->findAllBySql('SELECT sensor_id FROM sensor where
node_id="' . $beamId . '" and sensor_name = "I" ;');
foreach ($sensorsIds as $s) {
$sResult = array();
$modelSensor = SensorInfo2::model()->findBySql('SELECT * FROM information_sensor
where sensor_id= "' . $s['sensor_id'] . '"');
$sResult = array(($modelSensor->information_sensor_time),
($modelSensor->information_sensor_value));
/////////////// update////////////////
// for every information_sensor_time that I get from the previous query
// I want
// to update a row in another table //
foreach ($modelSensor as $up) {
$connection = yii::app()->db;
$sql = 'UPDATE last_point SET last_point_time = "' .
$up['information_sensor_time'] . '"
WHERE sensor_id= "' . $s['sensor_id'] . '" ';
$command = $connection->createCommand($sql);
$command->execute();
}
/////update end///////
}
echo json_encode($sResult);
Yii::app()->end();
}

$sensorsIds=Sensor::model()->findAllBySql('SELECT sensor_id FROM lead where
node_id="'.$beamId.'" and sensor_name = "I" ;' );
Remove ;
$sensorsIds=Sensor::model()->findAllBySql('SELECT sensor_id FROM lead where
node_id="'.$beamId.'" and sensor_name = "I"' );
Now try this.

You are using findBySql()` which only returns one record and then doing a foreach on tha makes no sense. so cheng the line
$modelSensor = SensorInfo2::model()->findBySql('SELECT * FROM information_sensor
where sensor_id= "' . $s['sensor_id'] . '"');
to
$modelSensor = SensorInfo2::model()->findAllBySql('SELECT * FROM information_sensor
where sensor_id= "' . $s['sensor_id'] . '"');
And you shoud use querybuilder which is far secure as suggested by Alex

finally I used this code
foreach ($sensors as $sensor) {
$lastPointId = 1;
$lastPoint = LastPoint::model()->findByPk($lastPointId);
$lastPoint->last_point_info = $sensor->information_time;
if ( ! $lastPoint->save()) {
throw new CException('Unable to save last point.');
}
}
Thanks for all

Related

Is there any way to find out duplicates value in mysql while inserting records?

I read many questions but i didn't found my solution to my question.
My concern:
I am inserting new records in My SQL, using foreach loop in PHP. So, before inserting is there any way to find out, the records i am inserting in my sql is already present or not. If it is present then it should return "ALREADY EXIST".
AS PER MY CODE:
As i am using FOR-EACH LOOP , i want which qstonesid is already exist in my sql tbl_stickering.
If exist then it should return ECHO "$qstonesid already exist" and if $qstonesid not exist then call my STORED PROCEDURE sp_stickering.
I hope i made my concern clear, and i am totally new to PHP and mySql, any help will be appreciated,
Below, I am sharing my PHP code
<?php
error_reporting(E_ERROR | E_PARSE);
include "config.php";
$stones = $_POST['stones'];
//echo json_encode($stones, true);
$StoneArr = json_decode($stones, true);
$updstmt = '';
foreach ($StoneArr as $Stone)
{
$currentdate=!empty( $Stone['currentdate'] ) ? $Stone['currentdate'] : '0000-00-00 00:00:00';
$qstonesid=$Stone['qstonesid'];
$clientname = $_REQUEST['clientname'];
$empid = $_REQUEST['empid'];
$updstmt .= 'CALL sp_stickering('.'"'.$currentdate.'"'.',
'.'"'.$clientname.'"'.',
'.'"'.$qstonesid.'"'.',
'.'"'.$empid.'"'.'
);';
}
//echo $updstmt;
$res = query($updstmt);
if (strlen($res) > 0) {
echo $res;
} else {
echo 'Records added successfully...';
}
below is my Stored Procedure I am using,
CREATE DEFINER=`root`#`%` PROCEDURE `sp_stickering`(
IN `_sdate_stickering` DATETIME,
IN `_client_name` VARCHAR(100),
IN `_qstonesid` VARCHAR(100),
IN `_empid` INT
)
BEGIN
IF EXISTS (SELECT qstonesid FROM tbl_stickering WHERE qstonesid = _qstonesid AND client_name = _client_name) THEN
BEGIN
UPDATE tbl_stickering SET empid = _empid WHERE qstonesid = _qstonesid AND client_name = _client_name;
END;
ELSE
BEGIN
INSERT INTO tbl_stickering
(sdate_stickering, client_name, qstonesid, empid)
VALUES
(_sdate_stickering, _client_name, _qstonesid, _empid);
END;
END IF;
END
One approach would be to retrieve a listing of qstonesid from the array and check the database prior to calling the procedure.
To get a list of qstonesid values from $StoneArr you can use array_column.
$ids = array_column($StoneArr, 'qstonesid');
Next retrieve the listing of those $ids that exists in the database and build another listing of those that exist.
I am not sure what database extension you are using, but I presume something like this. See the working example link below for a PDO demonstration with prepared statements.
$rs = query('SELECT qstonesid FROM tbl_stickering WHERE qstonesid IN(' . implode(',', $ids) . ')');
$exists = array_column($rs, 'qstonesid');
if qstonesid is an array of string values, you can wrap each value with quotes by using.
'"' . implode('","', $ids) . ') . '"';
Lastly in your foreach loop use in_array to check in your resulting $exists array for the $Stone['qstonesid'] and use continue to move on to the next iteration if it is.
Working Example: https://3v4l.org/eJXu5
foreach ($StoneArr as $Stone) {
if (in_array($Stone['qstonesid'], $exists)) {
echo $Stone['qstonesid'] . ' Already Exists.';
continue;
}
//...
}
Full Example:
$stones = $_POST['stones'];
$StoneArr = json_decode($stones, true);
//retrieve listing of submitted qstonesid values
$StoneArrIds = array_column($StoneArr, 'qstonesid');
//retrieve listing of existing qstonesid
/**
* modify to suit your database extension
* !! Subject to SQL Injection !!
* !! HIGHLY RECOMMEND USING PREPARED STATEMENTS !!
*/
$rs = query('SELECT qstonesid
FROM tbl_stickering
WHERE client_name = "' . $_REQUEST['clientname'] . '"
AND qstonesid IN("' . implode('","', $StoneArrIds) . '")');
$exists = array_column($rs, 'qstonesid');
$updstmt = '';
foreach ($StoneArr as $Stone) {
//qstonesid already exists, display a message and skip insertion
if (in_array($Stone['qstonesid'], $exists)) {
echo $Stone['qstonesid'] . ' already exist';
continue;
}
$currentdate= !empty($Stone['currentdate'] ) ? $Stone['currentdate'] : '0000-00-00 00:00:00';
$qstonesid = $Stone['qstonesid'];
$clientname = $_REQUEST['clientname'];
$empid = $_REQUEST['empid'];
$updstmt .= 'CALL sp_stickering('.'"'.$currentdate.'"'.',
'.'"'.$clientname.'"'.',
'.'"'.$qstonesid.'"'.',
'.'"'.$empid.'"'.'
);';
}
if ($updstmt) {
$res = query($updstmt);
if (strlen($res) > 0) {
echo $res;
} else {
echo 'Records added successfully...';
}
}

Dynamic "Where" clause in wpdb->prepare query

In the form, none of the inputs are mandatory. So, I want to have a dynamic "where" clause inside the wpdb query.
Presently this is the query:
$data = $wpdb->get_results($wpdb->prepare("SELECT * FROM
`wp_gj73yj2g8h_hills_school_data` where
`school_zipcode` = %d AND `school_type` = %s AND `school_rating` = %s
;",$selectedZip,$selectedType,$selectedRating));
if a user enters only school_zipcode then the where clause should have only "school_zipcode" column.
Same way for other combinations.
I would not make things complicated with dynamic where clauses... I would write PHP code which creates the query. For example...
NOTE!! THIS CODE IS NOT TESTED ON SERVER, IT'S JUST AN IDEA HOW TO SOLVE THE PROBLEM!
<?php
$where_query = array();
// Make sure to escape $_POST
if (!empty($_POST['school_zipcode')) {
$where_query[] = "school_zipcode='" . $_POST['school_zipcode'] . "'";
}
// Make sure to escape $_POST
if (!empty($_POST['school_type')) {
$where_query[] = "school_type='" . $_POST['school_type'] . "'";
}
// Should result in WHERE school_zipcode='123' AND school_type='text'
$where_query_text = " WHERE " . implode(' AND ', $where_query);
$data = $wpdb->get_results($wpdb->prepare("SELECT * FROM `wp_gj73yj2g8h_hills_school_data` " . $where_query_text . ";"));

Extracting an array into dynamic variables

I am trying to be lazy (or smart): I have 7 checkboxes which correlate with 7 columns in a MySQL table.
The checkboxes are posted in an array:
$can = $_POST['can'];
I've created the following loop to dump the variables for the MySQL insert:
for($i=1;$i<8;$i++){
if($can[$i] == "on"){
${"jto_can".$i} = 'Y';
}
else{
${"jto_can".$i} = 'N';
}
}
print_r($jto_can1.$jto_can2.$jto_can3.$jto_can4.$jto_can5.$jto_can6.$jto_can7);
This correctly outputs:
YYNYYYY
However, when I attempt to use those variables in my MySQL update, it doesn't accept the changes.
mysqli_query($db, "UPDATE jto SET jto_can1 = '$jto_can1', jto_can2 = '$jto_can2', jto_can3 = '$jto_can3', jto_can4 = '$jto_can4', jto_can5 = '$jto_can5', jto_can6 = '$jto_can6', jto_can7 = '$jto_can7' WHERE jto_id = '$id'")or die(mysqli_error($db));
Can anyone explain why the print_r displays the variables whereas MySQL update does not?
Stick with the array, and form the query dynamically:
$sql = 'UPDATE jto SET ';
$cols = array();
foreach( range( 1, 7) as $i) {
$value = $_POST['can'][$i] == 'on' ? 'Y' : 'N'; // Error check here, $_POST['can'] might not exist or be an array
$cols[] = 'jto_can' . $i . ' = "' . $value . '"';
}
$sql .= implode( ', ', $cols) . ' WHERE jto_id = "' . $id . '"';
Now do a var_dump( $sql); to see your new SQL statement.
this is not a mysql problem. mysql will only see what you put into that string. e.g. dump out the query string BEFORE you do mysql_query. I'm guessing you're doing this query somewhere else and have run into scoping problems. And yes, this is lazy. No it's not "smart". you're just making MORE work for yourself. What's wrong with doing
INSERT ... VALUES jto_can1=$can[0], jto_can2=$can[1], etc...

Change Static SQL update to dynamic based on changing column names

Ok, I asked a question last night and received a number of really great responses. Since that was my first time using StackOverflow I was really pleased.
I'm hoping you guys can help with a new one. Hopefully, down the road, I'll be able to repay the favor to some NEW newbies.
I have the following code in a php file:
$sql = "";
$now=date("Y-m-d h:i:s");
$updatedRecords = $json1->{'updatedRecords'};
foreach ($updatedRecords as $value){
$sql = "update `acea` set ".
"`ACEA_A1`='".$value->ACEA_A1 . "', ".
"`ACEA_A2`='".$value->ACEA_A2 . "', ".
"`ACEA_A3`='".$value->ACEA_A3 . "', ".
"`ACEA_A4`='".$value->ACEA_A4 . "', ".
"`ACEA_A5`='".$value->ACEA_A5 . "', ".
"`ACEA_B1`='".$value->ACEA_B1 . "', ".
"`ACEA_B2`='".$value->ACEA_B2 . "', ".
"`ACEA_B3`='".$value->ACEA_B3 . "', ".
"`ACEA_B4`='".$value->ACEA_B4 . "', ".
"`ACEA_B5`='".$value->ACEA_B5 . "', ".
"`ACEA_E1`='".$value->ACEA_E1 . "', ".
"`ACEA_E2`='".$value->ACEA_E2 . "', ".
"`ACEA_E3`='".$value->ACEA_E3 . "', ".
"`ACEA_E4`='".$value->ACEA_E4 . "', ".
"`ACEA_E5`='".$value->ACEA_E5 . "', ".
"`ACEA_E7`='".$value->ACEA_E7 . "' ".
"where `acea_id`=".$value->acea_id;
if(mysql_query($sql)==FALSE){
$errors .= mysql_error();
}
}
The "ACEA_XX" portions relate to columns in the "acea" database table (obviously), but the programmer set them statically. Unfortunately, these columns need to be added to periodically, with new columns being created related to the new ACEA specs that are introduced.
As a result, this code becomes outdated.
Without having to go in and update this code each time I add a new column, how can I redesign this code so that it updates itself dynamically to include the new columns? I've been trying all morning to make it work, and I can set it so that I can dynamically insert the actual column names into the update statement, but, I can't seem to dynamically grab the associated values dynamically (and I think my method for grabbing and inserting the column names is a little convoluted).
My actual database table columns are currently:
acea_id ACEA_A1 ACEA_A2 ACEA_A3 ACEA_A4 ACEA_A5 ACEA_B1 ACEA_B2 ACEA_B3 ACEA_B4 ACEA_B5 ACEA_E1 ACEA_E2 ACEA_E3 ACEA_E4 ACEA_E5 ACEA_E6 ACEA_E7 ACEA_E9 oil_data_id
The first and last columns will never change and will continue to be the first and last columns. Any new columns will be added somewhere in between, but not necessarily immediately preceding the "oil_data_id" column.
I've tried revising the code numerous ways in order to properly grab the values, but just can't make it work.
Anyone have a concise modification to the code to do what I want? It would be greatly appreciated.
Seems like Doug Kress' method spits some errors out so here is my shot:
$errors = array();
foreach($json1->updatedRecords as $record)
{
$fields = array();
foreach($record as $field => $value)
{
if(substr($field, 0, 5) === 'ACEA_')
{
$fields[] = $field.' = '.mysql_real_escape_string($value);
}
}
// Check if there are any fields set to be updated.
if(isset($fields[0]))
{
// I'm assuming $record->acea_id is an integer. If not,
// replace '%d' with '%s'.
$sql = "UPDATE `acea` SET %s WHERE `acea_id` = '%d';";
$sql = sprintf($sql, implode(',', $fields), $record->acea_id);
if(mysql_query($sql) === false)
{
$errors[] = mysql_error();
}
}
}
First, I would highly recommend making that into a separate table (turning the data 'sideways', if you will). Assuming that's not feasible:
$sql = "";
$updatedRecords = $json1->{'updatedRecords'};
foreach ($updatedRecords as $values){
$flist = array();
$params = array();
foreach ($values as $key => $value) {
if (preg_match('/^ACEA_[A-Z]+\d+$/', $key)) {
$flist[] = $key .'="%s"';
$params[] = mysql_real_escape_string($value);
}
}
$sql = "update `acea` set ". implode(', ', $flist) .
"WHERE `acea_id`='%s'";
$params[] = mysql_real_escape_string($value->acea_id);
$sql = sprintf($sql, $params);
if(mysql_query($sql)==FALSE){
$errors .= mysql_error();
}
}

insert multiple rows into database from arrays

i need some help with inserting multiple rows from different arrays into my database.
I am making the database for a seating plan, for each seating block there is 5 rows (A-E) with each row having 15 seats.
my DB rows are seat_id, seat_block, seat_row, seat_number, therefore i need to add 15 seat_numbers for each seat_row and 5 seat_rows for each seat_block.
I mocked it up with some foreach loops but need some help turning it into an (hopefully single) SQL statement.
$blocks = array("A","B","C","D");
$seat_rows = array("A","B","C","D","E");
$seat_nums = array("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15");
foreach($blocks as $block){
echo "<br><br>";
echo "Block: " . $block . " - ";
foreach($seat_rows as $rows){
echo "Row: " . $rows . ", ";
foreach($seat_nums as $seats){
echo "seat:" . $seats . " ";
}
}
}
Maybe there's a better way of doing it instead of using arrays?
i just want to avoid writing an SQL statement that is over 100 lines long ;)
(im using codeigniter too if anyone knows of a CI specific way of doing it but im not too bothered about that)
try
<?php
$blocks = array("A","B","C","D");
$seat_rows = array("A","B","C","D","E");
$seat_nums = array("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15");
foreach($blocks as $block){
foreach($seat_rows as $rows){
foreach($seat_nums as $seats){
$querys[] = "('" . $block "','" . $rows . "', '" . $seats . "' )";
}
}
}
$query_inserts = join ( ", ", $querys );
$query = "
INSERT INTO
table
( block, rows, seats )
VALUES
" . $query_inserts . "
";
mysql_query ($query);
?>
One solution is to use prepared statements:
$pdo = new PDO('mysql:dbname=mydb', 'myuser', 'mypass');
$stmt = $pdo->prepare('INSERT INTO seats
(seat_id, seat_block, seat_row, seat_number)
VALUES (?,?,?,?);
');
foreach (...) {
$stmt->execute(array($seat_id, $seat_block, $seat_row, $seat_number));
}

Categories