Sql server 将大型表从sql server复制到ssms中的odbc链接数据库(postgresql)

Sql server 将大型表从sql server复制到ssms中的odbc链接数据库(postgresql),sql-server,postgresql,odbc,ssms,Sql Server,Postgresql,Odbc,Ssms,我正在尝试将SQL Server中创建的整个数据库复制到Postgres。我一直在尝试编写一个脚本,可以在ssms中运行,并将postgres实例设置为链接服务器。这不是一次性操作 我已经设法创建了一个脚本来创建大多数模式,即表、约束、索引等。我通过使用sql server中的信息_schema表并格式化数据以形成有效的postgres sql,并在postgres运行EXEC(@sql)语句来实现这一点,其中,POSTGRES是链接的服务器,@SQL是包含我的语句的变量。这很好用 现在我尝试使

我正在尝试将SQL Server中创建的整个数据库复制到Postgres。我一直在尝试编写一个脚本,可以在ssms中运行,并将postgres实例设置为链接服务器。这不是一次性操作

我已经设法创建了一个脚本来创建大多数模式,即表、约束、索引等。我通过使用sql server中的信息_schema表并格式化数据以形成有效的postgres sql,并在postgres运行
EXEC(@sql)语句来实现这一点,其中,
POSTGRES
是链接的服务器,
@SQL
是包含我的语句的变量。这很好用

现在我尝试使用如下语句插入数据:

INSERT INTO OPENQUERY(POSTGRES,'SELECT * FROM targettable')
SELECT *
FROM sourcetable
INSERT INTO OPENQUERY(POSTGRES,'SELECT * FROM targettable')
SELECT *
FROM sourcetable
ORDER BY 1
OFFSET 0 ROWS FETCH NEXT 10000 ROWS ONLY
在某些情况下,这些语句实际上会稍微修改,以处理不同的数据类型,但这正是我们的想法。问题是,当表特别大时,此语句失败,出现错误:

Msg 109, Level 20, State 0, Line 0
A transport-level error has occurred when receiving results from the server. (provider: Named Pipes Provider, error: 0 - The pipe has been ended. 
我认为错误是由postgre或sql server使用太多内存生成大型语句造成的。我发现,如果我一次只手动选择要插入的数据的一部分,它就会起作用。例如,前10000行。但我不知道如何编写一个通用语句,一次只选择x行,而这不是我引用的表所特有的

也许有人能提出更好的方法。请记住,在将数据插入postgres之前,我确实需要更改一些数据,例如,地理空间信息被转换为字符串,以便postgres能够对其进行解释


谢谢

我已经转移了一些大型数据库,对于PostgreSQL,我看到了两种方法:

  • 将数据导出为CSV文件,将CSV文件转换为PostgreSQL
    COPY
    格式(请参阅),并使用
    COPY
    (wiki页面显示了更多备选方案)
  • 制作连接到两个数据库的Jython程序(Python很容易,Jython可以使用JDBC驱动程序),从源数据库中进行选择(如果有大量od数据,则使用
    setFetchSize()
    ),在目标数据库中使用带INSERT的PreparedStatement,然后使用
    dest_INSERT\u stmt.setObject(i,src_rs.getObject(i))

  • 我最终使用了SQL Server 2012中引入的
    偏移量X行只获取下一个Y行
    ,因此完整的语句如下所示:

    INSERT INTO OPENQUERY(POSTGRES,'SELECT * FROM targettable')
    SELECT *
    FROM sourcetable
    
    INSERT INTO OPENQUERY(POSTGRES,'SELECT * FROM targettable')
    SELECT *
    FROM sourcetable
    ORDER BY 1
    OFFSET 0 ROWS FETCH NEXT 10000 ROWS ONLY
    
    一切正常,出现错误!实际上,我使用动态SQL在每次迭代时都迭代
    偏移量
    值,并向其添加10000


    不是最干净或最好的解决方案。我想大多数人会更好地用Michal Niklas提到的另一种语言写东西,但这对我来说很有效。

    尝试
    插入
    a
    选择
    似乎有点奇怪。能否在PostgreSQL server中启用
    log\u语句='all'
    ,重新加载它,然后显示PostgreSQL日志中显示的内容?使用日志输出编辑您的问题,完成后在此处进行评论。我知道这是一个奇怪的符号,请查看microsoft关于openquery函数的文档。第二点似乎是我想要的一个好主意。但是我对TSQL有更好的了解,所以我最终选择了这条路线!但是,我将在某个时候研究Python和Jython的学习。我现在研究您提出的第二个建议,因为我在地理空间数据和使用odbc的速度方面存在一些问题。您是建议我使用zxJDBC连接数据库还是直接使用jdbc连接?如果是zxJDBC,我不知道如何进行批量插入。。。谢谢