MYSQL if table exit run something otherwise run another thing [duplicate] - mysql

I'm stumped, I don't know how to go about doing this.
Basically I just want to create a table, but if it exists it needs to be dropped and re-created, not truncated, but if it doesn't exist just create it.
Would anyone be able to help?

Just put DROP TABLE IF EXISTS `tablename`; before your CREATE TABLE statement.
That statement drops the table if it exists but will not throw an error if it does not.

Just use DROP TABLE IF EXISTS:
DROP TABLE IF EXISTS `foo`;
CREATE TABLE `foo` ( ... );
Try searching the MySQL documentation first if you have any other problems.

Well... Huh. For years nobody mentioned one subtle thing.
Despite DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... ); seems reasonable, it leads to a situation when old table is already gone and new one has not been yet created: some client may try to access subject table right at this moment.
The better way is to create brand new table and swap it with an old one (table contents are lost):
CREATE TABLE `bla__new` (id int); /* if not ok: terminate, report error */
RENAME TABLE `bla__new` to `bla`; /* if ok: terminate, report success */
RENAME TABLE `bla` to `bla__old`, `bla__new` to `bla`;
DROP TABLE IF EXISTS `bla__old`;
You should check the result of CREATE ... and do not continue in
case of error, because failure means that other thread didn't finish
the same script: either because it crashed in the middle or just
didn't finish yet -- it's a good idea to inspect things by yourself.
Then, you should check the result of first RENAME ... and do not
continue in case of success: whole operation is successfully
completed; even more, running next RENAME ... can (and will) be
unsafe if another thread has already started same sequence (it's
better to cover this case than not to cover, see locking note below).
Second RENAME ... atomically replaces table definition, refer to
MySQL manual
for details.
At last, DROP ... just cleans up the old table,
obviously.
Wrapping all statements with something like SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade'); allows to just invoke all statements sequentially without error checking, but I don't think it's a good idea: complexity increases and locking functions in MySQL aren't safe for statement-based replication.
If the table data should survive table definition upgrade... For general case it's far more complex story about comparing table definitions to find out differences and produce proper ALTER ... statement, which is not always possible automatically, e.g. when columns are renamed.
Side note 1:
You can deal with views using the same approach, in this case CREATE/DROP TABLE merely transforms to CREATE/DROP VIEW while RENAME TABLE remains unchanged. In fact you can even turn table into view and vice versa.
CREATE VIEW `foo__new` as ...; /* if not ok: terminate, report error */
RENAME TABLE `foo__new` to `foo`; /* if ok: terminate, report success */
RENAME TABLE `foo` to `foo__old`, `foo__new` to `foo`;
DROP VIEW IF EXISTS `foo__old`;
Side note 2:
MariaDB users should be happy with CREATE OR REPLACE TABLE/VIEW, which already cares about subject problem and it's fine points.

I needed to drop a table and re-create with a data from a view.
I was creating a table out of a view and this is what I did:
DROP TABLE <table_name>;
CREATE TABLE <table_name> AS SELECT * FROM <view>;
The above worked for me using MySQL MariaDb.

Related

MySQL workbench creates forward script dropping of tables in wrong sequence, violating foreign key constraints

The subject line actually says it all.
I have a schema, now when I create a forward script it generates the tables and I added the option to do a DROP TABLE IF EXISTS in front of every create table SQL. The creation part is fine. But if you run the script twice you notice that the drop sequence is the wrong order.
I think the concept of aligning the drop sequence with the create sequence is just conceptually arguable. I think you might be able to create schemas where you won't be able to create the tables in the same sequence as you would drop them.
Anyhow, I can't find any option to change the order or do anything. Has anyone an idea how I can change the drop sequence manually ?
I am sorry to be not able to share any SQL, however I think the problem is really generic. And you want solve it by writing different SQL. So it should be possible to answer based on discussion, not on code.
That's Workbench version 6.3.6. So almost latest. (Currently 6.3.7)
You must drop table in reverse order of creating them.
When creating:
Create table a...;
Create table b...;
Create table c...;
When dropping:
Drop table c;
Drop table b;
Drop table a;

If table exists drop table then create it, if it does not exist just create it

I'm stumped, I don't know how to go about doing this.
Basically I just want to create a table, but if it exists it needs to be dropped and re-created, not truncated, but if it doesn't exist just create it.
Would anyone be able to help?
Just put DROP TABLE IF EXISTS `tablename`; before your CREATE TABLE statement.
That statement drops the table if it exists but will not throw an error if it does not.
Just use DROP TABLE IF EXISTS:
DROP TABLE IF EXISTS `foo`;
CREATE TABLE `foo` ( ... );
Try searching the MySQL documentation first if you have any other problems.
Well... Huh. For years nobody mentioned one subtle thing.
Despite DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... ); seems reasonable, it leads to a situation when old table is already gone and new one has not been yet created: some client may try to access subject table right at this moment.
The better way is to create brand new table and swap it with an old one (table contents are lost):
CREATE TABLE `bla__new` (id int); /* if not ok: terminate, report error */
RENAME TABLE `bla__new` to `bla`; /* if ok: terminate, report success */
RENAME TABLE `bla` to `bla__old`, `bla__new` to `bla`;
DROP TABLE IF EXISTS `bla__old`;
You should check the result of CREATE ... and do not continue in
case of error, because failure means that other thread didn't finish
the same script: either because it crashed in the middle or just
didn't finish yet -- it's a good idea to inspect things by yourself.
Then, you should check the result of first RENAME ... and do not
continue in case of success: whole operation is successfully
completed; even more, running next RENAME ... can (and will) be
unsafe if another thread has already started same sequence (it's
better to cover this case than not to cover, see locking note below).
Second RENAME ... atomically replaces table definition, refer to
MySQL manual
for details.
At last, DROP ... just cleans up the old table,
obviously.
Wrapping all statements with something like SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade'); allows to just invoke all statements sequentially without error checking, but I don't think it's a good idea: complexity increases and locking functions in MySQL aren't safe for statement-based replication.
If the table data should survive table definition upgrade... For general case it's far more complex story about comparing table definitions to find out differences and produce proper ALTER ... statement, which is not always possible automatically, e.g. when columns are renamed.
Side note 1:
You can deal with views using the same approach, in this case CREATE/DROP TABLE merely transforms to CREATE/DROP VIEW while RENAME TABLE remains unchanged. In fact you can even turn table into view and vice versa.
CREATE VIEW `foo__new` as ...; /* if not ok: terminate, report error */
RENAME TABLE `foo__new` to `foo`; /* if ok: terminate, report success */
RENAME TABLE `foo` to `foo__old`, `foo__new` to `foo`;
DROP VIEW IF EXISTS `foo__old`;
Side note 2:
MariaDB users should be happy with CREATE OR REPLACE TABLE/VIEW, which already cares about subject problem and it's fine points.
I needed to drop a table and re-create with a data from a view.
I was creating a table out of a view and this is what I did:
DROP TABLE <table_name>;
CREATE TABLE <table_name> AS SELECT * FROM <view>;
The above worked for me using MySQL MariaDb.

mysql drop table if exists inside procedure

I'm trying to apply a nested set model example with procedures. I've found many of them with this technique and in the process I've found a problem. Every time I call the procedure I get unknown table XXX. When I create the procedure I got no problem at all. The quick example:
CREATE PROCEDURE `sp_getRoleTree` (IN root INT)
READS SQL DATA
BEGIN
DECLARE rows SMALLINT DEFAULT 0;
DROP TABLE IF EXISTS ROLE_TREE;
CREATE TABLE ROLE_TREE (
nodeID INT PRIMARY KEY
) ENGINE=HEAP;
INSERT INTO ROLE_TREE VALUES (root);
SELECT * FROM ROLE_TREE;
DROP TABLE ROLE_TREE;
END;
So my question is, am I doing something wrong here (it's example code), can I disable the warning on the if exists if the code is fine? Is there a special looping inside the procedures that's causing these kind of warnings?
As a work around: try to truncate table instead of re-creating.
Do not use DROP TABLE/CREATE TABLE. Create this table once (or when you need it) and use TRUNCATE TABLE command.
MySQL generates a warning when using DROP TABLE IF EXISTS tbl; when the table does not exist. This can be confusing and perhaps counter intuitive, but it is the expected behavior.
From http://dev.mysql.com/doc/refman/5.5/en/drop-table.html
Use IF EXISTS to prevent an error from occurring for tables that do not exist. A NOTE is generated for each nonexistent table when using IF EXISTS. See Section 13.7.5.41, SHOW WARNINGS Syntax.
IF EXISTS prevents MySQL from throwing an error, which is nice, but it causes a warning if the table does not exist. There is not an option to suppress this warning.

Drop table, then cannot recreate table with the same name

I first drop a table in SQL Server 2008 (after that it shows the message that the command was executed sucessfully).
I then tried to create a table with the same name, and it showed me an error.
After closing the SSMS window and re opening it it tried to create the table with the same name again and it succeeded.
What is going on?
You can't drop and create the same table in the same batch in sql server
see MSDN
Their examples use GO to break up the two commands. Semi colon might work,
Drop Table ...;
Create Table ,,,;
as might
Begin Transaction
Drop Table...
Commit Transaction
Create Table
Or of course splitting it up into two commands, which is what GO does in SQL server manager's query window.
If you do split it up, it might be wise to check whether the table exists before trying to drop it, and that it doesn't before trying to create it.

Could someone help me understand and convert this MySql statement into Postgresql?

so the code I am working on has this statement executed by PHP (note:This is taken from the PostgreSQL log file so it doesn't include any PHP stuff):
CREATE temporary table IF NOT EXIST temp tablename(id int primary key,
shared int default 0) replace select 1, userid as id
from tablefoo where sharedid = 1337
I don't quite understand what's going on here exactly, I know what a temporary table is, and I can quite accurately guestimate what IF NOT EXIST does, but what is replace doing here? I know replace is like insert but it replaces stuff as well, but in this case, nothing is specified for it to replace with, so does it just replace something with nothing and why the Select 1, I know that pretty much just tells you if your table has rows or something, but what is the point of using it here?
After some research, I found that IF NOT EXIST and replace do not exist in PostgreSQL. Most online sources suggest that SQL functions be used to replace them.
Should I use an SQL function to emulate IF NOT EXIST? If so, what would I write (sorry, I am pretty new to SQL) or should I just use a PHP function.
What about replace?
Sorry for the trouble, thanks for your time, oh and if you guys aren't busy or anything, you could also tell me about how to emulate "ignore", my current solution involves arbitrarily removing it.
Many uses in MySQL for temporary tables can be replaced in PostgreSQL with common table expressions or ordinary subselects.
WITH someCTE AS (
SELECT
...
) SELECT/UPDATE/DELETE ... WHERE sometable.column = someCTE.another_column;
Look into CREATE TABLE documentation. Temporary tables are just as name suggests not permanent:
If specified, the table is created as a temporary table. Temporary
tables are automatically dropped at the end of a session, or
optionally at the end of the current transaction (see ON COMMIT
below). Existing permanent tables with the same name are not visible
to the current session while the temporary table exists, unless they
are referenced with schema-qualified names. Any indexes created on a
temporary table are automatically temporary as well.
In particular temp tables are stored in diffrent (non-public) schema, e.g.:
=> Create Temporary Table someTempTable (value integer);
CREATE TABLE
=> \dt someTempTable
List of relations
Schema | Name | Type | Owner
-----------+---------------+-------+----------
pg_temp_2 | sometemptable | table | postgres
(1 row)
PostgreSQL doesn't have IF NOT EXISTS like in MySQL's CREATE TABLE, so you can't use it. If you want to create some table you need to firstly drop existing one (if it exists). Fortunately you could use SQL command DROP TABLE IF EXISTS to handle this:
=> Drop Table If Exists someTempTable;
DROP TABLE
=> Drop Table If Exists someTempTable;
NOTICE: table "sometemptable" does not exist, skipping
DROP TABLE