【问题标题】:SQL Server Linked Server Example QuerySQL Server 链接服务器示例查询
【发布时间】:2011-05-04 18:23:24
【问题描述】:

在 Management Studio 中,我尝试在两个链接服务器之间运行查询/连接。 这是使用链接数据库服务器的正确语法吗:

select foo.id 
from databaseserver1.db1.table1 foo, 
     databaseserver2.db1.table1 bar 
where foo.name=bar.name

基本上,您只是在 db.table 前面加上 db 服务器名称吗?

【问题讨论】:

    标签: sql-server linked-server


    【解决方案1】:

    格式应该是:

    <server>.<database>.<schema>.<table>
    

    例如: 数据库服务器1.db1.dbo.table1


    更新:我知道这是一个老问题,我的答案是正确的;但是,我认为任何其他偶然发现此问题的人都应该知道一些事情。

    也就是说,当在连接情况下查询链接服务器时,链接服务器中的 ENTIRE 表将可能按顺序下载到正在执行查询的服务器做join操作。在 OP 的情况下,来自DB1table1 和来自DB2table1 将全部传输到执行查询的服务器,大概命名为DB3

    如果您有大型表,这可能会导致操作需要很长时间才能执行。毕竟它现在受到网络流量速度的限制,比内存甚至磁盘传输速度慢几个数量级。

    如果可能,对远程服务器执行单个查询,而不连接到本地表,将您需要的数据提取到临时表中。然后查询。

    如果这不可能,那么您需要查看导致 SQL Server 必须在本地加载整个表的各种因素。例如使用GETDATE() 甚至某些连接。其他性能杀手包括不给予适当的权利。

    有关更多信息,请参阅http://thomaslarock.com/2013/05/top-3-performance-killers-for-linked-server-queries/

    【讨论】:

    • 如果数据库服务器名称有连字符,需要用方括号括起来
    • @bmw0128:更好的是,使用双引号:几乎所有平台都支持它,不像微软的方括号。
    • 当数据库服务器名称中有句点时,还需要使用方括号或双引号。
    • 如果您不确定任何限定符,请在 SSMS 对象资源管理器中深入到链接服务器中的表,单击鼠标右键,然后将表编写为、选择到和新查询编辑器窗口.生成的 SELECT 语句将包括正确的、完全限定的表路径。在使用 Sybase 时,我有一个神秘的数据库限定符,这给了我正确的名称。
    • @JohnMo 这不适用于某些非 SQL-Server 链接服务器 - 表结构不可用;我使用 ... SELECT * INTO [MySchema].[MyTable] FROM openquery(MyLinkedServer, 'SELECT * FROM TheSchema.TheTable WHERE 1=0'); 解决了这个问题
    【解决方案2】:
    SELECT * FROM OPENQUERY([SERVER_NAME], 'SELECT * FROM DATABASE_NAME..TABLENAME')
    

    这可能会对你有所帮助。

    【讨论】:

    • 赞成。这在您将 MySQL 链接到 MS SQL 时有效。
    • 换句话说,这是创建一个传递查询。请记住,查询语句必须以服务器的本机 SQL 编写。 Oracle 的语法不同于 Teradata,不同于 SQL Server 等。
    【解决方案3】:

    对于这些其他答案有问题的人,请尝试OPENQUERY

    例子:

     SELECT * FROM OPENQUERY([LinkedServer], 'select * from [DBName].[schema].[tablename]') 
    

    【讨论】:

    • 适用于 SQL Server
    • 这是唯一适合我的解决方案。快速翻译(可能对某些人有帮助):SELECT * INTO NEW_DB.dbo.tblCopy FROM OLD_DB.dbo.tblData forms to SELECT * INTO NEW_DB.dbo.tblCopy FROM OPENQUERY([server], 'select * from OLD_DB.dbo.tblData')
    【解决方案4】:

    如果您仍然发现 &lt;server&gt;.&lt;database&gt;.&lt;schema&gt;.&lt;table&gt; 有问题

    将服务器名称括在[]

    【讨论】:

    • 小心:我使用 [] 从 select 中执行了创建表,而不是在链接服务器上创建表,而是在本地创建表,名称类似于 dbo.databaseserver1.db1.dbo.table1
    【解决方案5】:

    您需要指定架构/所有者(默认为 dbo)作为参考的一部分。此外,最好使用较新的 (ANSI-92) 连接样式。

    select foo.id 
        from databaseserver1.db1.dbo.table1 foo
            inner join databaseserver2.db1.dbo.table1 bar 
                on foo.name = bar.name
    

    【讨论】:

    • 内连接语法优于隐式连接?
    • @bmw0128:是的,有几个原因。恕我直言,最重要的是,当您的表和连接位于两个不同的位置时,很容易意外地编写跨积连接。
    • 请注意,4-dotted-parts 不适用于某些非 SQL-Server 链接服务器。它可能会引发错误,例如...为链接服务器“MyLinkedServer”的提供程序“MSDASQL”指定了无效的架构或目录。
    【解决方案6】:
    select * from [Server].[database].[schema].[tablename] 
    

    这是正确的调用方式。 请务必在执行查询之前验证服务器是否已链接!

    检查链接服务器调用:

    EXEC sys.sp_linkedservers 
    

    【讨论】:

    • 这不适用于某些非 SQL-Server 链接服务器。它会引发错误,例如...为链接服务器“MyLinkedServer”的提供程序“MSDASQL”指定了无效的架构或目录。
    【解决方案7】:
    select name from drsql01.test.dbo.employee
    
    • drslq01 是 servernmae --linked serer
    • test 是数据库名称
    • dbo 是架构 - 默认架构
    • 员工是表名

    我希望它有助于理解,如何对链接服务器执行查询

    【讨论】:

      【解决方案8】:

      通常不应该在链接服务器的情况下使用直接查询,因为它大量使用 SQL 服务器的临时数据库。第一步将数据检索到临时数据库中,然后进行过滤。关于这个有很多线程。最好使用 open OPENQUERY,因为它将 SQL 传递给源链接服务器,然后返回过滤结果,例如

      SELECT *
      FROM OPENQUERY(Linked_Server_Name , 'select * from TableName where ID = 500')
      

      【讨论】:

      • 此答案不包含数据库名称
      • 我在创建链接服务器时确实提供了数据库信息。有关详细信息,您可以查看下面的 MSDN 链接:msdn.microsoft.com/en-us/library/ff772782(v=sql.110).aspx
      • 如果我的链接服务器需要身份验证,而我只是尝试使用 PDO 从我的 PHP 应用程序查询,我该怎么办?
      • 如何使用这种方法从数据库 1 连接到链接服务器上的数据库?
      【解决方案9】:

      右键单击一个表并单击脚本表作为选择

      【讨论】:

      • 那不是 OP 要求的
      • 这显示了如何为链接表上的选择查询获取正确的语法。结果就像肖恩回答
      • @ShimonDoodkin,一个很好的例子,不要给我一条鱼,而是教我如何钓鱼
      【解决方案10】:

      不管怎样,我发现以下语法效果最好:

      SELECT * FROM [LINKED_SERVER]...[TABLE]

      使用数据库名称,我无法获得其他人的建议。此外,此数据源没有架构。

      【讨论】:

        【解决方案11】:

        我已经使用openquery在link_server的表中查找了数据类型,结果是成功的。

        SELECT * FROM OPENQUERY (LINKSERVERNAME, '
        SELECT DATA_TYPE, COLUMN_NAME
        FROM [DATABASENAME].INFORMATION_SCHEMA.COLUMNS
        WHERE 
             TABLE_NAME  =''TABLENAME''
        ')
        

        对我有用

        【讨论】:

          【解决方案12】:

          以下查询效果最好。

          试试这个查询:

          SELECT * FROM OPENQUERY([LINKED_SERVER_NAME], 'SELECT * FROM [DATABASE_NAME].[SCHEMA].[TABLE_NAME]')
          

          将 MySQL 链接到 MS SQL 非常有帮助

          【讨论】:

            【解决方案13】:

            PostgreSQL

            1. 您必须在数据源 DSN 中提供一个数据库名称
            2. 管理员身份运行 Management Studio
            3. 您必须在查询中省略 DBName

              SELECT * FROM OPENQUERY([LinkedServer], 'select * from schema."tablename"')

            【讨论】:

              【解决方案14】:

              对于 MariaDB(可能还有 MySQL),尝试使用三点语法指定架构不起作用,导致错误“架构或目录的使用无效”。以下解决方案有效:

              1. 在 SSMS 中,转到服务器对象 > 链接服务器 > 提供程序 > MSDASQL
              2. 确保选中“动态参数”、“仅零级”和“允许进行中”

              然后您可以使用以下语法查询任何架构和表:

              SELECT TOP 10 *
              FROM LinkedServerName...[SchemaName.TableName]
              

              来源:SELECT * FROM MySQL Linked Server using SQL Server without OpenQuery

              【讨论】:

                【解决方案15】:

                在 sql-server(local) 中,有两种方法可以从链接服务器(remote) 查询数据。

                分布式查询(四部分表示法)

                1. 可能不适用于所有远程服务器。如果您的远程服务器是 MySQL,那么分布式查询将不起作用。
                2. 过滤器和连接可能无法有效工作。如果您有一个带有 WHERE 子句的简单查询,则 sql-server(local) 可能首先从远程服务器获取整个表,然后在本地应用 WHERE 子句。在大型表的情况下,这是非常低效的,因为大量数据将从远程移动到本地。然而,这并非总是如此。如果本地服务器可以访问远程服务器的表统计信息,那么它可能与使用 openquery More details 一样有效
                3. 积极的一面是 T-SQL 语法会起作用。
                SELECT * FROM [SERVER_NAME].[DATABASE_NAME].[SCHEMA_NAME].[TABLE_NAME] 

                打开查询

                1. 这基本上是一个传递。查询在远程服务器上完全处理,因此将使用远程服务器上的索引或任何优化。有效减少从远程传输到本地 sql-server 的数据量。
                2. 这种方法的小缺点是,如果远程服务器不是 sql-server,则 T-SQL 语法将不起作用。
                SELECT * FROM OPENQUERY([SERVER_NAME], 'SELECT * FROM DATABASE_NAME.SCHEMA_NAME.TABLENAME')

                在大多数情况下,整体 OPENQUERY 似乎是一个更好的选择。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-08-22
                  • 2014-04-16
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-08-09
                  • 2020-03-24
                  相关资源
                  最近更新 更多