PHP - Performing Additional Queries - php

I'm a couple months into grasping PHP and MySQL basics.
I am currently querying table A and displaying it live as an end user (ie, mysite.com/includes/querying.php). I'm echoing out all the different fields in table A to display beside two decision buttons; accept and deny. The data is being produced from form requests each as a new row. I'd like to have the control to determine if I want to accept or deny each request (row) independently.
My goal is to take this data querying from table A and select accept or deny and have the row written to another table; table B for querying additional data.
For example, the row in each table itself in it's simplest can have two fields, name and status. By default I have the status on all new rows set as PENDING. So I query Jon Doe and PENDING. Jane Doe and PENDING. Joe Doe and PENDING, and so on.
Once a new row of data is queried from table A and I select accept, the accept button forces writing this information into table B, switching the status from PENDING to Y or N and removing it from table A. Most of this is easy to complete in a couple steps.
Also, I started to make some progress by having the form submission write the data to BOTH table A and table B on submit. Then I'd only need to update the status from PENDING to Y or N in table B. However when I tried using WHERE I could only write a blanket condition that updates the status column in every row in table B which is below. I am clueless on how to make this statement specific to only the row I am selecting.
$query = "UPDATE table B SET confirmed='Y' WHERE confirmed='PENDING';
So I was wondering if there is a simple way to base the field update from PENDING to Y / N by checking an auto-increment ID, an email address, etc, basically something unique against itself?
As for resources I've utilized Learning PHP, MySQL & JavaScript from O'Reilly and completed many Google searches with failed attempts and phrasing.

You might want to rethink your database design, and google 3rd normal form. You want to avoid duplicating data. I recommend using 1 table and adding a column, or have an additional table that you join to.
But to answer your question you can use the AND keyword in your query.
UPDATE table B SET confirmed='Y' WHERE confirmed='PENDING' AND firstName = 'Jon' AND lastName = 'Doe';
Doing an update by the primary key would be best, because you could have multiple people with the same name. Ex:
UPDATE table B SET confirmed='Y' WHERE id = 1234;

Related

MySQLi subscribe list table

I have a table called users and a table called pages. Users of the system can subscribe to a page and receive updates about the page. My problem is that users and pages will be updated dynamically (ie. no manual intervention to the tables) and I don't want to keep adding another column everytime someone subscribes to the page.
How can I achieve updating both the users table and the pages table dynamically to reflect that they have subscribed to that page?
My idea would be to add an comma separated array of usernames into the pages table and update them as users subscribe/unsubscribe.
Just making it an official answer:
While the initial hunch may be to use comma separated values to represent the link between those 2 tables (or any other way of saving the data in one column like saving a json string), it is actually bad practice because it does not conform to the First Normal Form (and definitely not 2nd and 3rd).
First Normal Form - Wikipedia
First Normal Form says you should never store more than 1 value in 1 table cell.
The problem, in short, starts when you'll need to use that data, which will actually take you at least 2 actions - 1 is reading the data from the database and 2nd is to parse it in your languaging script. Imagine what happens when you need then to use that data to read some other data from the database - you are making more sql queries than you need and taking at least twice the time (+resources). It becomes even more complicated when you need to use JOIN queries or have other one-to-many data relationships.
The solution then is simple - you need to create a 3rd table that serves as an intermediate table.
You can call it users_pages or user2pages and that represents the 1 to many relationship between 1 user and many pages.
The structure of the table is as simple as:
users_pages
-----------
-- id // a unique id for the relationship, can be auto generated
-- user_id // the user id
-- page_id // the page id
-----------
This allows you to build a more robust application as well as run advanced queries and calculations without the need to parse the data in your script (i.e count amount of pages each user is subscribed to, or amount of users subscribed to 1 page).
Unsubscribing can be also much easier this way since you don't need to read the users or pages table at all. You simply delete the relation from the users_pages table.
Without it, you will need to (a) first read the users table (b) get the pages data comma separated (c) parse the data and remove the specific page from it (d) save the new data again to the database. That's 4 actions and 2 SQL queries...
I hope this helps!

Check if data entered by user in html form already exists in database in php

After entering data in html form while clicking on button to add the data in the database, I want to check whether the user already exists in the database. I am using php v5.3.5 and mysql v5.5.8.
Data is stored in 2 tables simultaneously named person and other and there is no primary key(in both columns) since there is no column which can be treated as primary key
Can any one help me how to do that??
Code is::
$sqlComm="Insert into person(Name,father_name,date_birth,
gender,Res_Address,Mobile_no)
values('$name','$fatherName','$dob',
'$gender1','$resAddress','$mobileNo')";
$sql="insert into other_staff(p_id,employer,off_ph_no)
values('$pId','$employer1','$phOffice')";
Id is automatically generated for each person which is retrieved and stored in other table as p_id.
combination of name,father_name,date_birth,employer can be made unique..
It seems like none of the fields suggested can be a primary key, any of them or a combination of them cannot uniquely identify a person. It's a really strange database design and I urge you to check your database design.
You will have to a search by doing a separate select query to find if the user exists. Also Ensure both the statements are executed inside a transaction.
You will have to think about what makes a person unique for your schema/application. Changing the mobile number probably does not make one a new person, but am i the same as an existing person, if we share the name, father_name, date_birth and gender? If so, make that a unique key and you will have something your database can tell you, that it already exists. Just in case you did not already know: keys can span multiple columns.
Dispite with a bad schema, we can find a way(given below) to check weather a user exist or not. BUT I think you also want to check second table THAT with particular user there is an employer or not. Then here is problem in your database cause there is no column in PERSON or OTHER_STAFF's table which can tell us the Particular employer of a specific user in PERSON table
Solution: But for this condition you can use cross join to get nearly correct result:
if($result=mysql_query("SELECT 1 FROM person p CROSS JOIN other_staff e WHERE p.name='$name' AND p.father_name='$father_name' AND p.date_birth='$dob' AND p.gender='$gender1' AND p.Res_Address='$resAddress' AND p.Mobile_no='$mobileNo' AND e.employer='$employer1' AND e.off_ph_no='$phOff';")){
if(mysql_fetch_array($result)){
//exist
}else{
//not exist
}
}
Suggestion: Next time store auto generated id in PERSON and OTHER STAFF table BUT for this project- If you can store p_id in PERSON table then this query will return 1 on exist, otherwise null(same in above):
$sql="SELECT 1 FROM person p LEFT JOIN other_staff e ON p.p_id=e.p_id WHERE p.name='$name' AND p.father_name='$father_name' AND p.date_birth='$dob' AND p.gender='$gender1' AND p.Res_Address='$resAddress' AND p.Mobile_no='$mobileNo' AND e.employer='$employer1' AND e.off_ph_no='$phOff';";

Populating a third table to maintain efficiency

I am currently working on a PHP/MySQL project for an assignment. In studying the efficient design of databases while working on the assignment I notice that in many cases it is good practice to create a third table when working with only two sets of data.
For example, if we have a table for "Students" and a table for "Addresses" it appears to be a good idea to create a third table i.e. "Student_Addresses" since a student can hypothetically have more than one address (separated parents etc.) and a single address can represent more than one student (siblings).
My question is: How do we go about populating that third table? Is there a way that it is done automatically using primary and/or foreign keys?
I've tried Google and my textbook to understand this but I've gotten nowhere. Links to tutorials or articles would be greatly appreciated.
Thanks for your help. I hope the question and example are clear.
n:m or 1:m normalization rule
Option 1:
user table
id
f_name
s_name
......
user address table
id
user_id // this should be index only as foreign keys will allow 1:1 only
address line 1
address line 2
address line 3
address_type (home, office ....)
Option 2:
user table
id
f_name
s_name
......
address table
id
address line 1
address line 2
address line 3
address_type (home, office ....)
user_address table
userId
addressId
according to your description option 2 would be the right solution. After adding the data to user table and address table then you need to add the data to user_address table manually. Some Object relational mapper (ORM) may do add the data to the third table automatically but you need to define the relations. check http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html.
http://docstore.mik.ua/orelly/linux/sql/ch02_02.htm
http://www.keithjbrown.co.uk/vworks/mysql/mysql_p7.php
You can save the data in the third table using triggers when the data is inserted/updated/deleted in your base tables. You can learn more about triggers at
mySQL Triggers
However in your case it would be better if you could write the logic at the application/code level to make an entry in the third table. You can set up foreign key relationships to this table from your base tables so that the data remains consistent.
There is no native method in MySQL to populate Student_Addresses in your situation - you have to take care of entering data (connections) by yourself, but you can use - for example - transactions - see answers in this topic: SQL Server: Is it possible to insert into two tables at the same time?
For taking care of connections consistency - in Student_Addresses make not-null fields for relations to ID from Student and ID from Address, make both of these field as unique key together and use ON UPDATE CASCADE and ON DELETE CASCADE. This will take care of removing records from junction table when removing records from any of two other tables and also won't allow you to add same address to the same student twice.
I don't think data will be populated automatically rather it's responsibility of user to insert data.
I am note sure about PHP but using Hibernate and Java this can be done seemlessly. Since data of Students and addresses could be coming through some web application Hibernate can map java objects to records in table and also populate relationship table.

Issue in copying rows from one table to another

I am implementing a request mechanism where the user have to approve a request. For that i have implemented a temporary table and main table. Initially when the request is added the data will be inserted to the temporary table, on approval it will be copied to the main table.
The issue is there will be more than 5k rows to be moved to the main table after approval + another 3-5 row for each row in the detail table (stores the details).
My current implementation is like this
//Get the rows from temporary table (batch_temp)
//Loop through the data
//Insert the data to the main table (batch_main) and return the id
//Get the details row from the temporary detail table (batch_temp_detail) using detail_tempid
//Loop through the data
//Insert the details to the detail table (batch_main_detail) with the main table id amount_id
//End Loop
//End Loop
But this implementation would take atleast 20k queries. Is there any better ways to implement the same.
I tried to create a sqlfiddle but was unable to create one. So i have pasted the query in pgsql.privatepaste.com
I'm sorry that I'm not familiar with PostgreSQL. My solution is in MySQL, I hope it can help since if they (MySQL & PostgreSQL) are same.
First, we should add 1 more field into your batch_main table to track the origin batch_temp record for each batch_main record.
ALTER TABLE `batch_main`
ADD COLUMN tempid bigint;
Then, on approval, we will insert 5k rows by 1 query:
INSERT INTO batch_main
(batchid, userid, amount, tempid)
SELECT batchid, userid, amount, amount_id FROM batch_temp;
So, with each new batch_main record we have its origin batch_temp record's id. Then, insert the detail records
INSERT INTO `batch_main_detail`
(detail_amount, detail_mainid)
SELECT
btd.detail_amount, bm.amount_id
FROM
batch_temp_detail `btd`
INNER JOIN batch_main `bm` ON btd.detail_tempid = bm.tempid
Done!
P/S:
I'm confuse a bit about the way you name your fields, and since I do not know about PostgreSQL and by looking into your syntax, can you use same sequence for primary key of both table batch_temp & batch_main? If you can, it's no need to add 1 more field.
Hope this help,
Simply need to update your Schema. Instead of having two tables: one main and one temporary, you should have all the data in main table, but have a flag which indicates whether a certain record is approved or no. Initially it will be set to false, and once approved it will simply be set to true and then the data can display on your website etc. That way you will not need to write the data two times, or even have to move it from one table to another
You haven't specified RDBMS you are using, but good old INSERT with SELECT in it must do the trick in one command:
insert main (field1,...,fieldN) select field1,...,fieldN from temporary

splitting data into multiple tables

I am building a employees page.
Some of the information goes into an 'employees' table but some of it goes into a 'availability' table that is referenced to the 'employee' table:
availability:
id / employeeid (unique id from employees table) / monday available / and on and on /
So I don't have that unique ID from the employees table until I create them.
Is it fine to do a query where I set the employee info and then a query to get the last created row in the employee table and then use the unique id from that to set the availability...
Or is that messy and should I have a create employee page and THEN a set availability page?
So basically I want to know if it is cleaner and 'better' coding to separate the two functions?
Adding to #Quassnoi's answer:
You would add the employee record, then use the MySQL LAST_INSERT_ID() function to find the autoincremented unique id for the employee record you added. You can then feed that value back into the availability INSERT statement.
More details are on the MySQL manual page at http://dev.mysql.com/doc/refman/5.1/en/example-auto-increment.html
It's important that you not use a SELECT statement (e.g. SELECT MAX(employee.id)) since there might be other uses adding records as well. LAST_INSERT_ID() is specific to your connection
Of course create employee first, availability then.
If your tables are InnoDB, you can do it in a transaction so that you can rollback the whole update if something goes wrong.
Is it fine to do a query where I set
the employee info and then a query to
get the last created row in the
employee table and then use the unique
id from that to set the
availability...
Yes, that sounds OK. If you use an autoincrement column for employeeid, you can then use mysql_insert_id() or equivalent to retrieve that last inserted id safely. Don't do SELECT MAX(employeeid) FROM ...., because you might get problems when loads of people are using it concurrently.
You can easily get the last insered record via
mysql_insert_id()
After that, you can insert an availability record for the desired employee.
Note: I would choose a framework that takes care of these issues, like Symfony or Cake.
Using the "last created row" may not always work the way that you're expecting and may complicate things in the future if there's growth or if another programmer assumes the project. If I understand what you're looking for, you should instead have 3 tables. One table for employees, one table for availability, and a third table should be used to store unique records for the association. In the association table each row will have columns for : a unique ID, the employee id, the availability id.

Categories