I'm trying to set some options to be active/inactive and I'm using a column called active which will either be 1 or 0.
Is there a better way to make all 0 except one which will equal 1 and be determined by form submission besides running two queries?
Right now I have this:
mysql_query("UPDATE customizer SET active='1' WHERE text_color='{$text_color}'");
But eventually they'll all be 1.
UPDATE `customizer` SET `active` = (`text_color` = '{$text_color}')
Performs a comparison, which returns 1 if true, 0 if false, and puts that result in the active column.
Consider changing your database structure, though. It would be much better for consistency to have active_colour saved with your user data or something.
Related
I currently have a query where I delete a record on call, however after other consideration I would rather just update the record on a is_deleted basis so that I can always have a record of whats been in the system, and or undelete that record at a later time.
My current query:
$delete=mysql_query("DELETE FROM pin_status_types WHERE pinstatus_id='$delete'");
Instead of deleteing the record, i would rather change a value in a column from 0 to 1.
0 = false (not deleted)
1 = true (is deleted)
Correct me if I wrong, but wouldnt I do (Note; I added table. and column. to for note purposes.) something like below to achieve what I am after?
$delete=mysql_query("UPDATE table.pin_status_types SET column.is_deleted = 1 WHERE pinstatus_id='$delete'");
Update your query to:
mysql_query("UPDATE pin_status_types SET is_deleted = 1, date_deleted = NOW() WHERE pinstatus_id = '{$delete}'"
Also, as David suggested in comments, you might want to add timestamp for when a record was deleted for audit purposed.
Update: changed query to cover the issue raised in your comment. Make the date_deleted column default to 0 instead on CURRENT_TIMESTAMP. See this question for more details on that.
Please learn about and use PDO going forward
Alright so I'm testing with some SQLi on localhost and I stumbled upon a really wierd "error" that I've never seen before.
I'm trying to get information from a database called "game" with a table called "users" (15 columns)
Here's the first part of the table:
http://i.gyazo.com/7e6c81ef2b235a778dec1fd343e8c3bf.png
The hashes are "test" and "test1".
So I'll get the first hash with
'+union+select+concat(password),2,3,4,5,6,7,8,9,10,11,12,13,14,15+from+game.users limit 0,1--+-
a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
Let's continue, we move to the other row with
'+union+select+concat(password),2,3,4,5,6,7,8,9,10,11,12,13,14,15+from+game.users limit 1,1--+-
and it gets b444ac06613fc8d63795be9ad0beaf55011936ac
So everything's working correctly, HOWEVER if I would change the users hashes so they have the same as
http://i.gyazo.com/df1154a02cae5e5bbde04d7e47256899.png
then our second injection doesn't work anymore
'+union+select+concat(password),2,3,4,5,6,7,8,9,10,11,12,13,14,15+from+game.users limit 1,1--+-
it returns nothing how and why is this possible and most importantly how would I fix this? I only want it to get 1 result at a time, not more.
I'm testing on a Windows 7 machine using Wamp.
The query being executed is
SELECT *
FROM users
WHERE id='-1'
UNION
SELECT concat(password),2,3,4,5,6,7,8,9,10,11,12,13,14,15
from game.users
limit 1,1
From MySQL Manual:
The default behavior for UNION is that duplicate rows are removed from the result.
http://dev.mysql.com/doc/refman/5.6/en/union.html
If you changed the password field to be the same for those two rows, then you will also two identical rows in the second part of the UNION that will be de-duped.
What you are doing however makes basically no sense. Why are you using CONCAT, but then not concatenating anything?
Also, why would you use an offset of 1 if you only wanted one row? I would think your offset should be 0 (i.e. LIMIT 0, 1).
Finally, why are you even doing this union to begin with?
What is probably happening is there is no record meeting the criteria of user id = -1 then because of the de-dupe, there is only one row returned in the pre-limit result set, which you are skipping over by specifying an offset of 1. Thus you get an empty result set.
Before when the password fields were different, you had two different rows in the pre-limit result set, thus there was a row at offset 1.
I want to add 1 to the value of the previous row for hit_count, but I'm afraid doing it may not be safe if multiple queries are being run quickly (i.e. the page is being loaded several times a second - this is for a web-app I'm making, and so I want to make sure any amount of page loads is supported well).
Here's what I had in mind:
$result = mysql_query("SELECT * FROM rotation");
$fetch = mysql_fetch_assoc($result);
$update_hit = $fetch['hit_counter']+1;
$query = "INSERT INTO rotation (hit_counter, rotation_name) VALUES ('$update_hit', '$rotation_name')";
$result = mysql_query($query);
I thought about setting the hit_counter column to a UNIQUE KEY, but I don't know what else I'd do after that.
I would use AUTO_INCREMENT but the problem is, I need the actual hit_counter value within the rest of the script.
Any ideas, comments, advice would be greatly appreciated!
Edit: I used hit_count and hit_counter, was a typo. Updated to avoid any confusion.
You can use the DUPLICATE KEY functionality when you make name + counter a unique value:
INSERT INTO rotation SET hit_counter = 1, rotation_name= 'name'
ON DUPLICATE KEY UPDATE hit_counter = hit_counter + 1
Performance wise (and if your requirements allow it) I advice pushing updates in bulk (per 100 hits) using a caching mechanism like f.e. memcached.
You could use AUTO_INCREMENT, if you need the inserted id within the rest script, you can use mysql_insert_id to get it.
Im working with a mysql database via php.
I have a table with some values that are = NULL
I select these values in php:
$opponentInv = db_execute("Select * from inventoryon where playerid = ".$defendid.";");
$opponentInv = mysql_fetch_assoc($opponentInv);
Then i insert the values into a another table:
db_execute("INSERT INTO `inventoryCombat` (`attackid` ,`defendid` ,`money` ,`item1` ,`item2` ,`item3`, `item4` ,`item5` ,`item6`, `time`)VALUES ('".$attackid."', '".$defendid."', '".$opponentInv["money"]."', '".$opponentInv["item1"]."', '".$opponentInv["item2"]."', '".$opponentInv["item3"]."', '".$opponentInv["item4"]."', '".$opponentInv["item5"]."', '".$opponentInv["item6"]."', '".$time."');");
The issue is that when i insert the values into the second table, they are always coming out as 0. The values in the inventoryCombat table are 0 when they should be NULL (what they are in the inventoryon table). The table is set to accept NULL as values.
Firstly I'd strongly recommend that you use prepared statements instead of building a literal SQL string. Not only is this a better practice and helps you to write a more secure application, it also handles NULL values correctly without requiring any extra work.
If you want to continue using the method you are currently using then you will need to explicitly check for undefined values and insert the string 'NULL' into your SQL. In other words, you need to do this:
INSERT INTO inventoryCombat (item1) VALUES (NULL);
Instead of what you are currently doing:
INSERT INTO inventoryCombat (item1) VALUES ('');
If it still doesn't work, double-check that the field you are trying to insert NULL into is set to allow NULL values. You can use SHOW CREATE TABLE inventoryCombat to do this.
I'd also recommend normalizing your database. Having columns called item1, item2, item3 etc. is a sign of a bad design. Your current design will, for example, make it more complicated to perform what should be simple queries such as 'How many players possess item X?' or 'Add item X to player P unless she is already holding 6 items'.
Values in array $opponentInv is may be set to 0.
Like $opponentInv["money"] = 0; that is why it is being saved as 0 in inventoryCombat table.
Try to set value of $opponentInv["money"] as NULL in your coding, instead if 0 or ''.
e.g
$opponentInv["money"] = ($opponentInv["money"] == 0 || $opponentInv["money"] == '')?NULL:$opponentInv["money"];
This seems to be that you're storing string(varchar, text) data into number field whose default value is set to 0.
There are 2 more solutions:- Even if it has accepted the values as 0 instead of NULL, this can be updated as NULL like this:- update set =NULL WHERE ;
Also you need to check if the column is set to be NULLABLE, then only above SQL will work, else it will again set the column with 0 value and will be of no use.
Further you can do the same via your SQL Manager interface. I am not sure about all but EMS postgresql manager works this with command CTRL+SHIFT+0 and few others like sql navicat for mysql and oracle use CTRL+0 [Please check your sql manager programs on your own]. Cheers!
I am having a wee problem, and I am sure there is a more convenient/simpler way to achieve the solution, but all searches are throw in up a blanks at the moment !
I have a mysql db that is regularly updated by php page [ via a cron job ] this adds or deletes entries as appropriate.
My issue is that I also need to check if any details [ie the phone number or similar] for the entry have changed, but doing this at every call is not possible [ not only does is seem to me to be overkill, but I am restricted by a 3rd party api call limit] Plus this is not critical info.
So I was thinking it might be best to just check one entry per page call, and iterate through the rows/entires with each successive page call.
What would be the best way of doing this, ie keeping track of which entry/row in the table that the should be checked next?
I have 2 ideas of how to implement this:
1 ) The id of current row could be save to a file on the server [ surely not the best way]
2) an extra boolean field [check] is add to the table, set to True on the first entry and false to all other.
Then on each page call it;
finds 'where check = TRUE'
runs the update check on this row,
'set check = FALSE'
'set [the next row] check = TRUE'
Si this the best way to do this, or does anyone have any better sugestion ?
thanks in advance !
.k
PS sorry about the title
Not sure if this is a good solution, but if I have to make nightly massive updates, I'll write the updates to a new blank table, then do a SQL select to join the tables and tell me where they are different, then do another SQL UPDATE like
UPDATE table, temptable
SET table.col1=temptable.col1, table.col2=temptable.col2 ......
WHERE table.id = temptable.id;
You can store the timestamp that a row is updated implicitly using ON UPDATE CURRENT_TIMESTAMP [http://dev.mysql.com/doc/refman/5.0/en/timestamp.html] or explicitly in your update SQL. Then all you need to do is select the row(s) with the lowest timestamp (using ORDER BY and LIMIT) and you have the next row to process. So long as you ensure that the timestamp is updated each time.
e.g. Say you used the field last_polled_on TIMESTAMP to store the time you polled a row.
Your insert looks like:
INSERT INTO table (..., last_polled_on) VALUES (..., NOW());
Your update looks like:
UPDATE table SET ..., last_polled_on = NOW() WHERE ...;
And your select for the next row to poll looks like:
SELECT ... FROM table ORDER BY last_polled_on LIMIT 1;