MySQL "CREATE TABLE IF NOT EXISTS" -> Error 1050 - sql

Using the command:
CREATE TABLE IF NOT EXISTS `test`.`t1` (
`col` VARCHAR(16) NOT NULL
) ENGINE=MEMORY;
Running this twice in the MySQL Query Browser results in:
Table 't1' already exists Error 1050
I would have thought that creating the table "IF NOT EXISTS" would not throw errors. Am I missing something or is this a bug? I am running version 5.1. Thanks.

Works fine for me in 5.0.27
I just get a warning (not an error) that the table exists;

As already stated, it's a warning not an error, but (if like me) you want things to run without warnings, you can disable that warning, then re-enable it again when you're done.
SET sql_notes = 0; -- Temporarily disable the "Table already exists" warning
CREATE TABLE IF NOT EXISTS ...
SET sql_notes = 1; -- And then re-enable the warning again

You can use the following query to create a table to a particular database in MySql.
create database if not exists `test`;
USE `test`;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
/*Table structure for table `test` */
CREATE TABLE IF NOT EXISTS `tblsample` (
`id` int(11) NOT NULL auto_increment,
`recid` int(11) NOT NULL default '0',
`cvfilename` varchar(250) NOT NULL default '',
`cvpagenumber` int(11) NULL,
`cilineno` int(11) NULL,
`batchname` varchar(100) NOT NULL default '',
`type` varchar(20) NOT NULL default '',
`data` varchar(100) NOT NULL default '',
PRIMARY KEY (`id`)
);

create database if not exists `test`;
USE `test`;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
/*Table structure for table `test` */
***CREATE TABLE IF NOT EXISTS `tblsample` (
`id` int(11) NOT NULL auto_increment,
`recid` int(11) NOT NULL default '0',
`cvfilename` varchar(250) NOT NULL default '',
`cvpagenumber` int(11) NULL,
`cilineno` int(11) NULL,
`batchname` varchar(100) NOT NULL default '',
`type` varchar(20) NOT NULL default '',
`data` varchar(100) NOT NULL default '',
PRIMARY KEY (`id`)
);***

I have a solution to a problem that may also apply to you. My database was in a state where a DROP TABLE failed because it couldn't find the table... but a CREATE TABLE also failed because MySQL thought the table existed. (This state could easily mess with your IF NOT EXISTS clause).
I eventually found this solution:
sudo mysqladmin flush-tables
For me, without the sudo, I got the following error:
mysqladmin: refresh failed; error: 'Access denied; you need the RELOAD privilege for this operation'
(Running on OS X 10.6)

Create mysql connection with following parameter. "'raise_on_warnings': False". It will ignore the warning. e.g.
config = {'user': 'user','password': 'passwd','host': 'localhost','database': 'db', 'raise_on_warnings': False,}
cnx = mysql.connector.connect(**config)

I had a similar Problem as #CraigWalker on debian: My database was in a state where a DROP TABLE failed because it couldn't find the table, but a CREATE TABLE also failed because MySQL thought the table still existed. So the broken table still existed somewhere although it wasn't there when I looked in phpmyadmin.
I created this state by just copying the whole folder that contained a database with some MyISAM and some InnoDB tables
cp -a /var/lib/mysql/sometable /var/lib/mysql/test
(this is not recommended!)
All InnoDB tables where not visible in the new database test in phpmyadmin.
sudo mysqladmin flush-tables didn't help either.
My solution: I had to delete the new test database with drop database test and copy it with mysqldump instead:
mysqldump somedatabase -u username -p -r export.sql
mysql test -u username -p < export.sql

Well there are lot of answeres already provided and lot are making sense too.
Some mentioned it is just warning and some giving a temp way to disable warnings. All that will work but add risk when number of transactions in your DB is high.
I came across similar situation today and here is the query I came up with...
declare
begin
execute immediate '
create table "TBL" ("ID" number not null)';
exception when others then
if SQLCODE = -955 then null; else raise; end if;
end;
/
This is simple, if exception come while running query it will be suppressed. and you can use same for SQL or Oracle.

If anyone is getting this error after a Phpmyadmin export, using the custom options and adding the "drop tables" statements cleared this right up.

Related

Golang-migrate returns "no change"

I'm starting learn Go and SQL. I tryed to make initial migration using golang-migrate in my go project. Database is postgresql
This is migration file:
CREATE TABLE users
(
id serial not null unique,
name varchar(255) not null,
username varchar(255) not null unique,
password_hash varchar(255) not null,
)
CREATE TABLE todo_lists
(
id serial not null unique,
title varchar(255) not null,
description varchar(255),
);
CREATE TABLE users_lists
(
id serial not null unique,
user_id int references users (id) on delete cascade not null,
list_id int references todo_lists (id) on delete cascade not null,
);
CREATE TABLE todo_items
(
id serial not null unique,
title varchar(255) not null,
description varchar(255),
done boolean not null default false,
);
CREATE TABLE lists_items
(
id serial not null unique,
item_id int references todo_items (id) on delete cascade not null,
list_id int references todo_lists (id) on delete cascade not null,
);
The command I use:
migrate -path ./schema -database 'postgres://postgres:root#localhost:5432/to_do?sslmode=disable' up
And bash returns:
no change (without any error)
Where can be problem?
I put together a small guide to help you solve your issue. Please be sure to follow along and you would be good to go!
Run Postgres
To run the Postgres instance I used to test my solution I used the following command:
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=postgres postgres
This command spins up an instance of Postgres with these two things:
It sets up the port mapping (the port 5432 on your machine is mapped to the port 5432 of your Docker container).
It sets the password for the postgres user to postgres (just for the sake of the demo).
Create the migration scripts
To create the first migration script, I used the following command:
migrate create -ext sql -dir db/migrations -seq create_users_table
Thanks to this command, I was able to create the folder path db/migrations and two files within it (one for the up migration and one for the down one).
Fill the files with the code
The next step was to fill the above-created files with the CREATE and DROP statements. Let's start with the up one.
000001_create_users_table.up.sql file
CREATE TABLE IF NOT EXISTS users
(
id serial not null unique,
name varchar(255) not null,
username varchar(255) not null,
password_hash varchar(255) not null
);
CREATE TABLE IF NOT EXISTS todo_lists
(
id serial not null unique,
title varchar(255) not null,
description varchar(255)
);
CREATE TABLE IF NOT EXISTS users_lists
(
id serial not null unique,
user_id int references users (id) on delete cascade not null,
list_id int references todo_lists (id) on delete cascade not null
);
CREATE TABLE IF NOT EXISTS todo_items
(
id serial not null unique,
title varchar(255) not null,
description varchar(255),
done boolean not null default false
);
CREATE TABLE IF NOT EXISTS lists_items
(
id serial not null unique,
item_id int references todo_items (id) on delete cascade not null,
list_id int references todo_lists (id) on delete cascade not null
);
To make the migration idempotent I added the IF NOT EXISTS check. Take this as a best practice when you're about to write migrations.
000001_create_users_table.down.sql file
DROP TABLE IF EXISTS users_lists;
DROP TABLE IF EXISTS lists_items;
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS todo_lists;
DROP TABLE IF EXISTS todo_items;
The same applies here with the IF EXISTS check. Pay attention to the order in which you're deleting stuff as you can easily get into error due to objects' dependencies.
Run migrations
To run this migration, be sure that the to_do DB is created.
To apply the migration run:
migrate -database 'postgres://postgres:postgres#localhost:5432/to_do?sslmode=disable' -path ./db/migrations up
With this, you'll get this output: 1/u create_users_table (44.392422ms).
If you run this twice, the second output will be: no change.
When you want to undo the migration, you've to run the following statement:
migrate -database 'postgres://postgres:postgres#localhost:5432/to_do?sslmode=disable' -path ./db/migrations down
This will undo all of the migrations applied so far. For a deeper understanding, please refer to the official doc: https://github.com/golang-migrate/migrate#cli-usage.
Let me know if this solves your issue or if you need anything else!
I resolve this problem by deleting migration table and correcting sql file (delete ',' in every string of last columns)

current_timestamp() vs CURRENT_TIMESTAMP for default value on TIMESTAMP column (mariadb:latest/mysql, laravel, sequel pro)

What is the difference between CURRENT_TIMESTAMP and current_timestamp() ?
I'm using laravel, and in the laravel migration file for my Tasks table I have this:
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate();
For my database container, I am using a local docker setup with:
mariadb:latest (seems to be bringing up version 10.8.3-MariaDB-1:10.8.3+maria~jammy (mariadb.org binary distribution) )
and the weird thing is..
I have Sequel Pro open, and when trying to manually insert a record ( for testing purposes ) through the sequel pro interface and it is failing with the following error:
Incorrect datetime value: 'current_timestamp()' for column .. created_at..
Notice when I click to add a new row, the defaults are 'current_timestamp()'
If I manually change these defaults to 'CURRENT_TIMESTAMP' instead of 'current_timestamp()' it seems to work:
The function/call or lower case version of CURRENT_TIMESTAMP does not work...
If I add a new row programatically / with laravel:
$newTask = new Task();
$newTask->title = 'testing';
$newTask->save();
the row is inserted properly ( with the current timestamp values.. ):
Where is this problem at?
Laravel side/configuration?
Could it be the 'mariadb:latest' bringing up a bug?
Could it be a sequel pro bug ?
This is the create table definition btw:
CREATE TABLE `tasks` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
While developing this question, I have decided to download MySql Workbench and try inserting the values there through the MySql Workbench interface,
and it seems to work, and it seems that it is because MySql Workbench simply runs INSERT queries:
INSERT INTO `tasks_pabloserver_db`.`tasks` (`title`) VALUES ('teeest');
INSERT INTO `tasks_pabloserver_db`.`tasks` (`title`) VALUES ('test444');
which work and insert the proper default/timestamp values.
I looked at the table structure in MySql Workbench and the default value is 'current_timestamp()' and not 'CURRENT_TIMESTAMP', and it still works so it cannot be the database version I guess.
So then I tried to run these same INSERT statements in Sequel Pro and it also worked properly, so my conclusion is that Sequel Pro interface has a bug and that is to blame.

H2 org.h2.jdbc.JdbcSQLSyntaxErrorException occurs when executing a script file in a h2 database

I have used java -cp h2-1.4.199.jar org.h2.tools.RunScript -url jdbc:h2:mem:db1 -script infra_params.sql command to execute below sql script in a H2 database.
infra_params.sql file:-
DROP TABLE IF EXISTS `infrastructure_parameter`;
CREATE TABLE `infrastructure_parameter` (
`id` varchar(36) NOT NULL,
`created_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modified_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`NAME` varchar(255) DEFAULT NULL,
`PROPERTIES` varchar(255) DEFAULT NULL,
`ready` tinyint(1) DEFAULT '0',
`TYPE` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNQ_infrastructure_parameter_0` (`NAME`,`PROPERTIES`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
LOCK TABLES `infrastructure_parameter` WRITE;
But it gives following exception:-
Exception in thread "main" org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "
LOCK[*] TABLES `INFRASTRUCTURE_PARAMETER` WRITE "; SQL statement:
LOCK TABLES `infrastructure_parameter` WRITE [42000-199]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:451)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
at org.h2.message.DbException.get(DbException.java:205)
at org.h2.message.DbException.get(DbException.java:181)
at org.h2.message.DbException.getSyntaxError(DbException.java:229)
at org.h2.command.Parser.getSyntaxError(Parser.java:989)
at org.h2.command.Parser.parsePrepared(Parser.java:951)
at org.h2.command.Parser.parse(Parser.java:788)
at org.h2.command.Parser.parse(Parser.java:764)
at org.h2.command.Parser.prepareCommand(Parser.java:683)
at org.h2.engine.Session.prepareLocal(Session.java:627)
at org.h2.engine.Session.prepareCommand(Session.java:565)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1292)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:217)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:205)
at org.h2.tools.RunScript.process(RunScript.java:261)
at org.h2.tools.RunScript.process(RunScript.java:192)
at org.h2.tools.RunScript.process(RunScript.java:328)
at org.h2.tools.RunScript.runTool(RunScript.java:143)
at org.h2.tools.RunScript.main(RunScript.java:70)
Any help on how to fix this issue would be appreciated.
LOCK TABLES is a MySQL-specific command, it isn't supported by H2.
You need to remove it from your file.
If you really need to use the same script in both MySQL and H2 and need this command in MySQL, you can try to wrap it into executable comment. MySQL, unlike other databases, executes code in /*! … */ comments.
/*! LOCK TABLES `infrastructure_parameter` WRITE; */

SQL syntax error

I use phpMyAdmin and want to create a table. I use the visual interface for creating the table but I'm gonna post the code from "Preview SQL" option:
CREATE TABLE `baza`.`koncert` (
`koncert_id` INT(10) NOT NULL AUTO_INCREMENT ,
`koncert_naziv` VARCHAR(50) NULL ,
`koncert_lokacija` VARCHAR(50) NOT NULL ,
`koncert_datum` DATE NULL DEFAULT NULL ,
`koncert_cijena` DOUBLE(10) NOT NULL ,
`koncert_slika` VARCHAR(500) NOT NULL )
ENGINE = InnoDB CHARSET=utf8 COLLATE utf8_croatian_ci;
And I get this error:
1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL version for the right syntax to use near ')' NOT NULL, 'koncert_slika' VARCHAR(500) NOT NULL ) ENGINE=InnoDB CHARSET=ut
I tried setting the 'koncert_datum' default value to CURRENT_TIMESTAMP, but then I get an error "Invalid default value for 'koncert_datum'". I just don't understand what could possibly be wrong (and I used the phpMyAdmin visual interface to try create the table!)
According to the documentation https://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html the DOUBLE type needs total digits and decimal digits. Something like
`koncert_cijena` DOUBLE(12,2) NOT NULL ,
Check the schema and ensure baza.koncert is present and try running them by removing "ENGINE = InnoDB CHARSET=utf8 COLLATE utf8_croatian_ci" this.

sql: making a table structure for injections

I want to take the values from this site for the country table in my database.
The problem is that they don't provide the table structure, so I have to create one, but I cannot get it right - my phpMyAdmin keeps displaying an error when I want to inject the data into the table I created below:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NUMERIC, alpha3, name, officialName) VALUES ('004','AFG','Afghanistan','Afghan' at line 1
--
-- Table structure for table `countrytable`
--
CREATE TABLE IF NOT EXISTS `countrytable` (
`NUMERIC` int(11) NOT NULL,
`alpha3` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`officialName` varchar(255) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
I think my table structure is incorrect. How can I fix it? Thanks!
Try all varchar fields to get the data in since all fields are in quotes in the string you have.
NUMERIC is reserved word in mysql
add in back-tick or quote it -> http://dev.mysql.com/doc/refman/5.1/en/reserved-words.html
`alpha3` should be a varchar(3) (or larger), not an int(11).