PHP MYSQL database structure, multiple queries for one entry - php

I'm building a fairly simple site to keep track of of some sales for work. It involves a mysql database with multiple tables for each entry. For the most part, the relationships are cut and dry. However, I have a comments table that will store multiple comments for the same sale. I have a foreign key in the comments table tied to the ID of the main sales table. I have a similar arrangement between a gross table and the sales table, in that it stores multiple gross amounts for the same saleID. What is the best way to insert these into the database? Currently, I'm inserting the comments and getting the ID of that row, then inserting the gross and getting the ID, then I make the insertion into the sales table using the comments id and the gross id. Is there a more efficient method rather than making 5 queries?
--Edit: Here is the current code. I'm pretty new to this so I had to look up procedures to see what you meant. It seems like it's basically what I'm doing, but creating a method for it instead, which I'll be doing once I figure out the most efficient way.
//Prepare the Queries
//Insert Gross Amounts Query
$grossQ = "INSERT INTO gross (commGross, storeGross, manGross, fiGross, flatGross) VALUES ('$commGross', '$storeGross', '$manGross', '$fiGross')";
//Insert Comments Query
$commentsQ = "INSERT INTO comments (comment, dealcomment, grosscomment) VALUES ('$otherComments', '$dealComments', $grossComments')";
//Insert Deal Query
$q = "INSERT INTO sales (make, model, location, vehtype, saletype, manager, county, flat, unitcount, armoramount, controlnumber, salesman, stock) VALUES ('$make', '$model', '$location', '$vehType', '$saleType', '$managerName', '$county', '$flat', '$unitCount', '$armorAmount', '$controlNumber', '$salesmanName1', '$stock')";
//Make database connection
$db = new db('palm_sales');
//Execute gross query and get the id of the row
$db->execute($grossQ);
$grossID = $db->getLastID();
//Execute comments query and get the id of the row
$db->execute($commentsQ);
$commentsID = $db->getLastID();
//Build Main Query
$q = "INSERT INTO sales (make, model, location, vehtype, saletype, manager, gross, comments, county, flat, unitcount, armoramount, controlnumber, salesman, stock) VALUES ('$make', '$model', '$location', '$vehType', '$saleType', '$managerName', '$grossID', '$commentsID', '$county', '$flat', '$unitCount', '$armorAmount', '$controlNumber', '$salesmanName1', '$stock')";
//Execute Main Query
$db->execute($q);
if(mysql_affected_rows() > 0)
{
echo "Success!";
}
else echo "Error: ".mysql_error();

It sounds like you're only performing 3 queries at the moment - mysql_insert_id() does not perform a new query, it gives your information about the insert just performed.
It's not clear why you need to insert into the sales table when you insert a comment or gross. I would imagine you'd have something like this:
TABLE sales PK id
TABLE comments PK id FK sales_id
TABLE gross PK id FK sales_id
When you get a new sale, you insert into the sales table. To add a new comment or gross, you insert into that table, with a foreign key of the sales ID. What part of that is not working?

Related

Can I add different data to two different tables using separate INSERT statements within nested IF statements?

I have a system where someone can place and order for multiple products, the same or different. I am storing some of the cart data (an overview of the order) to an orders table and I want to store specific item data to another table, order_item (eg quantity, product_id etc). The first query to INSERT INTO orders is working, but somehow, the second query won't INSERT INTO the second table. In order to insert into the second table, I need to find the highest id number from the orders table as well, so that this can be added to the order_item table.
Here are the SQL statements:
if(empty($hNum) || empty($street) || empty($city) || empty($county) || empty($postcode) || empty($country)){
header("Location: ../shop/checkout.php?error=emptyaddressfields");
exit();
}
else {
$sqlO = "INSERT INTO orders (customer_id, order_date, order_status, num_items, total_cost)
VALUES ('$customer_id', CURRENT_TIMESTAMP, 'Order Placed', '$num_items', '$total_cost')";
$stmt = mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt, $sqlO)) {
header("Location: ../shop/checkout.php?error=sqlerror");
exit();
}
else { //if statement here for second sql insert
$sqlMaxId = "SELECT order_id FROM orders ORDER BY order_id DESC LIMIT 1";
$sqlOI = "INSERT INTO order_item (order_id, product_id, quantity)
VALUES ('$sqlMaxId', '$productID', '$productQty')";
$result = mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($result, $sqlOI)) {
header("Location: ../shop/checkout.php?error=sqlerror3");
}
else {
mysqli_stmt_execute($stmt);
unset($_SESSION['shopping_cart']);
header("Location: ../shop/account.php");
exit();
}
}
}
All of the variables are named correctly, but there's no point putting them here. Maybe worth mentioning that all the variables are being taken via $_POST from another page where a form is submitted.
For finding the max id number, I have tried using MAX(id) but doesn't seem to work, maybe it's because the whole statement isn't working properly, but this definitely will work.
I think it could be a problem with how the statements are nested?
Any help would be appreciated!
$sqlMaxId = "SELECT order_id FROM orders ORDER BY order_id DESC LIMIT 1";
$sqlOI = "INSERT INTO order_item (order_id, product_id, quantity)
VALUES ('$sqlMaxId', '$productID', '$productQty')";
Here you are inserting the actual string $sqlMaxID
Even if you did like the below so the variable contents would be included, $sqlMaxId represents the String "select ..." and not the results of that query.
$sqlOI = "INSERT INTO order_item (order_id, product_id, quantity)
VALUES (" $sqlMaxId "," $productID "," $productQty ")";
Nested Ifs == the Devil. Also this needs to be done in one transaction. What would happen if two customers submit at the same time and by the time the second sql statement runs, the max ID has changed to the next customer?
What you should do is create a stored procedure that will handle all of the insert logic. Your application should not know or care about how the data is organized in the database. So in your new stored procedure you can use the Output Clause to output the data you just inserted into table 1 (including the identity column) into a table variable that will contain only what was successfully inserted. You can then join to that table variable to get the ID you want for the second insert. The output clause looks like this:
DECLARE #NewItem Table(ItemID int)
insert into Table1(Some stuff)
OUTPUT Inserted.ID
INTO #NewIssue
Values(1,2,3, etc)

Save data from a php page into 2 sql table

Good day!I really need your help guys. Can someone teach me what statements I need to save data into 2 tables. I have 2 tables namely sales and sales_item. The relationship bet. them is the srfno where in sales table it is the PK, so in sales_item table it is the FK. My php form has srfno, date, clientid, clientname, address, contactperson, contactno, returnreason, explanation, refno; these data should be saved in sales table which I already did and it's working brilliantly. My problem now is that qty, serial, desc also include in the form but these should be saved in sales_item table. When I execute the page, it saves the data in sales table and the qty, serial and desc can't save to sales_item table and it didn't get the srfno from sales table.
here's my code for saving qty, serial and desc to sales_item table which is being ignored by my sql statement when saving.
$retitem= "Select `srfno` from sales_item";
$psql= mysql_query($retitem,$con);
$reti = mysql_num_rows($psql);
$reti = $reti + 1;
while($return = mysql_fetch_assoc($psql))
{
if(isset($return['srfno']))
{
$srfno=$return['srfno'];
}
}
$addretex="Insert into `sales_item` (`sitemid`,`srfno`, `retqty`, `retdesc`,`retserial`, `exqty`, `exdesc`,`exserial`,)
VALUES (' ','$srfno', '$qty', '$desc', '$serialno', ' ', ' ', ' ')";
$ret=mysql_query($addretex);
easily you can use LAST_INSERT_ID to insert your last 3 values into table sales_item with related sales id.
INSERT INTO sales (srfno,date,clientid,clientname,address,contactperson,contactno, returnreason,explanation,refno)
VALUES('value1', 'value2','','',...);
INSERT INTO sales_item (sales_id,qty,serial,desc) //sales_id is foreign key came from sales table and its value will be insert automatically by using LAST_INSERT_ID.
VALUES(LAST_INSERT_ID(),'value_1', 'value_2','value_3');
Before Inserting into 'sales_item', you need to check whether $srfno has valid value using
echo "srfno=".$srfno;exit;
if not, you can easily get value of $srfno after inserting into sales table, just do following after inserting into sales table
$srfno=mysql_insert_id();
You can also check error of insert query of sales_item by mysql_error function
mysql_query($addretex) or die("$addretex ".mysql_error());

PHP MySQL INSERT data from another table using the where clause and insert unique values to the same rows

I want to insert data from one table into another where one field equals another in both tables. So far this works. The problem is, I also need to insert additional data into those same rows that is not included on the first table.
//enter rows into database
foreach($_POST['sku'] as $row=>$sku)
{
//this is the data that needs to be added to the table
$item_sku=$sku;
$image="/$item_sku.jpg";
$small_image="/$item_sku.jpg";
$thumbnail="/$item_sku.jpg";
//currently this is what is working to import data from one table to the other
$sql= "INSERT INTO magento_import (sku, description, price)
SELECT PR_SKU, PR_Description, PR_UnitPrice
FROM products
WHERE PR_SKU = '$sku'";
//I need something here to add the above variables to the same row where PR_SKU = '$sku'
if (!mysql_query($sql))
{
die('Error: '.mysql_error());
}
echo "$row record added";
}
The columns for the missing data on magento_table are called 'image', 'small_image', and 'thumbnail'. This is simple a hack to put data from an old product table into a new product table, export as a CSV, and run a profile in Magento. I don't need to worry about SQL injections. It's something I'm running off of a local machine. I'm trying to avoid as much manual data entry as possible while switching products over to a new ecommerce system. Thanks for any help you can give.
Selecting literal values should do what you intend:
$sql= "INSERT INTO magento_import (sku, description, price, image, small_image, thumbnail)
SELECT PR_SKU, PR_Description, PR_UnitPrice, \"$image\", \"$small_image\", \"$thumbnail\"
FROM products
WHERE PR_SKU = '$sku'";
You can use another update statement to do this. I doubt if you can do this with one single query
foreach($_POST['sku'] as $row=>$sku)
{
//this is the data that needs to be added to the table
$item_sku=$sku;
$image="/$item_sku.jpg";
$small_image="/$item_sku.jpg";
$thumbnail="/$item_sku.jpg";
//currently this is what is working to import data from one table to the other
$sql= "INSERT INTO magento_import (sku, description, price)
SELECT PR_SKU, PR_Description, PR_UnitPrice
FROM products
WHERE PR_SKU = '$sku'";
//I need something here to add the above variables to the same row where PR_SKU = '$sku'
if (!mysql_query($sql))
{
die('Error: '.mysql_error());
}else {
$sql = "UPDATE magento_import SET item='$item',image='$image',small_image='$small_image',thumbnail='$thumbnail' WHERE PR_SKU = '$sku'";
echo "$row record added";
}
}
You can just add the variables directly to the query. As long as they are quoted they will work as simple values.
$sql= "INSERT INTO magento_import (sku, description, price, x, y, z)
SELECT PR_SKU, PR_Description, PR_UnitPrice, '$x' AS x, '$y' AS y, '$z' AS z
FROM products
WHERE PR_SKU = '$sku'";

PHP/MySQL INSERT feature logic error

I recently asked a question about writing to multiple tables: PHP/MySQL insert into multiple data tables on submit
I have now tried out this code and there are no errors produced in the actual code but the results I am getting are strange. When a user clicks register this 'insert.php' page is called and the code can be found below.
<?php
$username = $_POST["username"];
$password = $_POST["password"];
$institution = $_POST["institution"];
$conn = pg_connect("database connection information"); //in reality this has been filled
$result = pg_query($conn, "INSERT INTO institutions (i_id, name) VALUES (null, '$institution') RETURNING i_id");
$insert_row = pg_fetch_row($result);
$insti_id = $insert_row[0];
// INSTITUTION SAVED AND HAS ITS OWN ID BUT NO MEMBER OF STAFF ID
$resultTwo = pg_query($conn, "INSERT INTO staff VALUES (NULL, '$username', '$password', '$insti_id'");
$insert_rowTwo = pg_fetch_row($resultTwo);
$user_id = $insert_rowTwo[0];
// USER SAVED WITH OWN ID AND COMPANY ID
// ASSIGN AN INSTITUTION TO A STAFF MEMBER IF THE STAFF'S $company_id MATCHES THAT OF THE
// INSTITUION IN QUESTION
$update = pg_query($conn, "UPDATE institutions SET u_id = '$user_id' WHERE i_id = '$insti_id'");
pg_close($conn);
?>
What the result of this is just the browser waiting for a server response but there it just constantly waits. Almost like an infinite loop I'm assuming. There are no current errors produced so I think it may be down to a logic error. Any ideas?
The errors:
RETURNING clause is missing in the second INSERT statement.
Provide an explicit list of columns for your second INSERT statement, too.
Don't supply NULL in the INSERT statements if you want the column default (serial columns?) to kick in. Use the keyword DEFAULT or just don't mention the column at all.
The better solution:
Use data-moidifying CTE, available since PostgreSQL 9.1 to do it all in one statement and save a overhead and round trips to the server. (MySQL knows nothing of the sort, not even plain CTEs).
Also, skip the UPDATE by re-modelling the logic. Retrieve one id with nextval(), and make do with just two INSERT statements.
Assuming this data model (you should have supplied that in your question):
CREATE TABLE institutions(i_id serial, name text, u_id int);
CREATE TABLE staff(user_id serial, username text, password text, i_id int);
This one query does it all:
WITH x AS (
INSERT INTO staff(username, password, i_id) -- provide column list
VALUES ('$username', '$password', nextval('institutions_i_id_seq'))
RETURNING user_id, i_id
)
INSERT INTO institutions (i_id, u_id, name)
SELECT x.i_id, x.user_id, '$institution'
FROM x
RETURNING u_id, i_id; -- if you need the values back, else you are done
Data model
You might think about changing your data model to a classical n:m relationship.
Would include these tables and primary keys:
staff (u_id serial PRIMARY KEY, ...)
institution (i_id serial PRIMARY KEY, ...)
institution_staff (i_id, u_id, ..., PRIMARY KEY(i_id, u_id)) -- implements n:m
You can always define institution_staff.i_id UNIQUE, if a user can only belong to one institution.

Auto-creating a "link" table between 2 main tables (ex table EmployeeProject from Employee and Project tables)

I have these 2 tables, Medication containing: IDMedication, IDCategory, Name, and Supplier, containing: IDSupplier, Name. I want to automatically create a relationship table, MedicationSupplier, containing: IDMedication and IDSupplier as keys, Price, and Quantity.
My idea was to have a main page where i request the following data: (Medication)Name, IDCAtegory, (Supplier)Name, Price, Quantity.
I'm not sure if i'm doing the right thing here.
So this is what i'm receiveing in the .php where i do the insert:
$Denumire=$_POST['Denumire']; //Medication Name
$IDCategorie=$_POST['IDCategorie']; //IDCategory
$Nume=$_POST['Nume']; //Supplier Name
$Pret=$_POST['Pret']; //Price
$Stoc=$_POST['Stoc']; //Quantity
And this is my insert:
$q_produse = "INSERT INTO produse VALUES ('','$IDCategorie','$Denumire')";
$q_prodfurniz = "INSERT INTO produsfurnizor VALUES ('','$IDFurnizor','$Pret','$Stoc')";
mysql_query($q_produse) or die($error);
mysql_query($q_prodfurniz) or die($error);
mysql_close();
My main problem at the moment is that i don't know how to insert IDMedication in the relationship table. Any help / suggestions of improving my code would be greatly appreciated. Thanks!
It sounds like you're needing to get the auto id created for the rows in your Medication and Supplier tables. You can use mysql_insert_id()
$q_produse = "INSERT INTO produse VALUES ('','$IDCategorie','$Denumire')";
$q_prodfurniz = "INSERT INTO produsfurnizor VALUES ('','$IDFurnizor','$Pret','$Stoc')";
mysql_query($q_produse) or die($error);
$produse_id = mysql_insert_id();
mysql_query($q_prodfurniz) or die($error);
$prodfurniz_id = mysql_insert_id();
$q_relationTable = "INSERT INTO MedicationSupplier VALUES ('$produse_id','$prodfurniz_id')";
mysql_query($q_relationTable) or die($error);
mysql_close();
Documentation on mysql_insert_id() is available at http://php.net/manual/en/function.mysql-insert-id.php
http://us2.php.net/mysql_insert_id
retrieves the last autoincremented value, in this case, IDMedication.

Categories