I've recently been given the task of maintaining a sports team's website and have encountered a problem which I cannot find the answer.
It uses Nucleus CMS which is fine and I'm used to it, unfortunately, the domain name has changed and all links and files within the site stored in the mysql database are now out of date and not the correct one.
I am able to manually alter each item using the admin panel of the CMS, but with several thousand posts, that task is daunting.
Is there a way I can do a "replace" domain1.com to domain2.com in the item table in one process through the mysql database?
Forgive me if I'm not using the correct terminology.
Try this:
UPDATE tbl SET domain_name = 'domain2.com' WHERE domain_name = 'domain1.com';
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 have an old website and a new website... the old website had 4500 orders placed on it, tracked by a table with a primary key for the order id.
When the new website was launched, it was launched before migrating old orders into it. To accomplish this, the auto_increment value on the new orders table was set to 5000 so any new order placed would not collide with an old id.
This allows orders to continue being placed on the new website, all is well...
Now I'd like to run my import script to bring in the old orders into the new website.
Is it possible to temporarily lower the auto_increment value on the new orders table to my desired order id?
Disclaimer: This is a migration from a Drupal 5 Ubercart based site, to a Drupal 7 Commerce based site, so I do not (easily) have control over the complex queries involved in assembling the new orders, and cannot simply (AFAIK) supply an order id when assembling an order, because the system always refers to the next available primary key value in the table when creating an order. I can easily take the site offline to run the script, so nothing gets out of sync.
For importing the "old" orders you don't need to rely on the autoincrement id-- they already have ids, and you probably want to keep those!
Modify your import script to insert the complete old records into the new table, id and all! As long as the ids don't collide, it shouldn't be a problem.
You can always run ALTER TABLE table_name AUTO_INCREMENT = 1; (or whatever number you want).
The question is: do you WANT to?
If you have any records already in the database, it's probably best to insure the next auto increment value is larger than the maximum already in your database.
I have been using a query to add editable profiles based on an original user table.
The original registration table has the fields, id - name - surname - username - password - email - confirmation
The profile has several more customizable fields, but the ones I am inserting into the profiles table from the users table is, id - name - email.
INSERT IGNORE INTO profile(cid,display_name,display_email)
SELECT id,name,email FROM users
This used to work for a couple of years now, but recently I noticed that the profiles table has topped inserting profiles when users register. When I run the query in phpmyadmin it just says 0 rows inserted.
Can someone please help me to figure out why this is happening? Updates to MySQL that I missed or something :(
Solved the problem.
It would seem my host for some reason, during upgrades changed my table field id on the profiles table to a defined value of 0.
I edited the structured and set it back to auto_increment. Which was the reason the query stopped adding the new values.
Thank you to everyone that questioned me, it pointed me towards the problem and helped to resolve this issue.
I'm working on a RoR projects. I'm migrating a user table. Because the new dbase has a different set up and I want to seperate the login stuff from the personal/settings stuff I'm not importing the dbase; I migrate all attribute separately. I want to keep the old user id's. When I use user=User.new I can do user.id = migratee.user_id and I keep the same user_id. Unfortunately in the old table different users where registered with the same email address (don't ask why). Off course I don't want that so what I do in stead of user=User.new is user=User.find_or_create_by_email(migratee.email). This is going to lead to some problems, I know, since users with same email address will be overwritten. This is a problem I 'll deal with seperately. My problem is that when I do user.id = migratee.user_id after user=User.find_or_create_by_email(migratee.email) the old ID isn't migrated but a new auto-incrementing id is assigned. Anybody know how to avoid that?
Regards,
Rutger
I don't know how your query looks like. If you're doing an INSERT SELECT you can add a HAVING to filter existing email adresses. Otherwise you could do a GROUP BY email do only get one email.
If its a once off I would probably just turn off the auto_increment in your new mysql table id column until you have finished your migrations and then turn it back on or/ create another column called udid in the new database table (and then rename and delete the id col). Probably nicer ways to do it, but its fast and easy.