save data in mysql by stored procedure - php

i have a table that must by update every month, due i upload text file on server and save it in temporary table, the bellow code show it:
$result_emp = "LOAD DATA LOCAL INFILE'".$myFile_emp."' INTO TABLE infemptemp COLUMNS TERMINATED BY ','";
then after update successfully and insert new data in "infemptem" table, i should compare the data of main table's "infemp" that have old data by "infemptemp" that have new data, for do this Scenario i write bellow code:
$viwe_emp =mysqli_query($conn,"select * from infempsame where 1");
$NumRows_emp=mysqli_num_rows($viwe_emp);
//echo $NumRows_vam;
$i=0;
while(($row=$viwe_emp->fetch_assoc())!=NULL)
{
$prsid1=$row['PrsID'];
$AccID1=$row['AccID'];
$numid1=$row['NumID'];
$sql2="select * from infempsame where prsID='".$prsid1."';";
if (mysqli_query($conn,$sql2))
{
$sql2_update="UPDATE `infemp` SET AccID='".$AccID1."',NumID='".$numid1."' WHERE prsID='".$prsid1."';";
if(mysqli_query($conn,$sql2_update))
{
$i+=1;
}
}// end if (mysqli_query($conn,$sql2))
}// end while insert new fields of infvam
by attention to the code and have 3500 record in "infempsame " table on my database, when i want update "infemp" table, the time out on browser occur.
I think if write above code by procedure, my problem solved.
Is it true? How do i can write procedure and call or use it?
Best Regards.

A stored procedure would be overkill. There is a better way hidden away but it get's only a very brief mention in the manual
You can also perform UPDATE operations covering multiple tables.
However, you cannot use ORDER BY or LIMIT with a multiple-table
UPDATE. The table_references clause lists the tables involved in the
join. Its syntax is described in Section 13.2.9.2, “JOIN Syntax”. Here
is an example:
UPDATE items,month SET items.price=month.price WHERE
items.id=month.id;
Thus you can write a simple query to get rid of the PHP script like this.
UPDATE infemp, infemptemp
SET infemp.AccID=infemptemp.AccID,
infemp.NumID=infemptemp.numID
WHERE infemp.prsID=infemptemp.prsID;
if you have an index on the prsID column this should complete very quickly.

Related

Clarifications about Multi Queries

I'm trying to execute 2 queries, but whenever I follow the guides online about multi queries, its not doing either of the queries.
What I'm trying to do on the first query is to INSERT or ADD whatever the user inputs on $HISTORY on the record that's currently on colHistory; I.E.:
Current data on colHistory:
A
User inputs 'B' on $HISTORY, the syntax should add 'B' on the 'A' that's currently on record, or 'AB'. Then use the second query to UPDATE all the other records or columns on this particular row.
Here's the code (Please note that the '...' means more code that's unnecessary):
$query = INSERT INTO tbInventory SET colHistory='$HISTORY' WHERE colSerno='$SERIALNUM';";
$query .= "UPDATE tbInventory SET
colImage='$IMAGE',
colSerno='$SERIALNUM',
...
...
colHistory=''
WHERE colSerno='$SERIALNUM'";
mysqli_multi_query($con,$query);
Please note where I declared colHistory as '' before I insert the data from the form. I'm not sure if I'm doing it right on this part. Is there anything that I'm missing?
*Edit:
I have already tried executing the queries one by one as:
mysqli_query($con,"INSERT INTO tbInventory SET colHistory='$HISTORY' ");
mysqli_query($con,"UPDATE tbInventory SET
...
...
colHistory=''
WHERE colSerno='$SERIALNUM'";
Yet it doesn't seem to work either, the whole thing gets ignored.
(** I have a script below the code block above where I could print the results already, and it does run)
Well I can tell you why your first query is broken.
INSERT INTO tbInventory SET colHistory='$HISTORY'
This query is using UPDATE syntax but you are telling the query processor to expect INSERT INTO syntax. So the query is unable to execute.
Decide whether you are needing to UPDATE an existing record or INSERT a new one and alter your query to reflect that. (Change INSERT INTO to UPDATE or change "Set colHistory = '$ History'" to "Values ('$ History', 'col2Val', and so on..")
As for your second query, the syntax looks alright from what you have shown but since you didn't post the entire query its hard to say what is happening there. If you can show more of that query I can update this response.
Here's a good SO question on inserts vs updates.
What are differences between INSERT and UPDATE in MySQL?
I ended up dropping the multi-query method and I did got my intended results by somehow cheating:
I assigned the old data or the data that's currently on the colHistory cell, displayed it, but I disabled the textarea. I then created one more hidden textbox in the script with the old data in it and then hid it to the users view.
I then concatenated both textareas with the new one that I've created that the user could modify, emulating the results wanted.

Simple concurrency in PHP?

I have a small PHP function on my website which basically does 3 things:
check if user is logged in
if yes, check if he has the right to do this action (DB Select)
if yes, do the related action (DB Insert/Update)
If I have several users connected at the same time on my website that try to access this specific function, is there any possibility of concurrency problem, like we can have in Java for example? I've seen some examples about semaphore or native PHP synchronization, but is it relevant for this case?
My PHP code is below:
if ( user is logged ) {
sql execution : "SELECT....."
if(sql select give no results){
sql execution : "INSERT....."
}else if(sql select give 1 result){
if(selected column from result is >= 1){
sql execution : "UPDATE....."
}
}else{
nothing here....
}
}else{
nothing important here...
}
Each user who accesses your website is running a dedicated PHP process. So, you do not need semaphores or anything like that. Taking care of the simultaneous access issues is your database's problem.
Not in PHP. But you might have users inserting or updating the same content.
You have to make shure this does not happen.
So if you have them update their user profile only the user can access. No collision will occur.
BUT if they are editing content like in a Content-Management System... they can overwrite each others edits. Then you have to implement some locking mechanism.
For example(there are a lot of ways...) if you write an update on the content keeping the current time and user.
Then the user has a lock on the content for maybe 10 min. You should show the (in this case) 10 min countdown in the frontend to the user. And a cancel button to unlock the content and ... you probably get the idea
If another person tries to load the content in those 10 min .. it gets an error. "user xy is already... lock expires at xx:xx"
Hope this helps.
In general, it is not safe to decide whether to INSERT or UPDATE based on a SELECT result, because a concurrent PHP process can INSERT the row after you executed your SELECT and saw no row in the table.
There are two solutions. Solution number one is to use REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. These two query types are "atomic" from perspective of your script, and solve most cases. REPLACE tries to insert the row, but if it hits a duplicate key it replaces the conflicting existing row with the values you provide, INSERT ... ON DUPLICATE KEY UPDATE is a little bit more sophisticated, but is used in a similar situations. See the documentation here:
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
http://dev.mysql.com/doc/refman/5.0/en/replace.html
For example, if you have a table product_descriptions, and want to insert a product with ID = 5 and a certain description, but if a product with ID 5 already exists, you want to update the description, then you can just execute the following query (assuming there's a UNIQUE or PRIMARY key on ID):
REPLACE INTO product_description (ID, description) VALUES(5, 'some description')
It will insert a new row with ID 5 if it does not exist yet, or will update the existing row with ID 5 if it already exists, which is probably exactly what you want.
If it is not, then approach number two is to use locking, like so:
query('LOCK TABLE users WRITE')
if (num_rows('SELECT * FROM users WHERE ...')) {
query('UPDATE users ...');
}
else {
query('INSERT INTO users ...');
}
query('UNLOCK TABLES')

Newly inserted rows deleted when creating a trigger in MySql

I m trying to fetch the IDs of all last inserted rows. For that i was created a trigger as follows;
CREATE TRIGGER mytable_insert
AFTER INSERT ON mytable
FOR EACH ROW SET #insertIDs = CONCAT_WS(',', #insertIDs, NEW.id)
then in the program section the code is like follows
$sql="INSERT INTO `table` ({columns}) VALUES({values})";
$command=Yii::app()->db->createCommand($sql);
if($command->execute()){
$sql='SELECT #insertIDs AS "Inserted_IDs"';
$command=Yii::app()->db->createCommand($sql);
$rows=$command->queryAll();
var_dump($rows);
}
Here I got some IDs....but the problem is i could not find those rows in the database...Dont know what is the mistake.....help needed....
What is your sql syntax?
SELECT #insertIDs AS "Inserted_IDs"
Where "From" ? (SELECT * FROM T;)
The #insertIDs is a user variable, which is visible in current session; so, you may create the different variables with the same name in other MySQL sessions.
It looks like your code uses more then one session, and therefore showы unexpected result. Check that your code uses one session ( I mean MySQL connection) to execute INSERT and SELECT query.
Also, you can try this code in MySQL command-line console, it must work.

How can i get the last affected table in php

I want to get the last affected table name (after insert).
I tried with mysql_insert_id() but i got only id.
I want table name also.
Can anyone give me the idea for my problem
It's a strech... But if :
you are running mysql 5.6.3 +
you still have access to the insert query (let's say it's $query)
you are sure it's an insert query (because, hey, you know you want last_insert_*, don't you?)
You can try:
$row = mysql_fetch_assoc(mysql_query("explain $query"));
$table = $row['table'];
From mysql 5.6.3+ you can combine explain with a insert into query.
This should return only 1 row, I think.
I dont have mysql 5.6.3+ myself to test it.
You can override mysql_query function as defined in this post, save you last call table name in global var or session and pray for last called insert finish last.
// THIS JUST SAMPLE... use code from link below ^
function custom_mysql_query($query){
if(strstr('INSERT',$query)){
/*GET YOUR TABLE NAME WITH REGEX*/
}
basic_mysql_query($query);
}
This is very very very bad solution for me. But in theory will work.
You mention in your comment that you're using a common function to apply the changes in, preventing you from 'knowing' what the last table is you inserted in.
If that's the case: your logic is flawed.
MySQL is not gonna tell you what the last table is it did an INSERT in. You will have to write a hook in your function where you last know what table you're gonna update. No matter what function you use, you must specifiy a table name at some point, before executing the insert. You store the table name at that point.
You can do that in many ways, depending on your needs:
store it in a mysql table (last_updated_table with only 1 column,
for example)
store it in a variable (if you only need it in the
same request)
store it in a session (I wouldn't opt for this)
You can use the information_schema database if you have one :
SELECT TABLE_SCHEMA, TABLE_NAME, UPDATE_TIME
FROM TABLES
ORDER BY UPDATE_TIME DESC
LIMIT 0,1
Use this after your query, and you'll get the affected table.

How to sync two database tables with each other in mysql PHP

I have two tables called clients, they are exactly the same but within two different db's. Now the master always needs to update with the secondary one. And all data should always be the same, the script runs once per day. What would be the best to accomplish this.
I had the following solution but I think maybe theres a better way to do this
$sql = "SELECT * FROM client";
$res = mysql_query($conn,$sql);
while($row = mysql_fetch_object($res)){
$sql = "SELECT count(*) FROM clients WHERE id={$row->id}";
$res1 = mysql_query($connSecond,$sql);
if(mysql_num_rows($res1) > 0){
//Update second table
}else{
//Insert into second table
}
}
and then I need a solution to delete all old data in second table thats not in master.
Any advise help would be appreaciated
This is by no means an answer to your php code, but you should take a look # Mysql Triggers, you should be able to create triggers (on updates / inserts / deletes) and have a trigger (like a stored proceedure) update your table.
Going off the description you give, I would create a trigger that would check for changes to the 2ndary table, then write that change to the primary table, and delete that initial entry (if so required) form the 2ndary table.
Triggers are run per conditions that you define.
Hopefully this gives you insight into 'another' way of doing this task.
More references on triggers for mysql:
http://dev.mysql.com/doc/refman/5.0/en/triggers.html
http://www.mysqltutorial.org/create-the-first-trigger-in-mysql.aspx
You can use mysql INSERT ... SELECT like this (but first truncate the target table):
TRUNCATE TABLE database2.client;
INSERT INTO database2.client SELECT * FROM database1.client;
It will be way faster than doing it by PHP.
And to your notice:
As long as the mysql user has been given the right permissions to all databases and tables where data is pulled from or pushed to, this will work. Though the mysql_select_db function selects one database, the mysql statement may reference another if you use complete reference like databasename.tablename
Not exactly answering your question, but how about just using 1 table, instead of 2? You could use a fedarated table to access the other (if it's on a different mysql instance) or reference the table directly (like shamittomar's suggestion)
If both are on the same MySQL instance, you could easily use a view:
CREATE VIEW database2.client SELECT * FROM database1.client;
And that's it! No synchronizing, no cron jobs, no voodoo :)

Categories