Related
A little background. I have an Oracle database that I am trying to query and then insert into a local MYSQL database so that I can generate canned reports. I have been trying to figure out this insert into Mysql for a while now. I have the Oracle portion running correctly but when I try to insert I have been getting a syntax error in mysql.
The result set comes back with 8 rows the first of which is the Key in MYSQL. I would really like to convert this insert query I built into a insert on duplicate key update statement but am lost on how I would do this properly. Any help you guys can provide would be appreciated.
$db1 = '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=HOST)(PORT = 1521))(CONNECT_DATA=(SERVICE_NAME=Service)))';
$c1 = oci_connect("Userid", "Pass", $db1);
$sql = oci_parse($c1, "select statement") ;
oci_execute($sql);
$i = 0;
while ($row = oci_fetch_array($sql)){
$i++;
$k = $row[0];
$dte = $row[1];
$cus = $row[2];
$odr = $row[3];
$lin = $row[4];
$cas = $row[5];
$lpo = $row[6];
$cpl = $row[7];
$cpo = $row[8];
};
$db_user = "userid";
$db_pass = "Pass";
$db = new PDO('mysql:host=host; dbname=databasename', $db_user, $db_pass);
$stmt = $db->prepare("INSERT INTO `cuspi` (k, dte, cus, odr, lin, casa, lpo, cpl, cpo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
$recordcount = count($k);
for ($i = 0; $i < $recordcount; $i++) {
$records[] = [
$k[$i],
$dte[$i],
$cus[$i],
$odr[$i],
$lin[$i],
$casa[$i],
$lpo[$i],
$cpl[$i],
$cpo[$i],
];
}
foreach ($records as $record) {
$stmt->execute($record);
}
?>
I was able to figure out the Answer. I was missing the grave accent around the column references for the insert.
Original
$stmt = $db->prepare("INSERT INTO `cuspi` (k, dte, cus, odr, lin, casa, lpo, cpl, cpo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
Fixed
$stmt = $db->prepare("INSERT INTO `cuspi` (`k`, `dte`, `cus`, `odr`, `lin`, `casa`, `lpo`, `cpl`, `cpo`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
I am editing a pre-made script for iDEAL payments which is available here. What I’m trying to do is add a few fields to the form and database. The extra fields show up fine in the email template, but they are not entered into the database. The script works with PHPmailer.
I think this is where the problem is:
$stmt = $db->prepare("INSERT INTO tbl_ideal_payments SET
ID = ?, datumtijd = NOW(),
naamfrom = ?, emailfrom = ?,
naamto = ?, emailto = ?,
bedrag = ?, descr = ?,
mailsubject = ?, mailtekst = ?,
ipadres = ?,
heenreis = ?,
terugreis = ?,
postcode = ?,
factuurnummer = ?,
status = 'open'");
//var_dump($stmt);
$stmt->bind_param('sssssdssss', $session, $naamfrom, $emailfrom, $contact, $emailto, $bedrag, $paydecr, $subject, $mailmsg, $heenreis, $terugreis, $postcode, $factuurnummer, $_SERVER['REMOTE_ADDR']);
The fields that I'm trying to add are heenreis, terugreis, postcode, and factuurnummer.
Full code for the config, form, and above script can be found here (seems a bit much to paste in this post).
What am I doing wrong?
Count the data type parameters 'sssssdssss' and then count the parameters place holders ?, and then count the columns in the SET clause, they should all be the same number.
Also this situation will have generated an error, but you are not testing for errors
While developing, specially if you are developing on a LIVE server where error reporting should be turned off add these lines at the top of the script, to turn on error reporting.
<?php
ini_set('display_errors', 1);
ini_set('log_errors',1);
error_reporting(E_ALL);
// if you are using the MYSQLI_ database extension add this also
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$stmt = $db->prepare("INSERT INTO tbl_ideal_payments SET
ID = ?, datumtijd = NOW(),
naamfrom = ?, emailfrom = ?,
naamto = ?, emailto = ?,
bedrag = ?, descr = ?,
mailsubject = ?, mailtekst = ?,
ipadres = ?,
heenreis = ?,
terugreis = ?,
postcode = ?,
factuurnummer = ?,
status = 'open'");
// also add error test
if ( !$stmt ) {
echo $db->error;
exit;
}
// now add the 4 missing data type parameters
// I have assumed they are all string !!!
// You should check with your schema what datatype they actually are
$stmt->bind_param('sssssdssssssss', $session,
$naamfrom,
$emailfrom,
$contact,
$emailto,
$bedrag,
$paydecr,
$subject,
$mailmsg,
$heenreis,
$terugreis,
$postcode,
$factuurnummer,
$_SERVER['REMOTE_ADDR']
);
I have been troubleshooting my code, searching stackoverflow to find the correct syntax to do this with PHP. I can't figure out how the ON DUPLICATE KEY UPDATE syntax works with prepared statements:
INSERT INTO placements_by_date (DateVal, PlacementName, PlacementId,
CampaignId, AdName, Format, TagId, Impressions, Clicks, Leads, MediaCost)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
// HERE COMES THE TRICKY SYNTAX:
DateVal = VALUES(DateVal), PlacementName = VALUES(PlacementName),
PlacementId = VALUES(PlacementId), CampaignId = VALUES(CampaignId),
AdName = VALUES(AdName), Format = VALUES(Format), TagId = VALUES(TagId),
Impressions = ?, Clicks = ?, Leads = ?, MediaCost = ?
I have tried many variations:
...ON DUPLICATE KEY UPDATE
DateVal = VALUES('$DateVal'), PlacementName = VALUES('$PlacementName'),
PlacementId = VALUES('$PlacementId'), CampaignId = VALUES('$CampaignId'),
AdName = VALUES('$AdName'), Format = VALUES('$Format'), TagId = VALUES('$TagId'),
Impressions = VALUES(?), Clicks = VALUES(?), Leads = VALUES(?),
MediaCost = VALUES(?)";
I store this as a string, $sql, and do my usual stuff:
$mysqli = new mysqli(...
...
$stmt = $mysqli -> prepare($sql);
$stmt -> bind_param('sissiiiis', $PlacementName, $PlacementId,
$AdName, $Format, $TagId, $Impressions,
$Clicks, $Leads, $MediaCost);
...
But maybe the parameters should be bound differently??
I enabled tried reading through the feedback but this was too generic with no actionable insights.
$driver = new mysqli_driver();
$driver->report_mode = MYSQLI_REPORT_ALL;
Hoping you have some insight to share?
Thanks!
Why not continue using the VALUES() method?
INSERT INTO placements_by_date(DateVal, PlacementName, PlacementId,
CampaignId, AdName, Format, TagId,
Impressions, Clicks, Leads, MediaCost
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
DateVal = VALUES(DateVal), PlacementName = VALUES(PlacementName),
PlacementId = VALUES(PlacementId), CampaignId = VALUES(CampaignId),
AdName = VALUES(AdName), Format = VALUES(Format), TagId = VALUES(TagId),
Impressions = VALUES(Impressions), Clicks = VALUES(Clicks), Leads = VALUES(Leads),
MediaCost = VALUES(MediaCost);
You don't specify what the unique key is. However, you don't need to include those columns in the update statements, because they are already the same.
If, perchance, you want to increment the last four values rather than just assign them, you can do that too:
ON DUPLICATE KEY UPDATE
DateVal = VALUES(DateVal), PlacementName = VALUES(PlacementName),
PlacementId = VALUES(PlacementId), CampaignId = VALUES(CampaignId),
AdName = VALUES(AdName), Format = VALUES(Format), TagId = VALUES(TagId),
Impressions = Impressions + VALUES(Impressions),
Clicks = Clicks + VALUES(Clicks),
Leads = Leads + VALUES(Leads),
MediaCost = MediaCost + VALUES(MediaCost)
EDIT:
The following should work just to update the last four columns:
INSERT INTO placements_by_date(DateVal, PlacementName, PlacementId,
CampaignId, AdName, Format, TagId,
Impressions, Clicks, Leads, MediaCost
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
Impressions = VALUES(Impressions), Clicks = VALUES(Clicks), Leads = VALUES(Leads),
MediaCost = VALUES(MediaCost);
This code below inserts some data into a MySQL database. I want the page to load to this record after the insert but the variable ($insert) that I'm trying to load is not coming through on the header. can someone help?
$pdo = Database::connect();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO riders (firstname,secondname,email,mobile,landline,dob,addressline1,town,county,postcode) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$q = $pdo->prepare($sql);
$q->execute(array($firstname,$secondname,$email,$mobile,$landline,$dob,$streetaddress,$town,$county,$postcode));
$insert = mysql_insert_id();
Database::disconnect();
header("Location:read.php?id=.$insert");
Use $pdo->lastInsertId() for getting last ID after SQL insert.
I was wondering if someone could help me.
Im trying to integrate some code into my application, the code that i need to integrate is written with PDO statements and i have no idea how it goes.
I was wondering if someone could help me convert it.
The code is as follows
$sql = "insert into message2 (mid, seq, created_on_ip, created_by, body) values (?, ?, ?, ?, ?)";
$args = array($mid, $seq, '1.2.2.1', $currentUser, $body);
$stmt = $PDO->prepare($sql);
$stmt->execute($args);
if (empty($mid)) {
$mid = $PDO->lastInsertId();
}
$insertSql = "insert into message2_recips values ";
$holders = array();
$params = array();
foreach ($rows as $row) {
$holders[] = "(?, ?, ?, ?)";
$params[] = $mid;
$params[] = $seq;
$params[] = $row['uid'];
$params[] = $row['uid'] == $currentUser ? 'A' : 'N';
}
$insertSql .= implode(',', $holders);
$stmt = $PDO->prepare($insertSql);
$stmt->execute($params);
You shoudl use PDO unles for some technical reason you cant. If you dont know it, learn it. Maybe this will get you started:
/*
This the actual SQL query the "?" will be replaced with the values, and escaped accordingly
- ie. you dont need to use the equiv of mysql_real_escape_string - its going to do it
autmatically
*/
$sql = "insert into message2 (mid, seq, created_on_ip, created_by, body) values (?, ?, ?, ?, ?)";
// these are the values that will replace the ?
$args = array($mid, $seq, '1.2.2.1', $currentUser, $body);
// create a prepared statement object
$stmt = $PDO->prepare($sql);
// execute the statement with $args passed in to be used in place of the ?
// so the final query looks something like:
// insert into message2 (mid, seq, created_on_ip, created_by, body) values ($mid, $seq, 1.2.2.1, $currentUser, $body)
$stmt->execute($args);
if (empty($mid)) {
// $mid id is the value of the primary key for the last insert
$mid = $PDO->lastInsertId();
}
// create the first part of another query
$insertSql = "insert into message2_recips values ";
// an array for placeholders - ie. ? in the unprepared sql string
$holders = array();
// array for the params we will pass in as values to be substituted for the ?
$params = array();
// im not sure what the $rows are, but it looks like what we will do is loop
// over a recordset of related rows and do additional inserts based upon them
foreach ($rows as $row) {
// add a place holder string for this row
$holders[] = "(?, ?, ?, ?)";
// assign params
$params[] = $mid;
$params[] = $seq;
$params[] = $row['uid'];
$params[] = $row['uid'] == $currentUser ? 'A' : 'N';
}
// modify the query string to have additional place holders
// so if we have 3 rows the query will look like this:
// insert into message2_recips values (?, ?, ?, ?),(?, ?, ?, ?),(?, ?, ?, ?)
$insertSql .= implode(',', $holders);
// create a prepared statment
$stmt = $PDO->prepare($insertSql);
// execute the statement with the params
$stmt->execute($params);
PDO really is better. It has the same functionality as MySQLi but with a consistent interface across DB drivers (ie. as long as your SQL is compliant with a different database you can theoretically use the exact same php code with mysql, sqlite, postresql, etc.) AND much better parameter binding for prepared statements. Since you shouldnt be using the mysql extension any way, and MySQLi is more cumbersome to work with than PDO its really a no-brainer unless you specifically have to support an older version of PHP.