65.9K
CodeProject 正在变化。 阅读更多。
Home

MS SQL Server 到 FireBird 迁移

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.84/5 (24投票s)

2005年2月4日

4分钟阅读

viewsIcon

129231

数据库迁移的实际案例(MS SQL -> FireBird)。

引言

最近我阅读了 CodeProject 上的一篇名为《Embedded Firebird》的文章,并决定尝试一下 FireBird。我喜欢嵌入式数据库的概念。 FireBird 允许 .NET 开发者将一个 DLL 放入 bin 目录,创建一个数据库文件,然后像平常一样访问数据库。理论上这听起来非常有吸引力且简单。所以我决定从 SQL Server 迁移到 FireBird。

数据库创建和工具

FireBird 的嵌入式版本非常轻巧,只有 1.5MB。 FireBird Data Provider for .NET 也不大,0.7MB。我下载了所有这些文件并将所需的 DLL 放入 bin 目录。然后我开始创建数据库。然而,FireBird Embedded 发行版不包含任何数据库管理工具。好吧,我下载了标准发行版(4MB)并在我的工作站上安装了功能齐全的 SuperServer。我翻遍了 Program Files,希望能找到一个数据库管理工具,结果找到了一个。它是一个 ISQL 控制台工具。“好吧,没有 GUI,”我心想,“这个数据库是为真正的极客准备的。”我打开了 QuickStart 指南,找到了关于数据库创建的部分,并尝试创建一个。但正如你可能猜到的,没有成功。出现了一个奇怪的行为,ISQL 拒绝相信我真的在创建新数据库,并告诉我数据库不可用。

在控制台纠结了一会儿后,我决定寻找一个 GUI 工具。在 IBPhoenix 网站 上有几个免费工具。我首先下载了 IBSQL(1MB)。它运行了,但当我尝试创建新数据库时,显示了一个错误“gds32.dll 未找到”。我到处查找,发现原始 DLL 可能被重命名并放入了 System32 目录。我启动了 IBSQL,它工作了!一个新数据库被创建了!

你认为迁移快要完成了?一点也不。模式导入成了一个真正的艰难任务。一开始,我就发现 FireBird 不支持 IDENTITY 关键字。这没问题,我删除了它。然后事情变得奇怪了。IBSQL 工具无法执行语句,在带有秒的表的 CREATE 语句行上弹出了错误。我尝试更正语句,并意识到该工具无法运行多个语句!大约有 40 条语句需要执行,而我一点也不想一条一条地手动执行。“好吧,找些更用户友好的东西吧。”我找到了 FeniSQL,一个非常轻巧(0.5MB)的工具。同样的 bug!我有点厌倦了。我在新闻组中找到了一些关于 IBOConsole 工具的建议,并下载了它们(2MB)。是的,这个工具确实很棒,拥有吸引人的 GUI 和有用的功能。并且在语句执行方面没有那些愚蠢的限制。

SQL 兼容性

然而,SQL 对 FireBird 来说仍然是错误的。我使用了名为“password”、“value”和“time”的列。这些是保留关键字。MS SQL Server 可以接受它们,但 FireBird 不行。如你所知,重命名几个列是个问题,但至少我想设置数据库。所以我重命名了模式中的字段,并再次运行了 SQL 脚本。数据库模式成功创建。

你认为迁移结束了吗?那一刻我以为是的,但 FireBird 将所有表名和列名都转换成了大写。而应用程序无法正确查询数据库。好吧。Google 新闻组很有帮助,我发现名称应该被引用。

CREATE TABLE "releases"
(
            "goal" VARCHAR(500),
            "finish_date" DATE,
            "start_date" DATE,
            "name" VARCHAR(150) NOT NULL,
            "project_plan_id" INTEGER NOT NULL,
            "release_id" INTEGER  NOT NULL,
             CONSTRAINT "pk_releases" PRIMARY KEY ( "release_id" )
);

我修改了 SQL,然后……是的!我做到了!我运行了应用程序,所有屏幕似乎都在工作。然后我尝试添加一个新项目,然后……是的,我收到一个错误(事实上我并不惊讶)。FireBird 不支持自增列。有一个解决方法是使用 Triggers 和 Generators。主要思想是创建一个生成器并在插入之前调用它来递增主键。有点像这样

CREATE GENERATOR "project_id_gen";
 
CREATE TRIGGER SET_ID FOR "projects";
BEFORE INSERT
AS BEGIN
   NEW."project_id" = GEN_ID ("project_id_gen", 1);
END

据我所知,这应该能正常工作。但它没有。

结论

我花了四个小时,下载了六个发行版,多次搜索 Google,几乎解决了所有问题(关键字是几乎)。好吧,也许我不是 DBA 大师,但我有使用几种主要数据库的丰富经验,并且从未遇到过如此的困难。FireBird 的行为在某些情况下对我来说是不合逻辑的,但我今天还是要完成迁移。不,我不是一只顽固的驴子,仅仅因为嵌入式。这条路很敏捷,应该很简单,但它很艰难。这很令人 sad。

今天我又捣鼓了 GENERATORS。然后(终于!)我找到了 关于 ID_GENERATOR 问题的帖子。解决方案是创建一个名为 id_generator 的表,其中包含两个字段:id (int)next (int)。我创建了 ID_GENERATOR 表,然后修改了触发器为

NEW."project_id" = GEN_ID (ID_GENERATOR, 1);

并且新的项目操作已经修复。你知道,FireBird 非常棘手……

作者简介

Michael Dubakov 是 TargetProcess 项目的负责人——XP Planning and Bug Tracking Software。

© . All rights reserved.