Peter Bailey
Peter Bailey

Reputation: 105918

Converting MySQL DDL to SQL Server DDL

I have a model that was generated for MySQL 5 but now I need to create these tables on a SQL Server installation.

It's been years since I mucked with SQL server and I want to make sure I can convert this script to be compatible.

I don't really know what to look for TBQH, so without further ado, here's my MySQL DDL

CREATE SCHEMA IF NOT EXISTS `bof_survey` DEFAULT CHARACTER SET utf8 COLLATE default collation ;
USE `bof_survey`;

-- -----------------------------------------------------
-- Table `bof_survey`.`question`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `bof_survey`.`question` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `text` VARCHAR(255) NOT NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `bof_survey`.`category`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `bof_survey`.`category` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `name` VARCHAR(45) NOT NULL ,
  `adverb` VARCHAR(45) NOT NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `bof_survey`.`answer`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `bof_survey`.`answer` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `question_id` INT UNSIGNED NULL ,
  `category_id` INT UNSIGNED NULL ,
  `text` VARCHAR(60) NULL ,
  PRIMARY KEY (`id`) ,
  INDEX `fk_answer_question` (`question_id` ASC) ,
  INDEX `fk_answer_category1` (`category_id` ASC) ,
  CONSTRAINT `fk_answer_question`
    FOREIGN KEY (`question_id` )
    REFERENCES `bof_survey`.`question` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_answer_category1`
    FOREIGN KEY (`category_id` )
    REFERENCES `bof_survey`.`category` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

Upvotes: 1

Views: 8812

Answers (5)

Jennifer Meyer
Jennifer Meyer

Reputation: 1

After exporting all the table definitions twice, I gave up and just coded the thing in Python.

count = 0
unique_keys = []
with open(my_sql_file_path, 'r') as input_file:
    data = input_file.readlines()

for line in data:
    count = count + 1
    if '`;' in line:
        line = line.replace('`;', '];')
    if '`,' in line:
        line = line.replace('`,', '],')
    if '` ' in line:
        line = line.replace('` ', '] ')
    if '`)' in line:
        line = line.replace('`)', '])')
    if '`\n' in line:
        line = line.replace('`\n', ']\n')
    if '`' in line:
        line = line.replace('`', '[')
    if 'ENGINE' in line.upper():
        line = line.replace('ENGINE', '-- ENGINE')
    if 'DOUBLE' in line.upper():
        line = line.replace('double', 'float(53)')
        line = line.replace('DOUBLE', 'FLOAT(53)')
    if 'ENGINE' in line.upper():
        line = line.replace('ENGINE', '-- ENGINE')
        line = line.replace('engine', '-- ENGINE')
    if 'bigint(20)' in line:
        line = line.replace('bigint(20)', 'bigint')
    if 'bigint(15)' in line:
        line = line.replace('bigint(15)', 'bigint')
    if 'CHARACTER SET' in line:
        line = line.replace('CHARACTER SET', 'COLLATE')
    if 'KEY' in line:
        if 'PRIMARY KEY' not in line \
                and 'UNIQUE KEY' not in line\
                and '_KEY_' not in line:
            line = line.replace('KEY', 'INDEX')
        if 'UNIQUE KEY' in line:
            row_num = (str(count) + " ")
            unique_keys.append(row_num)
        print(line)
print("Manually change these UNIQUE KEY lines to ALTER TABLE statements", unique_keys)

Upvotes: 0

Jennifer Meyer
Jennifer Meyer

Reputation: 1

I am exporting DDL from MySQL Server version 5.7.12 into SQL Server version 12.00.6024 and have discovered the following:

  1. When I export DDL from MySQL, the column names are surrounded with back ticks, e.g. `my_column_name` but when I export from SQL Server, the column names are surrounded by brackets [my_column_name].

I got around this by first doing a text search on all back ticks and replacing them with left brackets ([), then doing a search on left brackets followed by a space ([ ) and replacing them with right brackets followed by a space (] ), then doing a search on left brackets followed by a comma ([,) and replacing them with right brackets followed by a comma (],) and so forth.

  1. MySQL uses the keyword KEY where it means INDEX. Since there are actual PRIMARY KEYand FOREIGN KEY also identified, I had to manually go through the script and replace.

  2. MySQL exported columns with type bigint(20). I changed these to bigint

  3. I changed CHARACTER SET latin1 to COLLATE latin1

  4. I changed double to float(53).

  5. I removed UNIQUE KEY [NAME] ([NAME]), and created an alter statement after the table creation ALTER TABLE [my_table] ADD CONSTRAINT UNQ_NAME UNIQUE([NAME]).

Upvotes: 0

Brian Swan
Brian Swan

Reputation: 66

Another possibility (if you have access to the MySQL database itself, as opposed to the DDL) is to use the migration wizard that Microsoft has released:

For migrating to SQL Server 2008: http://www.microsoft.com/downloads/details.aspx?FamilyID=0e6168b0-2d0c-4076-96c2-60bd25294a8e&displaylang=en

For migrating to SQL Server 2005: http://www.microsoft.com/downloads/details.aspx?FamilyID=c6f14640-da22-4604-aaaa-a45de4a0cd4a&displaylang=en

I've used the wizard for SQL Server 2008...it works well.

-Brian

Upvotes: 0

sql_williamd
sql_williamd

Reputation: 441

Peter,

there are some differences between MySQL and MSSQL that you need to consider here, especially schemas. I am not too sure how they work with MySQL, but it seems to be almost like what MSSQL calls a database in its own right.

A schema in MSSQL is more a security abstraction layer and used to group objects inside a database. It is something that is not greatly used AFAIK, but something that MS would like to promote. I have left it out here, and the objects are then created in the default schema (normally dbo).

Needless to say, the rest is quite straight forward:

-- ----------------------------------------------------- 
-- Table question
-- ----------------------------------------------------- 
IF NOT EXISTS ( SELECT  *
                FROM    sys.objects
                WHERE   name = 'question' ) 
    BEGIN
        CREATE  TABLE question
            (id int IDENTITY(1, 1)
                    NOT NULL,
             text varchar(255) NOT NULL,
             PRIMARY KEY (id)) ; 
    END 

-- ----------------------------------------------------- 
-- Table category 
-- ----------------------------------------------------- 
IF NOT EXISTS ( SELECT  *
                FROM    sys.objects
                WHERE   name = 'category' ) 
    CREATE  TABLE category
        (id int IDENTITY(1, 1)
                NOT NULL,
         name varchar(45) NOT NULL,
         adverb varchar(45) NOT NULL,
         PRIMARY KEY (Id)) ; 

-- ----------------------------------------------------- 
-- Table answer 
-- ----------------------------------------------------- 
IF NOT EXISTS ( SELECT  *
                FROM    sys.objects
                WHERE   name = 'answer' ) 
    CREATE  TABLE answer
        (id int IDENTITY(1, 1)
                NOT NULL,
         question_id int NULL,
         category_id int NULL,
         text varchar(60) NULL PRIMARY KEY (Id),
         CONSTRAINT fk_answer_question FOREIGN KEY (question_id) REFERENCES question (id) ON DELETE NO ACTION ON UPDATE NO ACTION,
         CONSTRAINT fk_answer_category1 FOREIGN KEY (category_id) REFERENCES category (id) ON DELETE NO ACTION ON UPDATE NO ACTION);

CREATE INDEX fk_answer_question ON answer(question_id ASC) 
CREATE INDEX fk_answer_category1 ON answer(category_id ASC) 

Please note the following changes:

  • AUTO_INCREMENT is swapped for IDENTITY. You specify the start value and the increment
  • MSSQL doesnt have the notion of SIGNED or UNSIGNED ints
  • The Primary key will be created as a clustered index by default
  • The indexes will be created as non-unique and non clustered unless specified

The columnname 'text' is a reserved keyword and should be changed too, to stop any parsing problems.

Hope that helps.

Upvotes: 3

chryss
chryss

Reputation: 7519

One way of getting started is to load your DDL into a MySQL database and then use mysqldump --compatible=mssql to re-dump it. That should get you started -- and from there on it may be going through the T-SQL docs and asking here on a case-by-case basis.

In addition, Microsoft has some resources, such as this article (for SQL Server 2000, but it could help mapping the data types correctly).

Upvotes: 3

Related Questions