My Script needs to update the table if the name is already in there. But it is not doing it.
This is my code that i'm using
$sth = $db->prepare(
'INSERT INTO track (rsname, overallranknow, overalllevelnow, overallxpnow)
VALUES (:name, :Overalln, :Overall1, :Overall2)
ON DUPLICATE KEY UPDATE
rsname = values(rsname),
overallranknow = values(overallranknow),
overalllevelnow = values(overalllevelnow),
overallxpnow = values(overallxpnow)'
);
$sth->bindValue(':name', $name, PDO::PARAM_STR);
$sth->bindValue(':Overalln', $Overalln, PDO::PARAM_INT);
$sth->bindValue(':Overall1', $Overall[1], PDO::PARAM_INT);
$sth->bindValue(':Overall2', $Overall[2], PDO::PARAM_INT);
$sth->execute();
It should only update when the name is already there. I dont know mutch about PDO so thats why i'm asking so mutch about it.
~Kev (bad english = sorry)
Someone who taught you this query, didn't tell you that you need an unique key for it to work.
Related
I am trying to update a database that tracks a household. It keeps the household head as a client in a separate table, but uses their ID as a foreign key in the household table. I need to be able to add multiple people in a household. I tried using just an UPDATE statement, but it only replaced the data when I tried to add multiple people at once. I am trying to do this not using DELETE and INSERT statements for fear of losing information. For added information, this is all manipulated by a PHP Fat-Free Website because my school teaches it.
function editHousehold($id, $name, $age, $gender){
$id = $this->getLastId();
$sql= "UPDATE Household SET `name`=:name, age=:age, gender=:gender WHERE
Guests_ClientId=:Guests_ClientId";
$statement = $this->dbh->prepare($sql);
$statement->bindParam(':name', $name, PDO::PARAM_STR);
$statement->bindParam(':age', $age, PDO::PARAM_STR);
$statement->bindParam(':gender', $gender, PDO::PARAM_STR);
$statement->bindParam(':Guests_ClientId', $id, PDO::PARAM_INT);
$statement->execute();
}
Vs.
function editNeeds($id,$resource,$date, $amount, $voucher, $checkNum){
$sql = "DELETE FROM Needs WHERE Guests_ClientId = $id";
$statement = $this->dbh->prepare($sql);
$statement->execute();
$id = $this->getLastId();
$sql= "INSERT INTO Needs (resource, visitDate, amount, voucher, checkNum, Guests_ClientId)
VALUES (:resource, :date , :amount, :voucher, :checkNum, $id)";
$statement = $this->dbh->prepare($sql);
$statement->bindParam(':resource', $resource, PDO::PARAM_STR);
$statement->bindParam(':amount', $amount, PDO::PARAM_STR);
$statement->bindParam(':voucher', $voucher, PDO::PARAM_STR);
$statement->bindParam(':checkNum', $checkNum, PDO::PARAM_STR);
$statement->bindParam(':date', $date, PDO::PARAM_STR);
$statement->execute();
}
/**
* edit households, removes the old and replaces witha new set of values
* #param $id
* #param $name
* #param $age
* #param $gender
*/
function editHousehold($id, $name, $age, $gender){
$sql = "DELETE FROM Household WHERE Guests_ClientId = $id";
$statement = $this->dbh->prepare($sql);
$statement->execute();
$id = $this->getLastId();
$sql= "INSERT INTO Household (name, age, gender,Guests_ClientId)
VALUES (:name,:age,:gender,$id)";
$statement = $this->dbh->prepare($sql);
$statement->bindParam(':name', $name, PDO::PARAM_STR);
$statement->bindParam(':age', $age, PDO::PARAM_STR);
$statement->bindParam(':gender', $gender, PDO::PARAM_STR);
$statement->execute();
}
I think you are looking for an "either insert new entry or update if the primary key exists" type of statement. This is called "upsert", and MySQL provides it in the form of INSERT ... ON DUPLICATE KEY UPDATE.
It will insert new entries, unless the primary key of one of the entries to insert already exists. If so, it will instead update the existing entry.
Yesterday i had this topic with "pdo inserting and updating. Now here is the following
Warning: PDOStatement::execute() [pdostatement.execute]: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in on line 148
And this is my code.
$sth = $db->prepare(
'INSERT INTO track (`rsname`, `overallranknow`, `overalllevelnow`, `overallxpnow` )' .
'VALUES (:name, :Overalln, :Overall1, :Overall2) '.
'ON DUPLICATE KEY UPDATE ' .
"rsname = :name" .
"overallranknow = :Overalln" .
"overalllevelnow = :Overall1" .
"overallxpnow = :Overall2"
);
$sth->bindValue(':name', $name, PDO::PARAM_STR);
$sth->bindValue(':Overalln', $Overalln, PDO::PARAM_INT);
$sth->bindValue(':Overall1', $Overall[1], PDO::PARAM_INT);
$sth->bindValue(':Overall2', $Overall[2], PDO::PARAM_INT);
$sth->execute();
The error says my execute line is the wrong 1. I have tried it with a array and i still got it then. I hope maybe knows what i mean.
~Kev (bad english = sorry)
From the PDO::prepare manual;
You must include a unique parameter marker for each value you wish to pass in to the statement when you call PDOStatement::execute(). You cannot use a named parameter marker of the same name twice in a prepared statement.
That (sadly) means that you'll have to duplicate your bindings with secondary names to use the same value twice in a query. Not pretty, something like;
$sth = $db->prepare(
'INSERT INTO track (`rsname`, `overallranknow`, `overalllevelnow`, `overallxpnow` )' .
'VALUES (:name, :Overalln, :Overall1, :Overall2) '.
'ON DUPLICATE KEY UPDATE ' .
"rsname = :name_2" .
"overallranknow = :Overalln_2" .
"overalllevelnow = :Overall1_2" .
"overallxpnow = :Overall2_2"
);
$sth->bindValue(':name', $name, PDO::PARAM_STR);
$sth->bindValue(':name_2', $name, PDO::PARAM_STR);
$sth->bindValue(':Overalln', $Overalln, PDO::PARAM_INT);
$sth->bindValue(':Overalln_2', $Overalln, PDO::PARAM_INT);
$sth->bindValue(':Overall1', $Overall[1], PDO::PARAM_INT);
$sth->bindValue(':Overall1_2', $Overall[1], PDO::PARAM_INT);
$sth->bindValue(':Overall2', $Overall[2], PDO::PARAM_INT);
$sth->bindValue(':Overall2_2', $Overall[2], PDO::PARAM_INT);
$sth->execute();
EDIT: Since MySQL allows for the VALUES keyword in ON DUPLICATE KEY to not have to repeat the parameters, you'd be better off using #YourCommonSense's answer for this exact case.
INSERT INTO track (rsname, overallranknow, overalllevelnow, overallxpnow)
VALUES (:name, :Overalln, :Overall1, :Overall2)
ON DUPLICATE KEY UPDATE
rsname = values(rsname),
overallranknow = values(overallranknow),
overalllevelnow = values(overalllevelnow),
overallxpnow = values(overallxpnow)
it have to be.
Hi i have a question about mysql
this is my query:
$geboortedatum = $_POST['dag'].'-'.$_POST['maand'].'-'.$_POST['jaar'];
$geboortedatum1 = $_POST['dag1'].'-'.$_POST['maand1'].'-'.$_POST['jaar1'];
try{
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "
INSERT INTO clienten
(client_voornaam,
client_achternaam,
client_geboortedatum,
client_geslacht,
client_adres,
client_postcode,
client_woonplaats,
client_contactpersoon,
client_diagnose,
datun_aanmaak)
VALUES (:voornaam,
:achternaam.
:geboortedatum,
:geslacht,
:adres,
:postcode,
:woonplaats,
:contactpersoon,
:diagnose,
:datumaanmaak)
INSERT INTO verzorgers(
wat_is_verzorger,
voornaam_verzorger,
achternaam_verzorger,
geboortedatum_verzorger,
email_verzorger,
geslacht_verzorger,
adres_verzorger,
postcode_verzorger,
woontplaats_verzorger,
tel1_verzorger,
tel2_verzorger,
datum_aanmaak
)
VALUES(
:watisverz
:voornaamverz,
:achternaamverz,
:geboortedatumverz,
:emailverz,
:geslachtverz:
:adresverz,
:postcodeverz,
:woonplaatsverz,
:tel1verz,
:tel2verz,
:datumaanmaak
)
";
$stmt = $db->prepare($sql);
$stmt->bindParam(':voornaam', $_POST['voornaam'], PDO::PARAM_STR);
$stmt->bindParam(':achternaam', $_POST['achternaam'], PDO::PARAM_STR);
$stmt->bindParam(':geboortedatum', $geboortedatum, PDO::PARAM_INT);
$stmt->bindParam(':geslacht', $_POST['geslacht'], PDO::PARAM_STR);
$stmt->bindParam(':adres', $_POST['adres'], PDO::PARAM_STR);
$stmt->bindParam(':postcode', $_POST['postcode'], PDO::PARAM_INT);
$stmt->bindParam(':woonplaats', $_POST['woonplaats'], PDO::PARAM_STR);
$stmt->bindParam(':contactpersoon', $_POST['contactpersoon'], PDO::PARAM_STR);
$stmt->bindParam(':diagnose', $_POST['diagnose'], PDO::PARAM_INT);
$stmt->bindParam(':datumaanmaak', $_POST['datum_toetreding'], PDO::PARAM_INT);
$stmt->execute();
}
catch(PDOException $e)
{
echo '<pre>';
echo 'Regel: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage();
echo '</pre>';
} ?>
Now when the client and verzorger are created, they both get an unique ID.
Client had a column that stores the verzorger ID associated and vica versa.
Is it possible to make a query that also directly stores the IDs created?
EDIT:
ok maybe to difficult, maybe an answer to get only the client id in verzorger?:)
How about something like this (TableAID and TableBID are both AUTO_INCREMENT columns):
INSERT INTO TableA
(SomeColumn)
VALUES
('Blah');
SET #TableAID = LAST_INSERT_ID();
INSERT INTO TableB
(TableAID, AnotherColumn)
VALUES
(#TableAID,'Foobar');
SET #TableBID = LAST_INSERT_ID();
UPDATE TableA
SET TableBID = #TableBID
WHERE TableAID = #TableAID;
What you can do is create a function that queries against a sequence generator:
create function foo returns int
Begin
Declare nextValue int
Set nextValue = SELECT NEXT VALUE FOR mySequence;
End
return (nextValue);
Which would allow you to pass around the value returned from this sequence and you could know "ahead" of time what the values were going to be.
EDIT
Please understand how concurrency works and use either pessimistic or optimistic locking. While this should be obvious, some feel as though it is necessary to include.
I've created a database for one of my classes simulating a hotel reservation form.
my database table name that I am trying to get values from is tblNameRes and the fields are fldName and pkEmail
I have gotten the values from the database and displayed them in this table here:
http://www.uvm.edu/~cchessia/cs148/assign4/strugg.php
I want to add a column to be able to update and delete these records, but I don't really understand how. I have this code:
$updating = $db->prepare('UPDATE `tblNameRes` SET `name` = `name` + ? WHERE `id` = ?');
$updating->execute(array(20, $id));
but I want to be able to click a link that says "update" and it will take me to another page that allows me to edit the data and submit it back to the database. I would also like to be able to delete the data in the same way.
I'm a little confused to what you would like, would you like the PDO code to both update and delete items from your DB? If so I use this, I'm also new to PDO. Also try not to use ' around table/field names.
/** Code to update */
$query = "UPDATE tblNameRes SET name ='$name' WHERE id = :id";
$stmt = $db->prepare($query);
$stmt->BindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute();
/** Code to delete */
$query = "DELETE FROM tblNameRes WHERE id = :id";
$stmt = $db->prepare($query);
$stmt->BindValue(':id', $id, PDO::PARAM_INT);
$query->execute();
Let me know if this helps, or is not what you wanted. I'm new here so I can't post 'comments'.
/* code for update and remove this 'at the beginning an at the end*/
$query = "UPDATE tblNameRes SET name =:fname WHERE id = :id";
$stmt = $db->prepare($query);
$stmt->BindValue('fname',$fname);
$stmt->execute();
DETAILS
I am doing a single insert for the expiry of a new or renewed licence. The time period for the expiry is 2 years from the insertion date.
If a duplicate is detected, the entry will be updated such that the expiry equals the remaining expiry plus 2 years.
Regarding duplicates, in the example below there should only be one row containing user_id =55 and licence=commercial.
TABLE: licence_expiry
--------------------------------------------------------
| user_id | licence | expiry |
--------------------------------------------------------
| 55 | commercial | 2013-07-04 05:13:48 |
---------------------------------------------------------
user_id (int11), licence (varchan50), expiry (DATETIME)
I think in mysql you would write it something like this (Please note that I haven't checked whether the code works in mysql. )
INSERT INTO `licence_expiry`
(`user_id`, `licence`, `expiry`)
VALUES
(55, commercial, NOW()+ INTERVAL 2 YEAR)
ON DUPLICATE KEY UPDATE
`expiry` = `expiry` + INTERVAL 2 YEAR
QUESTION: How can I do this with PDO? I've written a rough outline of what I think I will use, but I'm not sure what to write for the expiry value for the ON DUPLICATE KEY UPDATE.
$sql = "INSERT INTO $table (user_id, licence, expiry)
VALUES (
:user_id,
:licence,
:expiry)
ON DUPLICATE KEY UPDATE expiry = Something";
try {
$dbh = new PDO('login info here');
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':user_id', $userID, PDO::PARAM_INT);
$stmt->bindParam(':licence',$licence, PDO::PARAM_STR);
$stmt->bindParam(':expiry',$expiry, PDO::PARAM_STR);
$stmt->execute();
//$stmt->closeCursor(); //use this instead of $dbh = null if you will continue with another DB function
$dbh = null;
}
catch(PDOException $e)
{
$error=$e->getMessage();
}
Any help is much appreciated.
You can use MySQL's VALUES() function:
In an INSERT ... ON DUPLICATE KEY UPDATE statement, you can use the VALUES(col_name) function in the UPDATE clause to refer to column values from the INSERT portion of the statement. In other words, VALUES(col_name) in the UPDATE clause refers to the value of col_name that would be inserted, had no duplicate-key conflict occurred.
Therefore, in your case:
ON DUPLICATE KEY UPDATE expiry = VALUES(expiry)
Alternatively, you can create a fourth parameter to which you bind $expiry again:
$sql = "INSERT INTO $table (user_id, licence, expiry)
VALUES (
:user_id,
:licence,
:expiry)
ON DUPLICATE KEY UPDATE expiry = :another";
try {
$dbh = new PDO('login info here');
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':user_id', $userID , PDO::PARAM_INT);
$stmt->bindParam(':licence', $licence, PDO::PARAM_STR);
$stmt->bindParam(':expiry' , $expiry , PDO::PARAM_STR);
$stmt->bindParam(':another', $expiry , PDO::PARAM_STR);
$stmt->execute();
// etc.
I know you have answer below, but i had same problem and my solution looks quite different but it works for me so if you want to use different statement of using insert in mysql with explicit binding values to columns you can try this code
$sql = "
INSERT INTO
$table
SET
user_id = :user_id,
licence = :licence,
expiry = :expiry
ON DUPLICATE KEY UPDATE
expiry = :expiry
";
$dbh = new PDO('login info here');
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$stmt = $dbh->prepare($sql);
$stmt->bindValue('user_id', $userID , PDO::PARAM_INT);
$stmt->bindValue('licence', $licence, PDO::PARAM_STR);
$stmt->bindValue('expiry' , $expiry , PDO::PARAM_STR);