php sql UPDATE with nested FROM (SELECT) - php

After hours of trying I need your advice.
I want to combine rows from 2 tables.
After I created a new row in table1 I want to find a row in table2 and combine some of the fields.
If I put the nested SELECT in the SET function
(SET postcode=(SELECT etc)
is works, but if I put it in the FROM function is gives an Error that the syntax is wrong
my code:
$sql = "INSERT INTO instanties(institution, category, postcode)
VALUES('$emapData[0]', '$emapData[1]', '$emapData[2]')";
if ($conn->query($sql) === TRUE) {
//get last added id
$last = $conn->insert_id;
//define WHERE function
$where="postcode_id=$postcode_id AND (minnumber <= $number AND maxnumber >= $number)";
//UPDATE last added row in table with info from other table
$sql2 = "UPDATE instanties
SET postcode_id=pc.postcode_id
FROM
(
SELECT postcode_id
FROM postcode
WHERE $where LIMIT 1
) pc
WHERE id=$last";
$result = $conn->query($sql2);
if ($result) {
echo 'update is done<br/><br/>';
}
}
else {
echo "Error: " . $sql2 . "<br>" . $conn->error.'<br/><br/>';
}
}
else {
echo "Error: " . $sql . "<br>" . $conn->error.'<br/><br/>';
}

That's not a valid MySQL syntax. You cannot add a "FROM" clause to an UPDATE statement.
http://dev.mysql.com/doc/refman/5.0/en/update.html
However, what you want to accomplish is still possible this way:
$sql2 = "UPDATE instanties
SET postcode_id=
(
SELECT postcode_id
FROM postcode
WHERE $where LIMIT 1
)
WHERE id=$last";
As long as there is only 1 result from the nested SELECT (and your LIMIT 1 kinda does that).
EDIT:
If you need many fields from the postcode table, you can join on it:
$sql2 = "UPDATE instanties as i
JOIN (
SELECT *
FROM postcode
WHERE $where LIMIT 1
) as pc
SET i.postcode_id=pc.postcode_id
WHERE i.id=$last";
We would usually use an "ON" clause with the join, but since you're only updating 1 row and your nested SELECT will also only return 1 row, it's not necessary.

try this:
$sql2 = "UPDATE instanties
SET postcode_id=(
SELECT postcode_id
FROM postcode
WHERE $where LIMIT 1)
WHERE id=$last";

Related

Updating multiple tables in SQL using an Array

Currently I had a table called crm_leads for my Leads page where I already have many records. Now for the same page I have created few new fields which is now going to be stored in another table called crm_leads_details. Now I'm storing all my POST values in an array format like so:
$main=array(
'priority'=>$this->input->post('priority'),
'lead_status'=>$this->input->post('lead_status'),
'comment'=>$this->input->post('comment'),
'sub_status'=>$this->input->post('sub_status'),
'lead_agent'=>$this->input->post('lead_agent'),
'emailopt'=>$this->input->post('emailopt')=='Y' ?'Y':'N',
// 'kitchen'=>$this->input->post('kitchen')
);
$loginid=$this->leads_model->update_lead($main,$id);
Now in my model I'm trying to use this statement to update both my tables but it does not work:
function update_lead($maindata,$id,$w=false)
{
if($w==true){
$cond=$id;
}
else{$cond['id']=$id;}
$sql = "UPDATE `crm_leads` LEFT JOIN `crm_leads_details` ON `crm_leads`.`id`=`crm_leads_details`.`leads_id`
SET ".$maindata." WHERE ".$cond;
$query = $this->db->query($sql);
print_r($this->db->last_query()); die();
return $query;
}
This gives the following output UPDATE crm_leads LEFT JOIN crm_leads_details ON crm_leads.id=crm_leads_details.leads_id SET Array WHERE Array
Additionally, since crm_leads_details is a new table there are currently no records in it so not sure if LEFT JOIN crm_leads_details ON crm_leads.id=crm_leads_details.leads_id will work here
Write the query like this
$sql = "UPDATE `crm_leads` LEFT JOIN `crm_leads_details` ON `crm_leads`.`id`=`crm_leads_details`.`leads_id`
SET ";
$i = 0;
foreach($maindata as $key=>$value) {
$i++;
$sql .= $key." = ".$value;
$sql .= ($i == count($maindata)) ? "" : " , " ;
}
$sql .= " WHERE ".$cond;

How to get columns values after insert using php mysql?

In this code, after insert values to DB.I am doing select query for selecting invoiceNo($sql1= "select invoiceNo from invoices order by invoiceID desc limit 1"; ).Instead of selecting from DB how to get InvoiceNo?
For eg: Assume two users are there.Two users inserts InvoiceID at a same time.While doing "select invoiceNo from invoices order by invoiceID desc limit 1";this will get last coming invoiceID .I need to get specific invoiceID (for particular user) .How to get it?
$query = "select * from invoices order by invoiceID desc limit 1";
$result = $link->query($query);
$row = $result->fetch_assoc();
$invoiceNo = $row["invoiceNo"];
$getinvoiceNo = str_pad($invoiceNo + 1, 4, 0, STR_PAD_LEFT); //inserting like 0000
$sql = "INSERT INTO invoices (invoiceNo)
VALUES ('$getinvoiceNo')";
if ($link->query($sql) === TRUE) {
//echo "1";
$sql1 = "select invoiceNo from invoices order by invoiceID desc limit 1";
$last_id = mysqli_insert_id($link, $sql1);
$result1 = mysqli_query($link, $sql1);
$row1 = mysqli_fetch_array($result1);
echo json_encode($row1);
} else {
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
mysql_close($link);
If i understand your question correctly, you are concerned about possible data corruption from the concurrent update of the record.
I think you should give a look to mysql SELECT ... FOR UPDATE syntax, it should do what you ask: lock the selected row until an update is fired. Then the lock will be released.
For example:
SELECT table_field FROM table_name WHERE table_id_field = id_param FOR UPDATE
will lock the selected row until
UPDATE table_name SET table_field = table_field + 1 WHERE table_id_field = id_param
If you're looking to prevent collisions in invoice numbers, all you need to do is create your table as
CREATE TABLE invoices (
invoiceID INTEGER NOT NULL AUTO_INCREMENT,
other columns . . .
PRIMARY KEY (invoiceID)
);
Then when you do your INSERT, don't insert the invoiceID and let MySQL do it.
This will ensure that each new invoice has a unique invoiceID.

Mysql Join two tables to check if a user has made a pick

Hi I am attempting to join two MySQL tables. The tables are as follows:
Table 1
Name: mlb_game_feed
Fields: game_feed_game_id, date, home_team, away_team
Table 2
Name: user_picks
Fields: pick_id, game_feed_game_id_fk, user_id_fk
Here is the sql I've attempted to use to join the two tables:
$sql = "
SELECT game_feed_game_id
, home_team
, away_team
, COUNT(1) as cnt
FROM game_feed_mlb
JOIN user_picks
ON user_picks.game_feed_game_id_fk = game_feed_mlb.game_feed_game_id
Where game_feed_mlb.date = '" . $_SESSION['date']."'
AND user_picks.user_id_fk = 1";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
$count = $row["cnt"];
$game_id = $row["game_feed_game_id"];
$home_team = $row['home_team'];
$away_team = $row['away_team'];
echo $game_id;
}
}
My intention is to check if the user has picked a winner (either home_team or away_team) from the mlb_game_feed table and if they have, I will change a link from make_pick to change_pick (with an if($count) statement) on the screen.
However, currently I'm not even getting any data back which means my sql is likely incorrect. Any help would be great! Thanks.
Consider the following suggestions:
Use a LEFT JOIN to return ALL records and a conditional aggregate to count matches in cnt field. Later you can use this cnt to run your update hyperlink in PHP. See if block in fetch loop.
As mentioned, your SQL string that concatenates on line breaks does not leave room before the clauses of SQL: FROM, JOIN, ON, and WHERE.
Use a GROUP BY clause for your aggregate query. Non-aggregated columns must appear in this clause else it is a violation of ANSI SQL. Unfortunately, MySQL allows the ONLY_FULL_GROUP_BY mode off whereas every other RDBMS will correctly throw an error.
Use table aliases for more readable code instead of repeating long name tables.
Pass in $SESSION date as a parameter to prepared statement. See ? placeholder in string.
PHP
$sql = "SELECT g.game_feed_game_id, g.home_team, g.away_team, " .
" SUM(CASE WHEN g.game_feed_game_id IS NOT NULL " .
" THEN 1 ELSE 0 END) as cnt " .
"FROM game_feed_mlb g " .
"LEFT JOIN user_picks u " .
" ON u.game_feed_game_id_fk = g.game_feed_game_id " .
"WHERE g.`date` = ? AND u.user_id_fk = 1 " .
"GROUP BY g.game_feed_game_id, g.home_team, g.away_team;"
// CONFIGURE PREPARED STATEMENT AND BIND PARAMETER
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s", $_SESSION['date']);
// EXECUTE STATEMENT AND RETURN RESULTS
$stmt->execute();
$result = $stmt->get_result();
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$count = $row["cnt"];
$game_id = $row["game_feed_game_id"];
$home_team = $row['home_team'];
$away_team = $row['away_team'];
echo $game_id;
if($row['cnt'] > 1) {
// change links accordingly...
}
}
}

PHP PDO dynamic WHERE clause

I have a simple function that returns a count from a database table, based on some criteria.
function MyCount($strTable, $strCriteria) {
$strSQL = "SELECT COUNT(*) FROM " . $strTable . " ";
if (trim($strCriteria) != "") $strSQL .= "WHERE " . $strCriteria;
$results = mysql_query($strSQL, $objConn);
$row = mysql_fetch_array($results);
return $row[0];
}
Its very useful for quickly getting a value in 1 line of code, e.g:
$Users = MyCount("Users", "Deleted = 0");
However, I'm now trying to move to PDO and am having trouble passing in the were as parametrized values. I'm trying to do something like the below (which doesn't work):
$objQuery=$objConn->prepare("SELECT count(*) as TheCount FROM :table_name WHERE :criteria");
$objQuery->bindParam(':table_name', $strTable);
$objQuery->bindParam(':criteria', $strCriteria);
I guess the obvious would be:
$objQuery=$objConn->prepare("SELECT count(*) as TheCount FROM :table_name WHERE ".$strCriteria");
$objQuery->bindParam(':table_name', $strTable);
But, this seems to go against the spirit of parametrized values... does anyone have any other suggestions?
Thanks
This line is the issue:
$objQuery->bindParam(':table_name', $strTable);
You can only bind values ( field= :value) in PDO you cannot bind table names or column names or custom dynamic where clause.
So you just build the query manually:
SELECT count(*) as TheCount FROM `$strTable` WHERE $strCriteria
function my_count($strTable, $strCriteria, $objConn)
{
$sql ="SELECT count(*) as TheCount FROM $strTable WHERE $strCriteria";
$objQuery=$objConn->query($sql);
$row =$objQuery->fetch();
return $row['TheCount'];
}
$Users = my_count("Users", "Deleted = 0", $objConn);

Check whether data is at table

I asked something about in_array() and I already got that working. But now I have a different problem:
I have a table that says which services are assigned to hosts: services_hosts(service_id, host_id).
How can I see if the service that is selected is already assigned to that host, also selected? Basically, I want to see if the specific line (service_id, host_id) already exists in that table.
EDIT:
The problem is that I want to compare in a separate file that has functions that connect to DB:
function addServiceToHost($service_name, $host_id)
{
$query = "INSERT INTO monitoring_hosts_services (service_id, host_id) values ((SELECT service_id FROM monitoring_services WHERE name = '".$service_name."'), '".$host_id."')";
$result = #pg_exec($this->conn, $query);
if ($row = pg_fetch_row($result))
{
"blabla error msg"
exit;
}
return $this->parseResultObj($result);
}
I might not unserstand your question correctly but would this do the trick:
SELECT * FROM ServerHostsTable WHERE service_id = '5' AND host_id = '8'
$query = ("SELECT * FROM ServerHostsTable WHERE service_id = '5' AND host_id = '8'")
if(mysql_num_rows($query)>0)
{
//the item is in the db
}
else
{
//not in the db
}
hope this helps
your question is not very clear, but from what I understand you want to test if a specific row is inserted into a database table. you could do this like this:
$result=mysql_query("SELECT service_id FROM services_hosts WHERE service_id=$theserviceid AND host=$thehostid");
if($row=mysql_fetch_row($result){
echo "already in the db";
} else {
echo "not in the db!";
}
I would run this query.
$sql = "SELECT COUNT(*) AS ret\n";
$sql.= "FROM services_hosts\n";
$sql.= "WHERE service_id = $service_id\n";
$sql.= "AND host_id = $host_id";
The result should be one row with one field (named ret):
0 - the service is not present on the host
1 - service is present on the host
enything else - there is a problem with table in database

Categories