4

我正在尝试编写一个应用程序,它将信息从 SQL Server 数据库中取出,通过 Web 服务加载对象模型,然后将该信息传递到 Access DB,该数据库基于与 SQL Server 不同的架构数据库,但包含的信息是相同的(所以我认为这类似于 ETL 过程)。我遇到的问题是,我正在提取信息的数据库(SQL Server)中的主键是 GUID,而我将它们放入(Access)的数据库是 INT。例如:

表 1,SQL Server 中的 Persons 表:

╔══════════════════════════════════════╦══════════╦════════════╗
║                  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,Access 中的 Persons 表:

╔════╦══════════╦════════════╗
║ 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 应该是唯一的。谁能想到一个好方法来做我想要完成的事情?我目前尝试这样做的方式有什么问题吗?

任何帮助将不胜感激。

4

2 回答 2

1

如果我是您,我不会依赖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     ║
╚══════════════════════════════════════╩══════════╝

如果不允许更改现有数据库,您甚至可以将其放入第三个数据库。

于 2012-05-17T14:43:29.320 回答
0

最简单的解决方案是在一端或另一端更改架构,以使它们相同。如果您在 Access 和 SQL 端都添加记录,那么我会使用 GUID 来防止为两个不同的记录添加相同的 ID。然后你所做的就是滚动你自己的“复制”系统。Access 和 SQL 都支持 GUID。

如果您不希望对每个表进行某种查找。这将为您提供每个 GUID 的等效整数,反之亦然。如果将 GUID 添加为 Access 表(表 2)中的附加列,则可以将其用作查找表。

ROW_NUMBER() 将返回唯一的数字,但每次使用时都会从 1 重新开始,因此每个表的所有插入都需要在一组中完成。如果您在访问中使用自动编号字段,这将为您提供跨单独插入的唯一值。

鉴于您现在在 Access 表中拥有 SQL 的 GUID 和唯一 ID,您只需在插入具有外键的表(例如地址表)时进行查找。因此,当您从带有 GUID 的 SQL 中插入地址以识别人员时,请在 GUID 上加入访问的人员表,并改为插入人员的整数 ID。

于 2012-05-17T10:22:57.823 回答