I have a mysql table column (runs) which holds an integer, I want to increment it by another dynamic value (1,2,3,4,5) using an update query on click of a button. How should I do that?
(Without retrieving the original value from that table column, is there any direct way to increment the value, not like AUTO_INCREMENT since it does it using a static value)
I've checked the documentation on MySql here and it seems you can do it with an update query like this:
UPDATE t1 SET col1 = col1 + 1;
where you can change 1 to any numeric value as long as col1 is also numeric.
MySql will get the initial value of col1 and add your number to it.
Even if MySql can do this, I'm guessing this also has an impact on speed, it might be faster then 2 queries, but probably needs testing to determin the differences.
When confronted with software speeds issues saving a select query for only one value it's not the key modification that you can do to optimize your app. As Digvijay Yadav suggested, you should also check other solutions, and other optimizations on to make your app faster.
another example on that page that also shows that what your are trying to do can work is :
UPDATE t SET id = id + 1 ORDER BY id DESC;
please try it and let me know if it doesn't work.
If DB interaction is the main problem then in this case I would suggest not to read/write to DB on every user click. Instead you should retrieve the value once and store them in a DS (may be an array or list). On every click you perform operations on this list and after sometime you update the DB with updated values.
Also, if you are creating and destroying the DB connections on every read/write operation then I would not suggest that. A better solution IMO is to create a DB connection when your webapp starts up and store the connection object in the ServletContext as an attribute as you are using servlets and JSPs.
Further if your web app is too big and has thousand of users then there are several caching techniques for improving the performance of DB.
Related
I have around 2000 rows in my database at the moment, the structure previously was varchar(200). I have since changed the structure to varbinary.
Now when I insert data into my table I use
AES_ENCRYPT('Obama', 'sadhjksauejs') (just an example)
anyway, I want to use AES_ENCRYPT on all the data that is currently in the database, so get the data, encrypt it and put it back into the database, without losing the original data.
what is the best way to do AES_ENCRYPT on all the data that is currently there?
First you have to create new field in your table encryptedText.
UPDATE table SET encryptedText = AES_ENCRYPT(textField,'sadhjksauejs');
There are a couple of things you need to look out for here ...
Yes, VARBINARY is the appropriate data type, however, AES_ENCRYPT is a block-based and will pad your plaintext to the necessary length so your ciphertext will likely be longer than the original. The documentation gives this for calculating the correct column size:
16 * (trunc(string_length / 16) + 1)
You should check that the column is still going to be long enough to hold any value you want to store.
Second, as you are already adding new records in encrypted form you need to make sure that your update statement is restricted to only those records that are still in plaintext.
Once you have taken those things into consideration (and assuming some id or created column) your UPDATE statement will look something like this
UPDATE `yr_table` SET `col1` = AES_ENCRYPT(`col1`,'sadhjksauejs'),
`col2` = AES_ENCRYPT(`col2`,'sadhjksauejs')
WHERE `id` > whatever;
(i.e. Not unlike the suggestion by #Sadikhasan)
I have a table in MySQL with a field "Ordering" These are just auto incremented numbers. Now I wonder if there is a query to change the values from the last to the first...
So the entry with ordering 205 should become 1, 204 -> 2 and so on...
It's actually not an auto-increment. The problem is I started adding projects from the current website. From page 1 to page 20, but the first item on page 1 is the latest. The way I added the new projects, the newest is on the last page..
If the ordering field is switched, the new items added will be correctly numbered again and added to the front page. It's just a wrong way I started adding old projects...
Structure
Examples of the content
I can't comment due to limitations, but i really agree with #Abhik Chakraborty.
You don't want to do this. Just use the order by as he suggested.
Example:
SELECT * FROM tableName
ORDER BY columnName DESC;
Just in case you would like to know more about it: http://www.w3schools.com/sql/sql_orderby.asp
Try this as one statement call:
SET #MaxSort := (SELECT MAX(Ordering) FROM MyTable);
UPDATE MyTable t set t.Ordering = (#MaxSort + 1 - t.Ordering);
This will work if field doesn't have unique constraint.
But this field, should not be an auto_increment field at first place. Auto increment is increasing NOT decreasing counter. Except if you just try to fix existing data and the new records will be increasing.
Additional explanation
Thanks for pointing it out. Multiple query inside single query statement doesn't work with php_mysqli and it is not used because of potential MySQL injection attack if servers allows it. Maybe you can setup PHPMyAdmin to use PHP PDO.
I can use multiple queries, but I'm using PHP PDO or DBeaver database manager.
I can only suggest to supply MaxSort manually (since this is one time job anyway):
UPDATE
MyTable t
set
t.Ordering = 254 - t.Ordering + 1;
The Problem
I have a VB6 application which uses Microsoft Access as the back end. The app is used in a multi-user environment. Recently, with no changes made to the application, we're seeing that in one of the tables of the database some records aren't being saved, while other records are saved twice, or some time even 3 times.
The Details
It's a VB6 application with Access 2002 as the back end. The app is installed in a computer running Windows 2008 Server. Multiple users on the network have a shortcut to the application on their computers and they run the application at once, accessing the same database but different records.
The application uses the following logic to save a record to the database:
1
If objectID > 0
' existing record
sql = "UPDATE myTable SET a=..., b=..., etc WHERE Id = objectID"
cn.Execute sql
Else
' new object; create new record
nextID = "SELECT Max(id) + 1 FROM myTable"
sql = "INSERT INTO myTable (a,b,c) VALUES (...)"
cn.Execute sql
objectID = nextID
End If
Exit Function
Err_Handler:
' handle the case where two people get the same ID
If timeNotExpired Then
' Try saving again;
Resume 1
Else
' Could not save; display error
End If
Thus when saving a record, if it exists it's UPDATED, otherwise it's INSERTED. The primary key field is obtained by calling Max(ID) + 1. With this setup, it's possible that Max(ID) + 1 may return the same ID for two users that are saving to the same table at the very same time. If this happens, the application goes back to where that label 1 is, and Max(ID) + 1 is called again until there is no conflict or until the save operation times out. Simple.
Last week, out of the blue, with no changes made to the application, it just started happening that (1) records in one table would randomly not save, or (2) a given record in that same table would show up in the database twice or even 3 times. In other words, a record in that table would appear in the database more than once.
It doesn't happen all the time but it happens a good 5-10 times a day. Please note that there are at least 5 people using the application throughout the day, mostly for data entry purposes. If a given record isn't save properly, the data gets out of sync and the application displays a message. At that point, if I check the database, I'll see that a record is either missing or duplicate. And usually, when it happens to one person, it will happen to other users who are also entering data. At the same time.
Edit
Let me add a bit more context... I have two tables (among others) that represent a parent/child relationship as in a customer/order scenario. A parent is required to have at least one child and the application has checks in place to ensure that a parent is not saved to the database unless the user has added at least one child for it. A user may not proceed to do anything with the application if he adds a parent without any children. The database code that saves parents (and children) has an if statement that reads something along the lines of "If parentHasNoChildren Exit Function". There's absolutely no way, absolutely no way, abso...lutely no... way... for the application to run code which would result in a parent that is saved to the database with no children.
But alas, starting last week, with absolutely no modifications to the application, we're seeing parents with no children left and right in the database. The problem occurs about 10 times per day, per user.
I have since modified the application so that it alerts the user when it finds a parent that has no children. If so, the program instructs them to delete the record and add it again, after which everything is fine.
Now, the fact that parents are reaching the database without children can only mean that (1) the application attempted to save the child, (2) Access returned no errors and behaved like everything was ok and (3) the application "thought everything was peachy" when in fact the child was not saved at all. And I know Access returned no error because the application logs every error that occurs during save operations. I checked the logs and there are no errors about children not being saved.
Edit 2: (I believe I found the problem!)
Upon inspection of the database, I just discovered that the primary key in the child table is gone. That is, the field that is supposed to be set as the primary key is there, but it isn't set as the primary key. I have no idea how this happened. The database design hasn't been touched so I'm assuming MS Access woke up one day and said "hmm, I wonder what would happen if I deleted the primary key from this table..."
In any event, I believe this is definitely the cause of my problem. The primary key was set up to prevent duplicate entries. With the key gone, it's possible to save two child records with the same ID. Since my code uses Max(ID) +1 to generate the ID for new child records, it's possible that Max (ID) +1 would return the same ID for multiple users that attempt to save a child record at the very same time. This would not be a issue in the past because Access would produce an error regarding the duplicate IDs and the application would detect the error and simply execute Max(ID) +1 again. But with no primary key, two child records would be saved with the same ID. And later, if any of the users made a change to one of those records, then both records would be updated and all fields for both (including the foreign key for the parent, parentID) would be set to identical values. This would then result in one parent having no children, and another parent having duplicate children. My goodness what a mess!!
I just tried adding the primary key to the table and I can't because there are duplicate records which I must find and delete. I'll post the final result as an answer after I'm able to add the primary key back. Thanks for all your help.
Now one last note: the table in question is the largest in the database, containing well over 3.5 million records. The table has 22 fields, 20 of which are long integers, one is a text field with a field size of 100. The other a Boolean field.
What I've Done
Since the application hasn't changed, I immediately assumed (and continue to assume) that the problem is corruption in the MS Access Database. I have done the following:
Compact the database every day
Create a fresh database and import the tables from the old database to the new one.
Create a new database and import only the definition of the tables, one at a time, then use Append Queries to get the data over to the new database.
Made sure I got latest service packs for Office
Made sure connection objects and recordsets are properly closed/disposed of
Contemplated suicide
Read and implemented suggestions detailed by a Microsoft article about how to keep a Jet database in top working order.
I'll also go over the application with a fine comb to see if I find anything, though everything points to Access being the culprit
Any Ideas?
Has anyone been in a situation like this before? I myself had a a similar issue with the same database about 10 years ago. Back then, I was getting the "Unrecognizable file format" error which was a clear case of database corruption. I fixed it by creating a new database and importing the tables, but that hasn't helped this time. Any ideas?
I would check the data type of the ID column, and make sure it is large enough. Consider changing it to a counter data type instead of running a domain function (MAX(ID)), or a replicationID if possible. That's where your issue may be happening.
I've set the ID to LONG before, and maintained my own counter in another table. Maybe a table that holds the NextID column, and a VBA function that gets this and updates + 1 for the next guy. Within a transaction this can be more reliable than MAX, which has to contend with locks.
Good luck!
It turns out the issue stemmed from the fact that Microsoft Access dropped the primary keys of two tables on the database. Because I use Max(ID) + 1 to obtain the ID for new records, and there are multiple users creating new records at once, the same ID was sometimes used for more than one record. This caused the issues mentioned above.
To solve the problem, I simply added the keys back after deleting any duplicate entries I found.
I'll also try to stay clear of Max(ID) + 1 for new records as suggested by #DanielG.
If anyone else is unlucky enough to be working with MS Access in a multi-user environment, I suggest following Microsoft's suggestions outlined in the article How to keep a Jet 4.0 database in top working condition.
Thank you all for your help!
I found a weard problem with my MySQL DB.
sometime when I insert new data into it, the way it arranges the data is like a stack, for example
4 (newest)
3
2
1 (oldest)
...
how can I make it arranged like this?
1 (newest)
2
3
4 (oldest)
thanks all.
SELECT *
FROM TABLE
ORDER BY ID
You have to remember that when viewing/selecting data from a table without any ORDER BY specified does not garuantee any specific order.
The way you are view the data (unordered) can be due to any one of a lot of factos (the database engine, schema, page storage, page fragmentation, indexes, primary keys, or simply execution plan optimization).
The SQL standards specifically states that tables do not have a "natural" order. Therefore, the database engine is free to return a request without an ORDER BY in any order it wants to. The order may change from one request to another because most engines choose to return the data in whatever order they can get it to you the most rapidly.
It follows, therefore, that if you want the data out in a particular order you must include a column in your table whose job is to proxy for the order in which you added records to the table. Two common ways of doing this are using an autoincrement field which will be in numerical order from oldest to newest record, and a TIMESTAMP column which does just what it says. Once you have such a column you can use ORDER BY ColumnName when searching to get an ordered result set.
My question is how to get the next id using NHibernate in a mysql db for an auto-increment ID column ?
Thanks,
Based on the further description you give (as an answer?) below it seems to me that you are indeed looking for the NHibernate feature to automatically read back IDs generated by the database: identity
This will tell NHibernate the ID's value is determined by the database upon insert, it will not send a value as part of its INSERT statement and it will read back the value of the ID column after it has performed the insert. But you do have to tell the database (in the table definition) that it should auto-generate a value for the ID column for each record inserted...
You're going to create a race condition if you do this. To answer your question, I don't think there is a specific way for Hibernate to give you this information since no application can give you this information. By getting the "next id", by the time it returns that data to you, it might be invalid already. The easiest way I can think of is to get the last_insert_id() and add +1 to it.
Why don't you post more information about you're trying to accomplish and we can find a better solution for you?
Provided that you are the only writer to your database then you could get your application to maintain the sequence number for you and allocate the next number yourself.
If you want to do this then you'll want to ensure that your application counter is thread safe.
You'll also want a way to get the last written sequence number when restarting you application.