明明已经连接远程DB了,但是总是提示[在sys.servers里找不到远程DB连接SUBLNK]。
但是如果把[第一段  开始]~[第一段  结束]的代码屏蔽掉的话,则可以顺利执行。
为什么加了第一段就不行了。
---------------第一段  开始---------------------------------------------------
USE [ABCDB]
GOIF (EXISTS (SELECT * FROM SYS.OBJECTS WHERE NAME = 'SP_COPYDATAFROMSUBDB'))
    DROP PROCEDURE SP_COPYDATAFROMSUBDB
GOCREATE PROCEDURE [dbo].[SP_COPYDATAFROMSUBDB]
AS
---------------第一段  结束------------------------------------------------------------------------------------远程DB连接---------------------------------
EXEC master.dbo.SP_ADDLINKEDSERVER 'SUBLNK', '','SQLNCLI',N'JCAPP\JCSQLSERVER12R2'
EXEC master.dbo.SP_ADDLINKEDSRVLOGIN 'SUBLNK','false ',NULL, 'sa', 'sa_12345678'
GOSELECT COUNT(1) FROM SUBLNK.SUBDB.DBO.M_CLIENT WHERE CLIENT_CODE = 'C0101'EXEC SP_DROPSERVER 'SASLNK ', 'droplogins'
GO

解决方案 »

  1.   

    本机通过sqlserver客户端执行的。但是我试验了一下,即使在服务器上执行,也是同样的错误。
      

  2.   

    纯粹的sql的话(---远程DB连接---下面的那部分代码),就没问题。
    但是为何加了个存储过程的create,就报错了呢?纳闷!
      

  3.   

    不加IF,单纯create proc行不行?
      

  4.   

    create proc的内容就是创建链接服务器?
      

  5.   

    链接服务器的代码放到存储过程里面执行的话,没问题,这个一开始没写成存储过程,就是一堆sql代码,都可以执行,可是一写成存储过程,就不行了。
      

  6.   

    创建linkserver的语句和查询的不能同时放到一个sp里面
    就是linkserver 还没有创建呢,但是查询语句还是会去判断一下对象
    似乎是这样的逻辑,导致编译出错了
    你这样做也米有什么意义,密码岂不是都被看到了
    如果只用一次使用的话,直接用openrowset
      

  7.   


    EXEC master.dbo.SP_ADDLINKEDSERVER 'SUBLNK', '','SQLNCLI',N'JCAPP\JCSQLSERVER12R2'
    EXEC master.dbo.SP_ADDLINKEDSRVLOGIN 'SUBLNK','false ',NULL, 'sa', 'sa_12345678'
    GO这部分不需要每次都执行,这是创建SUBLNK的,创建好了,下次直接用就行。
    所以把这两行代码放到存储过程外面执行一次就行了。
      

  8.   


    会不会是当中多加了一个 go呢:USE [ABCDB]
    GOIF (EXISTS (SELECT * FROM SYS.OBJECTS WHERE NAME = 'SP_COPYDATAFROMSUBDB'))
        DROP PROCEDURE SP_COPYDATAFROMSUBDB
    GOCREATE PROCEDURE [dbo].[SP_COPYDATAFROMSUBDB]
    AS
    ---------------第一段  结束------------------------------------------------------------------------------------远程DB连接---------------------------------
    EXEC master.dbo.SP_ADDLINKEDSERVER 'SUBLNK', '','SQLNCLI',N'JCAPP\JCSQLSERVER12R2'
    EXEC master.dbo.SP_ADDLINKEDSRVLOGIN 'SUBLNK','false ',NULL, 'sa', 'sa_12345678'
    GOSELECT COUNT(1) FROM SUBLNK.SUBDB.DBO.M_CLIENT WHERE CLIENT_CODE = 'C0101'EXEC SP_DROPSERVER 'SASLNK ', 'droplogins'
    GO
      

  9.   

    问题是不是只用一次啊,上面的代码只是一部分。
    这个远程连接要用到25次。
    sql现在总共写了4000行了。纯粹的sql可以执行的,但是一做成存储过程就不行了。
      

  10.   

    首先,手动创建链接服务器,
    然后,存储过程里面凡是要用到链接服务器的都加上:
    链接服务器名.db..tablename这样的格式,不要再把创建链接服务器的代码放到sp中
      

  11.   

    YES,你们说的对,我手动建立一个dbLink试一下。
      

  12.   

    手动建立一个dbLink,不能给这个dbLink起别名吗?原名太长了
    HIAPPSRV\JCSQLSERVER201212_R2,而且有[\],语法上通不过
      

  13.   

    距我了解,不行,\这个问题可以用:
    [HIAPPSRV\JCSQLSERVER201212_R2]来解决
      

  14.   


    下面的代码,就是你的存储过程的代码是把:---------------第一段  开始---------------------------------------------------
    USE [ABCDB]
    GOIF (EXISTS (SELECT * FROM SYS.OBJECTS WHERE NAME = 'SP_COPYDATAFROMSUBDB'))
        DROP PROCEDURE SP_COPYDATAFROMSUBDB
    GOCREATE PROCEDURE [dbo].[SP_COPYDATAFROMSUBDB]
    AS
    ---------------第一段  结束------------------------------------------------------------------------------------远程DB连接---------------------------------
    EXEC master.dbo.SP_ADDLINKEDSERVER 'SUBLNK', '','SQLNCLI',N'JCAPP\JCSQLSERVER12R2'
    EXEC master.dbo.SP_ADDLINKEDSRVLOGIN 'SUBLNK','false ',NULL, 'sa', 'sa_12345678'
    GOSELECT COUNT(1) FROM SUBLNK.SUBDB.DBO.M_CLIENT WHERE CLIENT_CODE = 'C0101'EXEC SP_DROPSERVER 'SASLNK ', 'droplogins'
    GO如果是的话,中间那个go就没有必要了,这个语句单独运行,肯定是没问题的,但多了go之后,意义就变了,改成这样试试:
    ---------------第一段  开始---------------------------------------------------
    USE [ABCDB]
    GOIF (EXISTS (SELECT * FROM SYS.OBJECTS WHERE NAME = 'SP_COPYDATAFROMSUBDB'))
        DROP PROCEDURE SP_COPYDATAFROMSUBDB
    GOCREATE PROCEDURE [dbo].[SP_COPYDATAFROMSUBDB]
    AS
    ---------------第一段  结束------------------------------------------------------------------------------------远程DB连接---------------------------------
    EXEC master.dbo.SP_ADDLINKEDSERVER 'SUBLNK', '','SQLNCLI',N'JCAPP\JCSQLSERVER12R2'
    EXEC master.dbo.SP_ADDLINKEDSRVLOGIN 'SUBLNK','false ',NULL, 'sa', 'sa_12345678'
    --GOSELECT COUNT(1) FROM SUBLNK.SUBDB.DBO.M_CLIENT WHERE CLIENT_CODE = 'C0101'EXEC SP_DROPSERVER 'SASLNK ', 'droplogins'
    GO
      

  15.   

    阳泉酒家小当家,多谢热心帮助啊,按照你的试了一下,一样的错误。
    Could not find server 'SUBLNK' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
      

  16.   


    呵呵,我知道问题在哪儿了:我做了一个实验:
    1.下面的代码报错了
    --建立链接服务器,通过@datasrc指定数据源,适合链接其他多种数据库
    EXEC master.dbo.sp_addlinkedserver @server = N'Link1',
                                       @srvproduct='ms', 
                                       @provider=N'SQLNCLI',                                    
                                       @datasrc=N'192.168.1.106,1433'EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'Link1',
                                        @useself=N'False',
                                        @locallogin=NULL,
                                        @rmtuser=N'sa',
                                        @rmtpassword='yupeigu'
      
                                        
    --查询远程表
    select * 
    from [Link1].test.dbo.t1
    /*
    消息 7202,级别 11,状态 2,第 18 行
    在 sys.servers 中找不到服务器 'Link1'。请验证指定的服务器名称是否正确。
    如果需要,请执行存储过程 sp_addlinkedserver 以将服务器添加到 sys.servers。
    */
    2.在创建连接服务器后,在select 连接服务器之间,加了一个go,就不报错了,这说明了一个问题,就是连接服务器,在用之前,必须已经存在,而且创建连接服务器、和使用连接服务器,不能在一个批处理中,也就是必须要加一个go语句,这样就成了2个批处理了:--建立链接服务器,通过@datasrc指定数据源,适合链接其他多种数据库
    EXEC master.dbo.sp_addlinkedserver @server = N'Link2',
                                       @srvproduct='ms', 
                                       @provider=N'SQLNCLI',                                    
                                       @datasrc=N'192.168.1.106,1433'EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'Link2',
                                        @useself=N'False',
                                        @locallogin=NULL,
                                        @rmtuser=N'sa',
                                        @rmtpassword='yupeigu'
      
    go
                                        
    --查询远程表
    select * 
    from [Link2].test.dbo.t1
    /*
    id v
    7 NULL
    9 NULL
    1 aa
    2 bb
    3 cc
    4 dd
    5 ee
    6 ff
    8 gg
    */3.所以,建议你采用上面提到的方面,就是先建立连接服务器,然后再使用,比如现在存储过程之外建立连接服务器,然后再存储过程中使用。
      

  17.   

    否则,由于你的连接服务器是动态创建的,也就是说在你创建存储过程的时候,连接服务器还没创建,所以报错了:xxx服务器在sys.servers中不存在