我正在尝试编写一个应用程序,该应用程序将从SQL Server数据库中获取信息,通过Web服务加载对象模型,然后将该信息传递到Access DB,该数据库基于与SQL Server数据库不同的架构,但包含的信息是相同的(因此我认为这类似于ETL过程(。我遇到的问题是,我正在提取信息的数据库(SQL Server(中的主键是GUID,而我将它们放入的数据库(访问(是INT。所以例如:
表1, SQL Server 中的人员表:
╔══════════════════════════════════════╦══════════╦════════════╗
║ ID ║ Name ║ CreatedOn ║
╠══════════════════════════════════════╬══════════╬════════════╣
║ 3648F6BB-F743-4952-9C69-93336667F3B1 ║ Person 1 ║ 01/01/2012 ║
║ DE44577A-CAE7-4101-B962-C052214E723B ║ Person 2 ║ 02/01/2012 ║
║ 94115C5E-9C7E-40CF-8A87-D4D837BD5DB3 ║ Person 3 ║ 03/01/2012 ║
║ F93E77D9-C344-420C-9499-BA3B4DD0F0BA ║ Person 4 ║ 04/01/2012 ║
╚══════════════════════════════════════╩══════════╩════════════╝
表 2,访问中的人员表:
╔════╦══════════╦════════════╗
║ ID ║ Name ║ CreatedOn ║
╠════╬══════════╬════════════╣
║ 1 ║ Person 1 ║ 01/01/2012 ║
║ 2 ║ Person 2 ║ 02/01/2012 ║
║ 3 ║ Person 3 ║ 03/01/2012 ║
║ 4 ║ Person 4 ║ 04/01/2012 ║
╚════╩══════════╩════════════╝
因此,表 1 是数据在 SQL Server 数据库中的返回方式,表 2 是信息在 Access 数据库中的显示方式。因此,所有 GUID 都应是整数,但数据之间的关系应保持不变。例如,如果我在 SQL Server 和 Access 中运行查询以获取此人的地址(地址表也将以类似方式设置(,则无论是否使用 GUID 或整数,查询都应返回相同的结果。
我在想的是使用 SQL Server 中的 ROW_NUMBER((,按 CreatedOn 日期排序(这是数据库中的日期时间类型,因此在所有记录中应该是唯一的(:
SELECT
(ROW_NUMBER() OVER (ORDER BY CreatedOn)) AS ID,
Name,
CreatedOn
FROM Table2;
唯一的问题是我看到从查询返回重复的整数 ID。例如,上面的表 1 如下所示:
╔════╦══════════╦════════════╗
║ ID ║ Name ║ CreatedOn ║
╠════╬══════════╬════════════╣
║ 1 ║ Person 1 ║ 01/01/2012 ║
║ 2 ║ Person 2 ║ 02/01/2012 ║
║ 1 ║ Person 3 ║ 03/01/2012 ║
║ 1 ║ Person 4 ║ 04/01/2012 ║
╚════╩══════════╩════════════╝
当每个 ID 应该是唯一的时。谁能想到一个好方法来做我想完成的事情?我目前尝试的方式有什么问题吗?
任何帮助将不胜感激。
如果我是你,我不会依赖ROW_NUMBER()
,因为你可能无法确定顺序总是相同的:
首先,在您的示例中,您仅显示CreatedOn
列的日期值(不含时间(。如果在同一天创建了多个人,则无法确定在该日期之前订购哪个人先到。
即使您实际上在CreatedOn
列中也有时间 - 如果从表中删除一个人,所有后续人员的ROW_NUMBER
也会发生变化。
最简单的解决方案是更改其中一个表格,就像 webturner 在他的答案中已经建议的那样。
如果由于任何原因无法执行此操作(例如,如果根本不允许您更改任一数据库的架构,或者如果您更改表的架构,遗留内容会中断(,则可以创建一个映射表,在其中存储两个表之间的关系:
╔══════════════════════════════════════╦══════════╗
║ SqlServerID ║ AccessID ║
╠══════════════════════════════════════╬══════════╣
║ 3648F6BB-F743-4952-9C69-93336667F3B1 ║ 1 ║
║ DE44577A-CAE7-4101-B962-C052214E723B ║ 2 ║
║ 94115C5E-9C7E-40CF-8A87-D4D837BD5DB3 ║ 3 ║
║ F93E77D9-C344-420C-9499-BA3B4DD0F0BA ║ 4 ║
╚══════════════════════════════════════╩══════════╝
如果不允许更改现有数据库,您甚至可以将其放入第三个数据库中。
最简单的解决方案是更改一端或另一端的架构,使它们相同。如果要在访问端和 SQL 端添加记录,则我将使用 GUID 来防止为两个不同的记录添加相同的 ID。然后,您所做的就是滚动自己的"复制"系统。Access 和 SQL 都支持 GUID。
否则,您将需要对每个表进行某种查找。这将为每个 GUID 提供整数等效项,反之亦然。如果将 GUID 作为附加列添加到访问表(表 2(中,则可以将其用作查找表。
ROW_NUMBER(( 将返回唯一数字,但每次使用时都会从 1 重新开始,因此每个表的所有插入都需要在一个集合中完成。如果您在访问中使用"自动编号"字段,这将在单独的插入中为您提供唯一值。
鉴于您现在在 Access 表中拥有 SQL 的 GUID 和唯一 ID,您只需在插入具有外键的表(如地址表(时执行查找。因此,当您使用 GUID 插入来自 SQL 的地址以在 GUID 上标识人员加入访问的"人员"表并改为插入人员的整数 ID 时。