简体   繁体   中英

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;

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).

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.

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

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, eg `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 KEY and 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]) .

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM