Product_model.php
public function addProduct($info)
{
$sql_array = array(
$info['name'],
$info['SKU'],
$info['supplier_id'],
$info['type_id'],
$info['brand_id'],
$info['added_on'],
$info['initial_cost_price']);
$this->db->trans_start();
//INSERT
$sql = "INSERT INTO
product(
name,
SKU,
supplier_id,
type_id,
brand_id,
added_on,
initial_cost_price
)
VALUES(
?,
?,
?,
?,
?,
?,
?
)
";
$query = $this->db->query($sql, $sql_array);
$insert_id = $this->db->insert_id();
$this->addProductVariant($insert_id, $info);
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
return 'transaction failed';
} return TRUE;
}
public function addProductVariant($product_id, $info)
{
$sql_array = array(
$product_id,
$info['variant_name'],
$info['variant_SKU'],
$info['barcode'],
$info['wholesale_price'],
$info['buy_price'],
$info['retail_price'],
$info['description'],
$info['initial_quantity'],
$info['added_on'],
$info['last_updated']
);
$sql = "INSERT INTO
product_variant(product_id,
name,
SKU,
barcode,
wholesale_price,
buy_price,
retail_price,
description,
qty_on_hand,
created_on,
last_updated
)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$query = $this->db->query($sql, $sql_array);
}
When I hit submit on the form, the page reloads and shows this error:
Error Number: 1048
Column 'name' cannot be null
INSERT INTO product_variant(product_id, name, SKU, barcode, wholesale_price, buy_price, retail_price, description, qty_on_hand, created_on, last_updated ) VALUES(71, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2017-09-17 10:45:12', '2017-09-17 10:45:12')
Filename: D:/xampp/htdocs/svcc_inv/system/database/DB_driver.php
Line Number: 691
But when I check the database, the inserts are successful. The new records are there.
I have tried echoing the values in the $sql_array and I get correct results. I don't know why the error says they're null. I'm hypothesizing could it be because I split the whole process into two methods, one of which is inside the other, but I don't see yet how that could be.
In your example $info['variant_name'] is NULL, you need to dump $info from the start of addProduct function what does it contain, like so :
public function addProduct($info)
{
var_dump($info);
exit;
...
}
Also, I you want to use $this->db->trans_status() then you need to run transactions manually, using $this->db->trans_begin() and not $this->db->trans_start(), like so :
$this->db->trans_begin();
$sql_array = array(
$info['name'],
$info['SKU'],
$info['supplier_id'],
$info['type_id'],
$info['brand_id'],
$info['added_on'],
$info['initial_cost_price']);
$this->db->trans_start();
//INSERT
$sql = "INSERT INTO
product(
name,
SKU,
supplier_id,
type_id,
brand_id,
added_on,
initial_cost_price
)
VALUES(
?,
?,
?,
?,
?,
?,
?
)
";
$query = $this->db->query($sql, $sql_array);
$insert_id = $this->db->insert_id();
$this->addProductVariant($insert_id, $info);
if ($this->db->trans_status() === false) {
$this->db->trans_rollback();
return 'transaction failed';
} else {
$this->db->trans_commit();
return true;
}
Related
Tried everything I can think of and I've narrowed down to the "?" placeholders.
I've tried replacing the "?" placeholders with random text and all works well (except of course it keeps overwriting the same row).
The error I get:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
produ' at line 2
Here is my code (I would provide more but it all works well except for this bug, and if I remove the "?" placeholders then all works perfectly except that the values are not dynamic, but please ask if you suspect the issue is elsewhere):
// Create MySQL connection to ds_signifyd_api
$mysqli = mysqli_connect( $db_server_name, $db_username, $db_password, $db_name );
// Check connection
if ($mysqli->connect_error) {
exit( $mysqliFailedBody );
}
$mainProdQueryStmt = "INSERT INTO products (`product_id`, `title`, `body_html`, `vendor`, `product_type`, `created_at`, `handle`, `updated_at`, `published_at`, `template_suffix`, `published_scope`, `tags`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
product_id = VALUES(product_id),
title = VALUES(title),
body_html = VALUES(body_html),
vendor = VALUES(vendor),
product_type = VALUES(product_type),
created_at = VALUES(created_at),
handle = VALUES(handle),
updated_at = VALUES(updated_at),
published_at = VALUES(published_at),
template_suffix = VALUES(template_suffix),
published_scope = VALUES(published_scope),
tags = VALUES(tags)";
$product_id = $product_title = $body_html = $vendor = $product_type = $created_at = $handle = $updated_at = $published_at = $template_suffix = $published_scope = $tags = "";
foreach ($dss_product_db_array as $product) {
$product_id = $product['id'];
//... more variables here...
$tags = mysqli_real_escape_string($mysqli, $tags);
if (!mysqli_query($mysqli, $mainProdQueryStmt)) {
printf("Errormessage: %s\n", mysqli_error($mysqli));
}
$mainProdQuery->bind_param("isssssssssss", $product_id, $product_title, $body_html, $vendor, $product_type, $created_at,
$handle, $updated_at, $published_at, $template_suffix, $published_scope, $tags);
$mainProdQuery->execute();
// $mainProdQuery->close();
}
UPDATE
Implemented the fixes mentioned here:
1. Stopped using mysqli_real_escape_string
2. Binding variables outside loop
3. Using only the object oriented method, as opposed to mixing them as in the case of mysqli_query($mysqli, $mainProdQueryStmt) VS $mysqli->prepare($mainProdQueryStmt) as it should have been -- this solved the "?" placeholders syntax error being incorrectly reported
Now everything works perfectly, no errors.
Updated Code:
$mainProdQueryStmt = "INSERT INTO dss_products (`product_id`, `title`, `body_html`, `vendor`, `product_type`, `created_at`, `handle`, `updated_at`, `published_at`, `template_suffix`, `published_scope`, `tags`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
product_id = VALUES(product_id),
title = VALUES(title),
body_html = VALUES(body_html),
vendor = VALUES(vendor),
product_type = VALUES(product_type),
created_at = VALUES(created_at),
handle = VALUES(handle),
updated_at = VALUES(updated_at),
published_at = VALUES(published_at),
template_suffix = VALUES(template_suffix),
published_scope = VALUES(published_scope),
tags = VALUES(tags)";
$mainProdQuery = $mysqli->prepare($mainProdQueryStmt);
if ($mainProdQuery === FALSE) {
die($mysqli->error);
}
$product_id = $product_title = $body_html = $vendor = $product_type = $created_at = $handle = $updated_at = $published_at = $template_suffix = $published_scope = $tags = "";
$mainProdQuery->bind_param("isssssssssss", $product_id, $product_title, $body_html, $vendor, $product_type, $created_at,
$handle, $updated_at, $published_at, $template_suffix, $published_scope, $tags);
if ($mainProdQuery) {
foreach ($dss_product_db_array as $product) {
$product_id = $product['id'];
$product_title = $product['title'];
$body_html = $product['body_html'];
$vendor = $product['vendor'];
$product_type = $product['product_type'];
$created_at = $product['created_at'];
$handle = $product['handle'];
$updated_at = $product['updated_at'];
$published_at = $product['published_at'];
$template_suffix = $product['template_suffix'];
$published_scope = $product['published_scope'];
$tags = $product['tags'];
if (!$mysqli->prepare($mainProdQueryStmt)) {
printf("Errormessage: %s\n", $mysqli->error);
}
$mainProdQuery->execute();
}
}
When you use placeholders you have to use mysqli_prepare(), you can't use mysqli_query(). It looks like you intended to do that, but somehow that code got lost, since you use a variable $mainProdQuery that you never assigned.
You should prepare the query and bind the parameters just once, outside the loop. Then call execute() inside the loop.
$mainProdQueryStmt = "INSERT INTO products (`product_id`, `title`, `body_html`, `vendor`, `product_type`, `created_at`, `handle`, `updated_at`, `published_at`, `template_suffix`, `published_scope`, `tags`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
product_id = VALUES(product_id),
title = VALUES(title),
body_html = VALUES(body_html),
vendor = VALUES(vendor),
product_type = VALUES(product_type),
created_at = VALUES(created_at),
handle = VALUES(handle),
updated_at = VALUES(updated_at),
published_at = VALUES(published_at),
template_suffix = VALUES(template_suffix),
published_scope = VALUES(published_scope),
tags = VALUES(tags)";
$mainProdQuery = $mysqli->prepare($mainProdQueryStmt);
$mainProdQuery->bind_param("isssssssssss", $product_id, $product_title, $body_html, $vendor, $product_type, $created_at,
$handle, $updated_at, $published_at, $template_suffix, $published_scope, $tags);
foreach ($dss_product_db_array as $product) {
$product_id = $product['id'];
//... more variables here...
$mainProdQuery->execute();
}
You're running the query before it's properly prepared, and then, after the fact, attempting to bind to something that's not the right type, it's not a statement handle but a result set. You need to structure it this way:
$mainProdQueryStmt = "INSERT INTO products (`product_id`, `title`, `body_html`, `vendor`, `product_type`, `created_at`, `handle`, `updated_at`, `published_at`, `template_suffix`, `published_scope`, `tags`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
product_id = VALUES(product_id),
...
tags = VALUES(tags)";
// Prepare the statement to get a statement handle
$stmt = $mysqli->prepare($mainProdQueryStmt);
foreach ($dss_product_db_array as $product) {
// Bind to this statement handle the raw values (non-escaped)
$stmt->bind_param("isssssssssss",
$product['id'], $product['title'], ...);
// Execute the query
$stmt->execute();
}
Try to avoid creating heaps of throw-away variables an just bind directly to the values in question, like those in $product. The variables do nothing useful and only introduce opportunities for silly mistakes.
Try using PDO(PhP Data Objects) prepared statements. It's less painful to work with and cross database i.e can be used with any RDBMS. See PDO Official Documentation or here
I've created this to insert to multiple tables, and I want to insert the same ID to both table. ID is auto-incremented in test table and I want test_category table to take the same ID.
I tried it but don't know where I am doing it wrong and getting an error
Fatal error: Call to undefined method mysqli_stmt::insert_id() in C:\wamp64\www\Android\include\DbOperations.php on line 27"
Check this pic for detailed error report
[https://www.dropbox.com/s/nuij2o2ac3xp8mz/Untitled4.png?dl=0]
My php
public function testReg($name, $pin, $a, $b, $ho, $ll, $c, $d){
$stmt = $this->con->prepare("INSERT INTO `test` (`name`, `pin`) VALUES (?, ?)");
$stmt->bind_Param("ss",$name,$pin);
if(!$stmt->execute()){
return 2;
}
$stmttst = $this->con->prepare("INSERT INTO `test_category` (`pid`, `name`, `a`, `b`, `ho`, `ll`, `c`, `d`) VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
$stmttst->bind_Param("isssssss",$stmt->insert_id(),$name,$a,$b,$ho,$ll,$c,$d);
if ($stmttst->execute()){
return 1;
}else{
return 2;
}
}
The "mysqli::$insert_id" is an attribute of mysqli object and your trying on $stmt
Try Following code will resolve your issue.
public function testReg($name, $pin, $a, $b, $ho, $ll, $c, $d){
$stmt = $this->con->prepare("INSERT INTO `test` (`name`, `pin`) VALUES (?, ?);");
$stmt->bind_Param("ss",$name,$pin);
if(!$stmt->execute()){
return 2;
}
$stmttst = $this->con->prepare("INSERT INTO `test_category` (`pid`, `name`, `a`, `b`, `ho`, `ll`, `c`, `d`) VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
$stmttst->bind_Param("isssssss",$this->con->insert_id(),$name,$a,$b,$ho,$ll,$c,$d);
if ($stmttst->execute()){
return 1;
}else{
return 2;
}
}
As of Documents
mysqli::$insert_id -- mysqli_insert_id — Returns the auto generated id used in the latest query
So instead of using $this->con->insert_id() you can use
$var = $this->con;
mysqli_insert_id($var);
Try putting your last inserted id in a variable and then pass it to your 2nd query.
public function testReg($name, $pin, $a, $b, $ho, $ll, $c, $d){
$stmt = $this->con->prepare("INSERT INTO `test` (`name`, `pin`) VALUES (?, ?);");
$stmt->bind_Param("ss",$name,$pin);
if(!$stmt->execute()){
return 2;
}else{
//ADDED ESLE AND STORE ID IN VAR
$lastid=$stmt->insert_id();
}
$stmttst = $this->con->prepare("INSERT INTO `test_category` (`pid`, `name`, `a`, `b`, `ho`, `ll`, `c`, `d`) VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
$stmttst->bind_Param("isssssss",$lastid,$name,$a,$b,$ho,$ll,$c,$d);
// CHANGED BIND PARAM for last id
if ($stmttst->execute()){
return 1;
}else{
return 2;
}
}
Also, you shold specify if you are using mysqli or PDO as most people assume you are using PDO as it is most commonly used.
http://php.net/mysqli_multi_query might also help you in this case. Or try creating a second connectionto the BD, not just a 2nd statement.
You are probably looking for PDO::lastInsertId. It returns the ID of the last inserted row. Therefore you can use this in your second query as it will hold the ID of the first. More info here: http://php.net/manual/en/pdo.lastinsertid.php
I try to insert some data with php and a stored procedure. The stored procedure works fine but only for the first row.
PHP:
$sql = "SELECT * FROM [importliste_TCSv3]";
$stmt = sqlsrv_query($conn, $sql);
if ($stmt === false ) {
die (print_r(sqlsrv_errors(), true));
}
while ($row = sqlsrv_fetch_array($stmt)) {
// print works fine without call proc
$query = "{call difInport(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}";
$params = array("0gtp", $row["Kostenstelle"], $row["Vorname"], $row["Nachname"], $row["CI-Nummer"], $row["cmo_mon"], $row["Raum"], $row["Gebaeude"], $row["Bemerkung"], $row["Hardware"], $row["fmo_mon"], $row["Zubehoer"]);
$stmt = sqlsrv_query($conn, $query, $params);
if ($stmt === false) {
die (print_r(sqlsrv_errors(), true));
}
}
Stored Procedure:
ALTER proc [dbo].[difInport]
#mandant_id varchar(50),
#kostenstelle varchar(50),
#vorname varchar(50),
#nachname varchar(50),
#ci_nummer int,
#anzahl_monitore_old int,
#raum varchar(50),
#gebäude varchar(50),
#bemerkung text,
#hardware_typ varchar(50),
#anzahl_monitore_new varchar(50),
#zubehör text
as
BEGIN
SET NOCOUNT ON;
DECLARE
#latestPersonID int,
#latestCmoID int,
#latestFmoID int
INSERT INTO [RC.Persons] (kostenstelle, vorname, nachname) VALUES (#kostenstelle, #vorname, #nachname);
SET #latestPersonID = (SELECT SCOPE_IDENTITY())
INSERT INTO [RC.CMO] (ci_nummer, anzahl_monitore, raum, gebäude, bemerkung) values (#ci_nummer, #anzahl_monitore_old, #raum, #gebäude, #bemerkung);
SET #latestCmoID = (SELECT SCOPE_IDENTITY())
INSERT INTO [RC.FMO] (hardware_typ, anzahl_monitore, zubehör) values (#hardware_typ, #anzahl_monitore_new, #zubehör);
SET #latestFmoID = (SELECT SCOPE_IDENTITY())
INSERT INTO [RC.Persons_RC.CMO] (cmo_id, person_id) VALUES (#latestCmoID, #latestPersonID);
INSERT INTO [RC.Persons_RC.FMO] (fmo_id, person_id) VALUES (#latestFmoID, #latestPersonID);
INSERT INTO [RC.Persons_RC.Mandant] (person_id, mandant_id) VALUES (#latestPersonID, #mandant_id);
END
I read this question: Call mysql PROCEDURE inside while loop works only first time
but I dont give any result set or is the set declaration with a select the result problem?
You are overwriting your $stmt variable. Change the name of the variable you use in the while loop:
while ($row = sqlsrv_fetch_array($stmt)) {
// print works fine without call proc
$query = "{call difInport(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}";
$params = array("0gtp", $row["Kostenstelle"], $row["Vorname"], $row["Nachname"], $row["CI-Nummer"], $row["cmo_mon"], $row["Raum"], $row["Gebaeude"], $row["Bemerkung"], $row["Hardware"], $row["fmo_mon"], $row["Zubehoer"]);
$stmt_proc = sqlsrv_query($conn, $query, $params);
if ($stmt_proc === false) {
die (print_r(sqlsrv_errors(), true));
}
}
When working with the sqlsrv_query command I can request data from the MSSQL server.
This works
But!
When I want to add data it returns the error [error:array].
The code I use for this is:
$tsql= "INSERT INTO dbo.VERLOF_events (id,
username,
soort,
afdeling,
description,
evdate,
trdate)
VALUES
(?, ?, ?, ?, ?, ?, ?)";
$var = array('', $username, $soort, $afdeling, $description, $evdate, $trdate);
if (!sqlsrv_query($conn, $tsql, $var))
{
die('Error: ' . sqlsrv_errors());
}
echo "1 record added";
The array values are set in the POST statement.
$afdeling = $row['Afdeling'];
$submit = #$_POST['submit'];
$description = #$_POST["description"];
$evdate = #$_POST["evdate"];
$trdate = #$_POST["trdate"];
$username = #$_SESSION['username'];
$soort = #$_POST['Dagen'];
Why does it return the array error?
I looked it up but could not find the problem returning the error.
Any help is appreciated!
The problem is probably you're trying to add an empty value in the id field. If you set identity on it with auto-numbering, you don't need to include it in your query :
$tsql= "INSERT INTO dbo.VERLOF_events (
username,
soort,
afdeling,
description,
evdate,
trdate)
VALUES
(?, ?, ?, ?, ?, ?)";
$var = array($username, $soort, $afdeling, $description, $evdate, $trdate);
if (!sqlsrv_query($conn, $tsql, $var))
{
die('Error: ' . sqlsrv_errors());
}
echo "1 record added";
First of all sorry for my bad English..
I have this function in a model:
function insertUser($data){
$sql = "INSERT INTO USERS VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$query = $this->db->query($sql, array(
$data["uname"],
$data["nome"],
$data["dnuser"],
$data["muser"],
$data["fruser"],
$data["cpuser"],
$data["euser"],
md5($data["passu"])
));
//return $this->db->_error_number();
}
I have one primary key and when data is correct the function works but when is inserted a duplicate key the function doesn’t work. But how can i know that? i mean how can i catch the error ORA-00001 ??
BTW the commented line doesn’t work..
Thank you very much!!
You can use try catch block...
function insertUser($data){
$sql = "INSERT INTO USERS VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
try{
$this->db->trans_start();
$query = $this->db->query($sql, array(
$data["uname"],
$data["nome"],
$data["dnuser"],
$data["muser"],
$data["fruser"],
$data["cpuser"],
$data["euser"],
md5($data["passu"])
));
$this->db->trans_commit();
}
catch(Exception $ex){
$this->db->trans_rollback();
echo "Error:".$ex;
}
}
You can check the following article..
http://ellislab.com/codeigniter/user-guide/database/transactions.html