I'd like to add a counter to my website.
I am currently using php and mysql.
An example would be a total count of people who logged in my website.
The structure would look like this
|Total User Logins|
| 1|
If a user logs in though, I'd like to do this
|Total User Logins|
| 2|
How would I do this? At the moment it only creates a new row, which is not what I am after.
This is what I tried to do:
mysql_query(" UPDATE `Statistics` SET `Success`= `Success` + 1 WHERE 1 ");
^ this works on the phpmyadmin panel. But does not work on the php script.
Thanks
You need to be more specific in the WHERE clause, as to the specific column that is to be updated. That's why your code failed you and is creating a new row each time.
I.e.:
mysql_query(" UPDATE `Statistics` SET `Success`= `Success` + 1 WHERE column_x = 'y' ");
Side note: column_x could be User as per what you posted for column names. I didn't see one called Success. The y is an example also. Use the value from the given row you wish to update.
This is purely an example, given you seem to have left out some important details.
By the way, the api you're using is quite old. It is recommended that you move over to either the mysqli_ or PDO api as soon as possible and preferably with a prepared statement. This will help safeguard against a possible SQL injection should user input be involved or any other method such as an href through a GET method.
Related
We have a table on our database that tracks user behavior.
Basically each page that the user views we track this.
In the table we have the following:
id | user_id | user_ip | page | created_on
When a user checks the site from PC and let's say he checks a specific article the system saves under "page" the following "/article/specific/slug" however if the user checks the same page from the mobile version of the website it saves "http://m.website.com/article/specific/slug"
We are looking to change this.
We have added a new field in the database as enum (pc, m) and therefore we want regardless of device to save under "page" always "/article/specific/slug"
One issue is that we now have 30 million records in the past that need to be converted.
Meaning we write a query that checks if "http://m.website.com" exists update the field removing the "http://m.website.com" and making the "device" field updated as "m".
Can someone please help with this?
Query:
update visits_table
set
page=replace(page, 'http://m.website.com', ''),
device='m'
where
page like 'http://m.website.com%';
To go through 30 mil rows you'll have to... go through 30 mil rows. So you'll either do it just with the above query either:
when the site is down for maintenance
when the site has low traffic (e.g early morning hours?)
whenever you want, but expect some stress on the mysql until it's done (it may take a while)
Otherwise, if your ids are incremental, you can update in batches by splitting the query in many queries. e.g:
update ... where ... and id between 1 and 1000000;
update ... where ... and id between 1000001 and 2000000;
update ... where ... and id between 2000001 and 3000000;
...
I am new in forum, and need some help to do one functionality for my unity game. I am trying to save the progress of the player in one mysql database, like this:
userid level stars
29 1 2
29 2 1
45 1 3
50 1 2
50 2 3
50 3 1
29 3 3
so the script send the userid provided by the user registration in the begining of the game. and for each level he complete, the script send the number of the level, and the amount of stars collected in the level..
the problem and question is, how I configure this in the php script and mysql database to save the information only once? because if the player with the id 50 play the first level, will add a line with the information, but if the same player play the first level again and change the amount of stars, I dont want a new line, just update the stars amount.
I take a look in the INDEX, UNIQUE, PRIMARY, FULLTEXT, SPATIAL functions but dont figured out what is the correct combination and how to put in the php script, and take a look in other questions in the forum but nothing like this.
thanks for the help!
I recommend you use http://redis.io/ (in-memory data structure store, used as database, cache and message broker) to save progress in the games.
First you want an unique index on the combination (userid, level) and then you want to do an update if the combination exists and an insert otherwise.
For how to create the unique index please take a look at How do I specify unique constraint for multiple columns in MySQL?
For how to code the SQL query to do update/insert please take a look at SQL: If Exists Update Else Insert
The article above uses Microsoft SQL syntax. In PHP you can code this by issuing the query and then using mysql_affected_rows to see how many rows where affected. If 0 rows where affected then you issue the INSERT query from PHP.
in pseudo code you need to do something like this in SQL.
UPDATE $table set column=value WHERE id=$ID
Hi brayan actually the problems is that no one will write code for you, you have to do it yourself. I guess you are unaware with SQL i.e., you asked that
how I configure this in the php script and mysql database to save the
information only once? because if the player with the id 50 play the
first level, will add a line with the information, but if the same
player play the first level again and change the amount of stars, I
dont want a new line, just update the stars amount.
Anyhow You first required some basic understanding of SQL and PHP with Unity. I will recommend you this Guide Server_Side_Highscores of unityWiki it help you to make database and server logic intergartion with PHP.
Now for your Second important part of question.
You have to update user code after each level completion.Or you can simply ask to user about socre save.
Before inserting new record into the database you have to check that userId with level id alread exist or not. some thing like this
Select userid, level, stars
from youTableName
where userid = ?
and level = ?
if the above query return empty response then you simply need to add the record
INSERT INTO table_name (userid, level, stars)
VALUES (value1,value2,value3);
Otherwise you have to update that specific column.
I have a table that contains invoices for several companies, each company needs to have their own incrementing invoice number system.
id | invoiceId | companyId
--------------------------
1 | 1 | 1
2 | 2 | 1
3 | 1 | 2
4 | 1 | 3
I was hoping to achieve this with a unique compound key similar to this approach for MyISAM outlined here, but it seems it is not possible with InnoDB.
I need to return the new ID immediately after insertion and have concerns about creating a race condition if I try and achieve this with PHP.
Is my best option to create a trigger and if yes what would that look like? I have no experience with triggers and my research into using an after insert trigger has me worried with this quote from the MariaDB documentation:
RESTRICTIONS
You can not create an AFTER trigger on a view. You can not update the
NEW values. You can not update the OLD values.
Thanks for any advice
You need to add a unique index besides getting your next value. The next value is best gotten by querying the table with a trigger or by some procedure within a transaction. The remark of trigger on a view is not relevant in that case.
The unique index is on companyId,invoiceId is required to prevent two insert processes running on the same company adding an invoice, which then can end up both with the same invoiceId. Even better is when you switch to InnoDB so you can use transactions: Then 2 processes started at virtually the same time can benefit from transaction isolation with as result that they will be serialized and you get 2 unique incrementing invoice ids returned without having to handle the unique index exception in your code.
As far as I know, mysql's last_id is connection based, and not global and shared between processes.
using this simple script I've validated my concerns
(note this is codeigniter syntax, but it's relatively easy to understand)
I accessed the following function twice, within 10 seconds of each other(in different browser windows)
function test(){
$arr['var'] = rand(0,100000000);
$this->db->insert('test_table',$arr);
sleep(30);
$id = $this->db->insert_id();
var_dump($id);
}
Interesting to note, instead of getting "2" as a response in both of them, I've gotten 1 and two respectfully. This makes even more sense when you look at the underlying function
function insert_id()
{
return #mysqli_insert_id($this->conn_id);
}
This solves the returned ID, Your race condition is the product of the underlying query, which is basically "Select MAX(invoiceId ) WHERE companyID = X" and add +1 to that, and insert it.
This should be possible with a table lock before insert, however this depends on how many times per second you expect this table to get updated.
note, on persistent connection the last_insert_id might work differently, I haven't tested it.
I am curious what path I should take to accomplish the following. I want multiple computers at one location to be able to view and make changes to data inside a mysql DB with a web browser. I dont have extensive knowledge in this area, but from what I do remember this was very difficult if not impossible.
Example: Lets say I have a record for John and I want 2 computers to be able to edit Johns record. Please note that the computers will not be editing the same portion of Johns record. Lets say one record is changing a status from need to be called to called and the other computer is changing the status of need to be ordered to ordered.
I want a solution that could natively handle this.
My current knowledge is building web interfaces with PHP and SQL. I would like to use these languages as I have some prior knowledge.
So my question: Is this possible? If, so exactly how would it work(flow of info)?
There are several ways that you can accomplish this. There's already some great PHP database editing software packages out there (phpMyAdmin).
To handle this in code though you can either use Transactions (depending on what flavor of SQL you're using this would be done differently)
One of the easier ways to ensure that you don't have people's data clashing with one another is just by adding additional where clauses to your statement.
Lets say you have a user record and you want to update the last name from Smith to Bill, and the user ID is 4.
Instead of writing
UPDATE users SET lastName='Bill' WHERE id='4'
You would add in:
UPDATE users SET lastName='Bill' WHERE id='4' AND lastName='Smith'
That way if someone else updates the last name field while you're working on it, your query will fail and you'll have to re-enter the data, thus faking a transaction
Use Transactions. Updating a single record at the exact same time isn't really supported, but applying one transaction followed immediately by another certainly is. This is native to MySQL.
START TRANSACTION;
SELECT #A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=#A WHERE type=1;
COMMIT;
One other thing to do is the old desktop approach. Wich is almost mannualy control the flow of modifications. I will show:
Say that you have a client table with the fields id, firstname, lastname, age. In order to control multiple users updates you will add the version integer default 0 field to this table.
When you populate the object on the form to an user you will also store the actual version that the user has selected.
So lets assume that your client table is like this:
id firstname lastname age version
1 Tomas Luv 20 0
2 Lucas Duh 22 0
3 Christian Bah 30 0
When the user select the client with the id=1 the version of this row is, in this moment, 0. Then the user update the lastname of this client to Bob and submit it.
Here comes the magic:
Create a trigger (before update) that will check the current version of that registry with the version that the user previously selected, something like this (this is just pseudo code, as I'm doing it from my head):
create trigger check_client_version on client before update as
begin
if new.version != old.version then
throw some error saying that a modification already was done;
else
new.version = old.version + 1;
end if;
end;
On the application you check if the update has this error and inform to user that someone else made change on the registry he try to change.
So with the given example it would be like:
1 - The user A selected the row 1 and start editing it
2 - At the same time the user B selected the row 1 and save it before the user A
3 - The user A try to save his modifications and get the error from the application
On this context the user A has the version field pointed to 0 also is the user B but when the user B save the registry it now is 1 and when the user A try to save it it will fail because of the check trigger.
The problem with this approch is that you will have to have a before update trigger to every table in your model or at least the one you are concerned with.
Is it possible to search for a value in MySQL and if the value is not found, automatically insert that value?
For example:
This is my table. The id is auto increment, the case id is inserted by me
when I search for a number on my search box. If that number is not inside the table, it will auto insert it into the table.
id| case id
1 | 324
2 | 789
3 | 314
when me search 123 on my search box.that number of 123 is not in my table so that number of 123 will auto insert into my table.
id | case id
1 | 324
2 | 789
3 | 314
4 | 123
Is this possible?
here is my code
mysql_select_db($database_connection_db, $connection_db);
$query_viewAduan = mysql_query("SELECT No_KP, COUNT(*) FROM aduan_tidak_hadir WHERE No_KP LIKE '%".$no_kp."%' GROUP BY No_KP;");
while ($row = mysql_fetch_array($query_viewAduan))
{
if (!$row['COUNT(*)'])
{
echo 'satu';
}
else if ($row['COUNT(*)'] == '1')
{
echo 'dua';
}
else if ($row['COUNT(*)'] == '2')
{
echo 'tiga';
}
}
Yes this is possible but not with simple sql statements. This has to be done with an extension of sql called PLSQL. If you know PLSQL then continue reading or otherwise stop right here and learn it befor you read this full answer.
Here's the code for you question:
declare numb my_table.case_id%type
begin
select case_id into numb from my_table where numb=case_id;
exception
when no_data_found then
insert into my_table values(/*you said the id auto_increments so I'm leaving this one out*/,numb);
end;
Since I didn't know the name of your table I just called it my_table. Try this and it should work.
A quick note before I move to an answer. Any time you ask a question, whether it be on the web or to another person, you should have tried something already. This is true for any subject. If you want to drive your car, you must first try to start it. It might be obvious that you tried that, but in a more technical subject, we need to know that you in fact did try something, and that what you tried did not work. A lot of times these questions get asked because the users have in fact tried nothing at all. It is important that you try something, because that is your real learning experience. Just following a set of instructions given to you here will not help you in the future.
Now on to helping you figure out your problem. You have flagged your question as a PHP and MySQL question, which suggests that you don't need to do it in a single MySQL query. I won't give you the code to do it, but I will point you in a direction for some sample code.
Let's break down your question into the actual steps:
Search value in table
This is the first part of your question. This is a basic select statement. I'm sure you can figure it out. If not, google for MySQL select.
if the value is not found
This is the second part of your question that essentially defines what you must do in PHP. You need to check if the value was not found. You need to look at the results of select statement from your search value in table step and determine whether or not it was empty or contained results.
auto insert
At this step, based on your last step if the value is not found, we can determine whether or not we should insert the value. For instructions on how to do an insert, Google mysql insert.