I have a MySQL script which is executed automatically under certain conditions. That script executes an ALTER TABLE command, because that column is needed in the database, but it may or may not have it...
Is it possible to make MySQL 4 execute the ALTER TABLE statement if the column doesn't exist or ignore the duplicate column error for this single command and allow the script execution to continue?
ALTER [IGNORE] TABLE will only ignore certain errors, like duplicate key errors when adding a new UNIQUE index, or SQL mode errors.
http://dev.mysql.com/doc/refman/4.1/en/alter-table.html
More details about the "script" you are using would help to answer the question. In python for example, the error would raise an exception which could then be caught and dealt with or ignored.
[EDIT] From the comment below, seems like you're looking for the mysql -f command line option.
You can first check the table schema before you attempt an addition of the column? However , I strongly suspect the design where you need to add columns on the fly. Something is not quite right. Can you explain the requirement in a little detail. I'm sure there are other cleaner way around this.
Related
Hi I have Amazon rds which i can connect to using the mysql prompt
I want to empty a table using the prompt command line
What's the best way to do the above? Thanks!
You can use the standard truncate command to empty the required tables. If you want to truncate multiple tables follow this question.
Try
DELETE FROM `table_name`;
Notice the missing where clause, this will delete all rows.
Data can't be deleted that's connected by a constraint.
What you need is code that first removes constraints, then deletes the
data, and finally restores the constraints:
See more at: http://www.devx.com/dbzone/Article/40967#sthash.NUmxsFr3.dpuf
Moreover, use DELETE command as you can ROLLBCK the operation. While using truncate, operation cannot be rolled back and no triggers will be fired
I have a database I'm creating and I made a 1 to 1 connection with another table in Mysql, below is a screen shot. My question is can I drop the extra column (assembly factory_id) that was created when I made the connection? I only want the single (factory_id) will this mess up the connection that I made? Should i drop the (factory_id) and let the connection stay?
I'm a noob, thanks!
I am assuming that your comment "but should i drop the table?" really meant to say "but should i drop the column?".
Short answer: if it is safe, you should delete the column - there's no reason to keep it cluttering up the database and the minds of future developers.
Long answer: how to determine if it's safe: If 1) the value in factory_id IS and ALWAYS WILL BE identical to assembly factory_id, eg, they are a duplicate value of each other, and 2) no other tables or program code refer to assembly factory_id, you can safely delete assembly factory_id.
However, if there's any chance that they ever mean different things (not just the sample of 20 or so rows), you can't delete it. See fiddle: http://sqlfiddle.com/#!9/0bf17/1
If they are always the same, but parts of the database or the code refer to assembly factory_id, you can refactor those database or code parts to refer to factory_id instead and THEN delete assembly factory_id.
When doing something like this, you should make tests to verify that the state of queries and programs after the change is the same as the state before the change.
You can drop the extra column by using the Alter statement.
ALTER TABLE table_name DROP COLUMN factory_id;
You can also refer to http://docs.oracle.com/cd/E18283_01/server.112/e17118/statements_3001.htm#i2103683
(Drop column clause in particular)
Edit:
As far as the connection is concerned, the Alter statement dumps to a temporary table and then rebuilds without losing any connection. Please refer to the section Storage, Performance, and Concurrency Considerations in this document
Once a record is entered in a particular table, I think I don't ever want it to be deleted. The records are there to keep track of things for historical purposes. I'm using MySQL, InnoDB. Is there any way I can protect that table from accidental deletes by the application layer? If so, is this a good approach?
If you can set the permission for your user(s), don't give the delete permission. There're situations where this practice is a "must be" like the tables for statistics purpose. Thus, if your table is used to achieve one of this goal, it's a good approach.
I use a trigger that detects the deletion and does some illegal stuff so the whole operation fails. For example like this:
CREATE TRIGGER protect_delete before delete ON protected_table
FOR EACH ROW UPDATE non_existing_table SET non_existing_column=1;
So when someone will attempt a delete operation - the whole statement will fail. You also might use better names for non_existing_column and non_existing_table.
E.g it is possible to obtain an error message like this:
ERROR 1146 (42S02): Table 'database.delete_restricted_on_tableX'
doesn't exist
EDIT: also it is possible to create even better fail messages, please check here http://www.brokenbuild.com/blog/2006/08/15/mysql-triggers-how-do-you-abort-an-insert-update-or-delete-with-a-trigger/
One other option is switch to the ARCHIVE engine for historical tables.
This will prevent any DELETE or UPDATE actions on the table, and compress the data. One (major) downside to this approach is that you cannot index the columns on the table.
I think you should implement this logic in your application layer and insert a column where you put a no-delete flag.
Another idea would be to exclude the delete access for the db user
You may want to write a trigger that detects the deletion, then reinserts the record, but there may be some issues with that, so you can also just add a foreign key constraint that will prevent the deletion.
For some discussions on this you can look at: http://rpbouman.blogspot.com/2011/10/mysql-hacks-preventing-deletion-of.html.
I am trying to restore a DB using an SQL script, but things foreign key constraints get in the way
I am taking a MySQL DB and bringing it over to PostgreSQL.
Since the MySQL create table syntax ended up being quite different, I took another PostgreSQL DB with the same schema, but different data and restored the schema only, from that.
In other words, I now have a database with tables, constraints, sequences and all that shnaz but no data inside.
So, it's is time to restore data.
I take a backup of the MySQL DB with phpMyAdmin (data only) as an SQL script (pgAdmin does not seem to accept zip or gzip files for some reason) and run the SQL script.
Now, this is where the problems start to happen, it's only natural, I am going from MySQL to PostgreSQL, so syntax errors are bound to happen.
But, there are other non syntax related problems to, like this one:
ERROR: insert or update on table "_account" violates foreign key constraint "fk_1_account"
DETAIL: Key (accountid)=(2) is not present in table "_entity".
So, yeah, basically, a foreign constraint exists, the query is trying to insert data into the _account table, but the corresponding data has not been inserted into the _entity table yet.
How do I get around that? Is there a way to make pgAdmin3/PostgreSQL disable ALL OF the constraints, insert the data, and then re-enable the constraints?
A syntax related error I encountered, was this one:
INSERT INTO _accounttype_seq (id) VALUES (11);
The PostgreSQL equivalent of that statement (if I am correct) is
ALTER SEQUENCE _accounttype_seq INCREMENT BY 11;
But, it's a bit of a pain to run through the whole script and change all 200+ Sequence insert statements. So, I am being lazy here, but is there an easier way to deal with the sequences as well?
Or, do you guys have any suggestions for a different set of tools to make this easier?
Thanks for your time, have a good day.
Do not try to get around the foreign key constraints. That is the way to make sure the data is bad.
First look at the constraints and make sure you are inserting to the tables in the correct order. If _entity is parent of "_account, then it should be populated first.
Next you need to have the script move any failing records to an exception table. Then you can look at them and see what the data integrity issues is and if you need to throw the records away permanently or try to figure out what the missing parent value should be. If it is critical data such as orders where the customer no longer exists (possible in any system that didn't have correct fks to begin with) and you must keep the record and cannot determine what the parent value should have been, you can create an 'Unknown" record in the customer table and assign all bad orders to that customer id.
And manually changing the alter sequences shouldn't take long even if it is boring. There wil be plently of other things you need to handle manually in a conversion of this type.
I would try to find a data import tool for PostgreSQL - I live in SQL server world where I would use SSIS but you need the equivalent of SSIS for the PostgreSQL world.
Aparently the foreign keys weren't actually enforced in MySQL (maybe because of using MyISAM) or the generated SQL just does it in the wrong order.
If it's "only" the wrong order, I see two possible solutions:
edit the generated script and either move all FK definitions to the end of the script
Edit the definition of each FK constraint and set them all to initially deferred. Then run the script as one single transaction with only on commit at the very end.
Edit (because this is too much to be put as a comment)
Using SET CONSTRAINTS ALL DEFERRED will only work if the constraints have been created with the option DEFERRABLE.
To run everything in one single transaction, you have to make sure you have turned autocommit off. Then simply run the INSERTs and at the very end issue a COMMIT. A ; will only commit if you have autocommit on.
If you want to be independent of the autocommit setting, then start your script with [BEGIN][1] and make sure there is only a single COMMIT at the very end.
BEGIN DEFERRABLE
INSERT INTO table_one ... ;
INSERT INTO table_two ... ;
.....
COMMIT;
I am fairly new to using mysql. I have an application that performs some basic querying. I am also trying to run a simple delete statement -
delete from mydb.mytable
This table is a simple 2 column table with not keys or triggers or anything defined. For some reason, the delete is not being performed. If I run the statement from MySql Workbench in the query window, it works fine. From the code, it does nothing. I am not seeing any error messages. I created a user with select, insert, update and delete rights to the schema. I am able to do the insert fine, but the delete does not seem to be working.
Is there a setting for mysql that I am missing that will not allow me to perform the delete?
Thanks for any thoughts.
Fist of all, check if
you are connected to the right database ;
you are using transaction and forgetting 'commit' ;
the user you use have enough permissions to delete from the table .
As a side notice, if you want to delete all records, you should use truncate instead of delete
Are you using transactions? My first guess is that your code might be issuing a BEGIN TRANSACTION without a COMMIT.
We would have to see some of your code to answer the question.
My guess is that you are not calling commit from your code. You can configure MySQL to auto-commit your queries, but this is usually not what you want.