2

经过一番折腾,我设法安装了正确的 ODBC 驱动程序,并在 SQL Server 2008 上成功创建了一个链接服务器,通过它我可以从 SQL 服务器访问我的 PostgreSQL 数据库。

我正在使用以下形式的合并语句将 PgSQL DB 中的某些表中的所有数据复制到 SQL Server 中:

with mbRemote as 
    (
        select 
            * 
        from 
            openquery(someLinkedDb,'select * from someTable')
    ) 
merge into someTable mbLocal 
using mbRemote on mbLocal.id=mbRemote.id
when matched 
        /*edit*/ 
        /*clause below really speeds things up when many rows are unchanged*/
        /*can you think of anything else?*/
        and not (mbLocal.field1=mbRemote.field1
                and mbLocal.field2=mbRemote.field2
                and mbLocal.field3=mbRemote.field3
                and mbLocal.field4=mbRemote.field4)
        /*end edit*/
        then 
        update
        set
                mbLocal.field1=mbRemote.field1,
                mbLocal.field2=mbRemote.field2,
                mbLocal.field3=mbRemote.field3,
                mbLocal.field4=mbRemote.field4
when not matched then 
        insert
        (
            id,
            field1,
            field2,
            field3,
            field4
        )
        values
        (
            mbRemote.id,
            mbRemote.field1,
            mbRemote.field2,
            mbRemote.field3,
            mbRemote.field4
        )
WHEN NOT MATCHED BY SOURCE then delete;

此语句完成后,本地(SQL Server)副本与远程(PgSQL 服务器)完全同步。

关于这种方法的几个问题:

  1. 理智吗?
  2. 令我震惊的是,更新将在本地行中不一定更改的所有字段上运行。唯一的先决条件是本地和远程 id 字段匹配。是否有更细粒度的方法/一种将合并语句限制为仅更新实际更改的行的方法?
4

1 回答 1

1

如果您不能或不想使用像 SSIS 这样的工具,这看起来是一种合理的方法。

您可以在匹配时添加检查以检查是否发生了更改,例如:

when matched and mbLocal.field1 <> mbRemote.field1 then

如果您要检查的列多于几列,这将变得笨拙,因此您可以在其中添加一个检查列(例如 LastUpdatedDate)以使其更容易。

于 2010-03-18T22:13:32.433 回答