简体   繁体   English

将 MySQL DDL 转换为 SQL Server DDL

[英]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.我有一个为 MySQL 5 生成的模型,但现在我需要在 SQL Server 安装上创建这些表。

It's been years since I mucked with SQL server and I want to make sure I can convert this script to be compatible.自从我使用 SQL 服务器以来已经有很多年了,我想确保我可以将此脚本转换为兼容。

I don't really know what to look for TBQH, so without further ado, here's my MySQL DDL我真的不知道要寻找什么 TBQH,所以不用多说,这是我的 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.一种入门方法是将您的 DDL 加载到 MySQL 数据库中,然后使用mysqldump --compatible=mssql重新转储它。 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.这应该会让你开始——从那时起,它可能会浏览 T-SQL 文档并逐案询问这里。

In addition, Microsoft has some resources, such as this article (for SQL Server 2000, but it could help mapping the data types correctly).此外,Microsoft 有一些资源,例如这篇文章(对于 SQL Server 2000,但它可以帮助正确映射数据类型)。

Peter,彼得,

there are some differences between MySQL and MSSQL that you need to consider here, especially schemas.您需要在此处考虑 MySQL 和 MSSQL 之间的一些差异,尤其是模式。 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.我不太确定它们如何与 MySQL 一起工作,但它似乎几乎就像 MSSQL 本身所称的数据库一样。

A schema in MSSQL is more a security abstraction layer and used to group objects inside a database. MSSQL 中的模式更像是一个安全抽象层,用于对数据库内的对象进行分组。 It is something that is not greatly used AFAIK, but something that MS would like to promote.这是 AFAIK 没有大量使用的东西,而是 MS 想要推广的东西。 I have left it out here, and the objects are then created in the default schema (normally dbo).我在这里省略了它,然后在默认模式(通常是 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. AUTO_INCREMENT 被替换为 IDENTITY。 You specify the start value and the increment您指定起始值和增量
  • MSSQL doesnt have the notion of SIGNED or UNSIGNED ints MSSQL 没有 SIGNED 或 UNSIGNED 整数的概念
  • 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.列名 'text' 是一个保留关键字,也应该更改,以防止出现任何解析问题。

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:另一种可能性(如果您可以访问 MySQL 数据库本身,而不是 DDL)是使用 Microsoft 发布的迁移向导:

For migrating to SQL Server 2008: http://www.microsoft.com/downloads/details.aspx?FamilyID=0e6168b0-2d0c-4076-96c2-60bd25294a8e&displaylang=en迁移到 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迁移到 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.我已经使用了 SQL Server 2008 的向导......它运行良好。

-Brian -布莱恩

I am exporting DDL from MySQL Server version 5.7.12 into SQL Server version 12.00.6024 and have discovered the following:我正在将 DDL 从 MySQL Server 版本 5.7.12 导出到 SQL Server 版本 12.00.6024 并发现以下内容:

  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] .当我从 MySQL 导出 DDL 时,列名用反`my_column_name`包围,例如`my_column_name`但是当我从 SQL Server 导出时,列名用括号[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 . MySQL 使用关键字KEY表示INDEX Since there are actual PRIMARY KEY and FOREIGN KEY also identified, I had to manually go through the script and replace.由于还确定了实际的PRIMARY KEYFOREIGN KEY ,我不得不手动检查脚本并进行替换。

  2. MySQL exported columns with type bigint(20) . MySQL 导出类型为bigint(20)列。 I changed these to bigint我把这些改成了bigint

  3. I changed CHARACTER SET latin1 to COLLATE latin1我将CHARACTER SET latin1更改为COLLATE latin1

  4. I changed double to float(53) .我将double改为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]) .我删除了UNIQUE KEY [NAME] ([NAME]),并在表创建之后创建了一个 alter 语句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.在导出所有表定义两次后,我放弃了,只用 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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