MySQL Vs. Oracle: Some more observations…

Posted : November 22, 2004 at 7:09 pm [America/Los_Angeles]

Almost 6 months back, I had written an entry on some of the differences that I found between Oracle and MySQL as I was getting to know more MySQL. This afternoon, while dabbling with some more MySQL, I found a few more things that I thought I would point out, especially pertaining to using MySQL’s mysql vs. Oracle’s sqlplus

Let’s take a simple Oracle SQL script (save it as run.sql):

set echo on;

drop table customers;

create table customers
(
 customerid number not null primary key,
 name varchar(11) not null,
 address varchar(100) not null,
 city varchar(30) not null

);

drop table orders;

create table orders
(
 orderid number not null primary key,
 customerid number not null,
 amount number(6,2),
 orderdate date not null

);

drop table books;

create table books
(
 isbn varchar(13) not null primary key,
 author varchar(50)
 title varchar(100),
 price number(6,2)
);

Upon execution, it gives the following result:

SQL> @E:run.sql;
SQL>
SQL> drop table customers;
drop table customers
           *
ERROR at line 1:
ORA-00942: table or view does not exist 

SQL>
SQL> create table customers
  2  (
  3   customerid number not null primary key,
  4   name varchar(11) not null,
  5   address varchar(100) not null,
  6   city varchar(30) not null
  7  );

Table created.

SQL>
SQL> drop table orders;
drop table orders
           *
ERROR at line 1:
ORA-00942: table or view does not exist 

SQL>
SQL> create table orders
  2  (
  3   orderid number not null primary key,
  4   customerid number not null,
  5   amount number(6,2),
  6   orderdate date not null
  7  );

Table created.

SQL>
SQL> drop table books;
drop table books
           *
ERROR at line 1:
ORA-00942: table or view does not exist 

SQL>
SQL> create table books
  2  (
  3   isbn varchar(13) not null primary key,
  4   author varchar(50),
  5   title varchar(100),
  6   price number(6,2)
  7  );

Table created.

SQL> 

Anyone who knows a thing or two about SQL can look at this interaction and come to a conclusion about whether the script went well or failed.

A quick-and-dirty translation of the SQL above into MySQL’s flavor resulted in this (save it as run1.sql):

drop table customers;

create table customers
(
 customerid int unsigned not null auto_increment primary key,
 name varchar(11) not null,
 address varchar(100) not null,
 city varchar(30) not null

);

drop table orders;

create table orders
(
 orderid int unsigned not null auto_increment primary key,
 customerid int unsigned not null,
 amount float(6,2),
 orderdate date not null

);

drop table books;

create table books
(
 isbn varchar(13) not null primary key,
 author varchar(50),
 title varchar(100),
 price float(6,2)
);

So, what’s different? Well, other than replacing all instances of number and number(x,y) from Oracle’s SQL script with MySQL’s int and float respectively and removing sqlplus-centric command like set echo on, it was really not much. So far so good.

However, if you try running this script using mysql (assuming you already have a MySQL user account and database with relevant privileges), your interaction will be perfunctory at best:

E:>mysql -D books -u anand -p < "E:run1.sql"
Enter password: ****************
ERROR 1051 (42S02) at line 1: Unknown table 'customers'

E:>

Well, that was dumb. Ofcourse there isin’t a ‘customers’ table. Can’t you just skip that error and just move on? Turns out, by default, mysql won’t. However, it has an option –force, -f which will solve our problem. Here’s what our interaction looks like with -f added:

E:>mysql -D books -f -u anand -p < "E:run1.sql"
Enter password: ********
ERROR 1051 (42S02) at line 1: Unknown table 'customers'
ERROR 1051 (42S02) at line 11: Unknown table 'orders'
ERROR 1051 (42S02) at line 21: Unknown table 'books'

E:>

While it worked, notice that the output is not too user-friendly. How do I know if the script worked or failed? After running my script, I had to login and run show tables to confirm that it had indeed worked. It was far cleaner in Oracle where the transcript of the session (thanks to set echo on) was pretty obvious.

So, after some more monkeying around with mysql’s command-line options, I was finally able to come up with an interaction which was almost like Oracle’s:

E:>mysql -D books -f -v -v -u anand -p < "E:run1.sql"
Enter password: ***********
--------------
drop table customers
--------------

ERROR 1051 (42S02) at line 1: Unknown table 'customers'
--------------
create table customers
(
 customerid int unsigned not null auto_increment primary key,
 name varchar(11) not null,
 address varchar(100) not null,
 city varchar(30) not null
)
--------------

Query OK, 0 rows affected

--------------
drop table orders
--------------

ERROR 1051 (42S02) at line 11: Unknown table 'orders'
--------------
create table orders
(
 orderid int unsigned not null auto_increment primary key,
 customerid int unsigned not null,
 amount float(6,2),
 orderdate date not null
)
--------------

Query OK, 0 rows affected

--------------
drop table books
--------------

ERROR 1051 (42S02) at line 21: Unknown table 'books'
--------------
create table books
(
 isbn varchar(13) not null primary key,
 author varchar(50),
 title varchar(100),
 price float(6,2)
)
--------------

Query OK, 0 rows affected

Bye

E:>

Much better. Definitely far more informative and user-friendly output.

Now, let’s zero-in on the various command-line options and what they mean:

E:>mysql -D books -f -v -v -u anand -p < “E:run1.sql”

The -D books specifies the database that the script will work on

The -f forces mysql to continue executing the SQL script despite errors

The -v -v (double -v) is for “more” verbose output. Try the command with just one -v and you will know why we need two -v

The -u anand specifies the userid that mysql will attempt logging in as

The -p tells mysql that it should prompt for a password in order to authenticate the user

On a side note, mysql sorta supports sqlplus’s spool command. During an interactive mysql session, you can use tee <filename> and notee options and it will work very similar to spool <filename> and spool off respectively. However, this does not seem to work when you run a batch SQL file

Bottomline, if you’re a frequent user of MySQL’s mysql client tool, hope these options taught you something new today. It sure was new to me

Note:

MySQL supports DDL statements that look like:

CREATE TABLE IF EXISTS customers;

This would have also solved our problem where ‘mysql’ seems to die when trying to run the MySQL sql script (shown above) for the first time. However, using -f (or –force) seemed somewhat simpler.

- Anand

Viewed: 3377 times

5 Comments

You should use

DROP TABLE IF EXISTS `customers`;

to prevent getting error messages.

Posted by: Mike at May 25, 2005 @ 12:13 pm

The Drop table command you displayed returns results:

Error: ORA-00933: SQL command not properly ended.

You have to do a lot of SQL to “drop if exists” in Oracle and it involves a cursor (and a lot of cursing)….

Posted by: George at March 15, 2006 @ 2:32 pm

I just found out how to drop a table in Oracle (if Exists) it’s ugly, but here goes:

declare
cursor c is
select 1 from all_TABLES where TABLE_name = ‘Customers’;
l_int integer;
begin
open c;
fetch c into l_int;
if c%found then
execute immediate ‘drop table Customers purge’; –Purge reclaims space, without purge table is moved to recyclebin.
end if;
close c;
exception
when others then
if c%isopen then
close c;
end if;
raise;
end;

Yech! I hate Oracle. Oracle is to SQL what Netscape was to IE.

Posted by: George at March 15, 2006 @ 3:08 pm

I was also looking for the same thing but was trying to create a table and a sequence if they did not exist; “CREATE TABLE IF NOT EXISTS table_name (field varchar2(20));” in Oracle.
Here is what I had to code to accomplish this in Oracle (I hope it saves someone some time):
DECLARE
tabl_name VARCHAR2 (100);
BEGIN
SELECT table_name
INTO tabl_name
FROM user_tables
WHERE UPPER (table_name) = ‘TABLE1′;
DBMS_OUTPUT.put_line (’Table TABLE1 already exists.’);
DBMS_OUTPUT.put_line (’Sequence TABLE1_SEQ already exists.’);

/* When table/sequence does not exist create them. */
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line (’NOTE: Creating table TABLE1…’);
DBMS_OUTPUT.put_line (’NOTE: Creating sequence TABLE1_SEQ…’);
EXECUTE IMMEDIATE ( ‘ CREATE TABLE table1 ( ‘
|| ‘ field1 number(5), ‘
|| ‘ field2 varchar2(100), ‘
|| ‘ field3 timestamp(2), ‘
|| ‘ field4 varchar2(10), ‘
|| ‘ field5 varchar2(10)) ‘
);

EXECUTE IMMEDIATE ( ‘CREATE SEQUENCE table1_seq ‘
|| ‘INCREMENT BY 1 ‘
|| ‘MINVALUE 0 ‘
|| ‘START WITH 0 ‘
|| ‘MAXVALUE 9999 ‘
|| ‘NOCACHE ‘
|| ‘NOCYCLE ‘
);
END;
/

Posted by: Kyle Miller at April 7, 2006 @ 9:44 am

Thank you, very much. This article really helped me a lot.

Posted by: ravi at September 17, 2006 @ 12:00 pm