SQL ERROR 7311解决方法

今天又遇到一个问题,建立一个Linked Server,在Management Studio可以展开它,看到视图,用select竟查不到数据,而且出现错误:

Msg 7311, Level 16, State 2, Line 1
Cannot obtain the schema rowset "DBSCHEMA_TABLES_INFO" for OLE DB provider "SQLNCLI" for
linked server "<ServerName>". The provider supports the interface, but returns a
failure code when it is used.

查找Microsoft相关说明,有如下说明:

从 64 位 SQL Server 2005 客户端访问 32 位 SQL Server 2000 服务器可能会失败
若要从 64 位 SQL Server 2005 客户端对 32 位 SQL Server 2000 服务器进行分布式查询,则需要使用 SQL Server 2000 SP3 或更高版本。分布式查询包括对您使用 sp_addlinkedserver 以及 OPENROWSET 和 OPENQUERY 函数定义的链接服务器项的引用。另外,必须在 SQL Server 2000 SP3 和 SP4 服务器上手动升级系统存储过程(也称为目录存储过程)。

如果 32 位实例的 SQL Server 2000 上的目录存储过程的版本未更新为随此 Service Pack 发布的版本,您将收到以下错误消息:

 
"The stored procedure required to complete this operation could not be found on the server.
Please contact your system administrator."
Msg 7311, Level 16, State 2, Line 1
Cannot obtain the schema rowset "DBSCHEMA_TABLES_INFO" for OLE DB provider "SQLNCLI" for
linked server "<ServerName>". The provider supports the interface, but returns a
failure code when it is used.

 

若要解决此问题,则必须对 32 位实例的 SQL Server 2000 或 MSDE 运行该 Service Pack 的 instcat.sql 脚本。

继续看相关主题如下:

如果要解决这个问题,请在 32 位 SQL Server 2000 服务器上安装 SQL Server 2000 SP3 或 SQL Server 2000 SP4;然后,在 32 位 SQL Server 2000 服务器上手动执行 SQL Server 2000 SP3 或 SP4 随附的 Instcat.sql 脚本。

看了下这个脚本,包含了N多的系统表和过程。其实很多表和过程是没有变动的,这个问题是SQL Server 2000缺少过程:sp_tables_info_rowset_64

只需要创建该过程就ok了。

/*  Procedure for 8.0 server */ 
create procedure sp_tables_info_rowset_64 
    ( 
    @table_name sysname,  
    @table_schema   sysname = null,  
    @table_type nvarchar(255) = null  
    ) 
as 
    select  * 
    from    (select TABLE_CATALOG       = db_name(), 
            TABLE_SCHEMA        = user_name(o.uid), 
            TABLE_NAME      = o.name, 
            TABLE_TYPE      = convert(nvarchar(30), 
                            case o.type  
                            when 'U' then  
                                case when ObjectProperty(o.id, 'IsMSShipped') = 0 
                                then N'TABLE' else N'SYSTEM TABLE' end 
                            when 'S' then N'SYSTEM TABLE' 
                            when 'V' then  
                                case when ObjectProperty(o.id, 'IsMSShipped') = 0 
                                then N'VIEW' else N'SYSTEM VIEW' end 
                            end), 
            TABLE_GUID      = convert(uniqueidentifier, null), 
            BOOKMARKS       = convert(bit, 1), 
            BOOKMARK_TYPE       = convert(int, 1 /*DBPROPVAL_BMK_NUMERIC*/), 
            BOOKMARK_DATATYPE   = convert(smallint, 21 /*DBTYPE_UI8 */), 
            BOOKMARK_MAXIMUM_LENGTH = convert(int, 8), 
            BOOKMARK_INFORMATION    = convert(int, 0), 
            TABLE_VERSION       = convert(bigint, ObjectPropertyEx(o.id, 'objectversion')), 
            CARDINALITY     = x.rows, 
            DESCRIPTION     = convert(nvarchar(1), null), 
            TABLE_PROPID        = convert(int, null)  
     
        from    sysobjects o left join sysindexes x on o.id = x.id and x.indid in (0,1) 
        where   o.name = @table_name 
        and     o.type in ('U','V','S') 
        and permissions(o.id) <> 0) as t 
 
    where   (@table_schema is null or @table_schema = TABLE_SCHEMA) 
    and     (@table_type is null or @table_type = TABLE_TYPE) 
    order by 4, 2, 3 
create procedure sp_tables_info_rowset_64;2 
    ( 
    @table_schema   sysname = null,  
    @table_type nvarchar(255) = null  
    ) 
as 
    select  * 
    from    (select TABLE_CATALOG       = db_name(), 
            TABLE_SCHEMA        = user_name(o.uid), 
            TABLE_NAME      = o.name, 
            TABLE_TYPE      = convert(nvarchar(30), 
                            case o.type  
                            when 'U' then  
                                case when ObjectProperty(o.id, 'IsMSShipped') = 0 
                                then N'TABLE' else N'SYSTEM TABLE' end 
                            when 'S' then N'SYSTEM TABLE' 
                            when 'V' then  
                                case when ObjectProperty(o.id, 'IsMSShipped') = 0 
                                then N'VIEW' else N'SYSTEM VIEW' end 
                            end), 
            TABLE_GUID      = convert(uniqueidentifier, null), 
            BOOKMARKS       = convert(bit, 1), 
            BOOKMARK_TYPE       = convert(int, 1 /*DBPROPVAL_BMK_NUMERIC*/), 
            BOOKMARK_DATATYPE   = convert(smallint, 21 /*DBTYPE_UI8 */), 
            BOOKMARK_MAXIMUM_LENGTH = convert(int, 8), 
            BOOKMARK_INFORMATION    = convert(int, 0), 
            TABLE_VERSION       = convert(bigint, ObjectPropertyEx(o.id, 'objectversion')), 
            CARDINALITY     = x.rows, 
            DESCRIPTION     = convert(nvarchar(1), null), 
            TABLE_PROPID        = convert(int, null)  
     
        from    sysobjects o left join sysindexes x on o.id = x.id and x.indid in (0,1) 
        where   o.type in ('U','V','S') 
        and permissions(o.id) <> 0) as t 
 
    where   (@table_schema is null or @table_schema = TABLE_SCHEMA) 
    and     (@table_type is null or @table_type = TABLE_TYPE) 
    order by 4, 2, 3 

 

使用 Windows 验证模式
如果要使用「Windows 验证」模式升级 SQL Server 2000 的 32 位实例上的系统预存程序,请依照下列步骤进行:
以 SQL Server sysadmin 固定服务器角色成员的 Windows 帐户登入计算机。
单击 [执行],输入 cmd.exe,然后单击 [确定]。
在命令提示字符中输入下列其中一个命令,然后按下 ENTER:

对于预设实例
osql -E -S <LinkedServerName> -i <Location>\instcat.sql

对于具名实例
osql -E -S <LinkedServerName>\<InstanceName> -i <Location>\instcat.sql

注意<LinkedServerName>、<InstanceName> 和 <Location> 代表连结的服务器名称、实例名称以及含有 Instcat.sql 脚本的文件夹完整路径。根据预设,这个文件夹位于 C:\Program Files\Microsoft SQL Server\MSSQL\Install。

 

使用 SQL Server 验证模式
如果要使用「SQL Server 验证」模式升级 SQL Server 2000 的 32 位实例上的系统预存程序,请依照下列步骤进行:
使用任何 Windows 帐户登入计算机。
单击 [执行],输入 cmd.exe,然后单击 [确定]。
在命令提示字符中输入下列命令,再按下 ENTER 键:
对于预设实例
osql -U <AdminLogin> -P <AdminPassword> -S <LinkedServerName> -i <Location>\instcat.sql
对于具名实例
osql -U <AdminLogin> -P <AdminPassword> -S <LinkedServerName>\<InstanceName> -i <Location>\instcat.sql

因为对方数据库是人事系统,我想不太可能去要求他做什么动作;

太郁闷了,这不太可能吧!

因为时间紧,竟提出要求开发人员利用另一台暂时做中转,这不是办法!!!!!

于是进一步研究,终于成功
利用openqery语句也可以查询数据

SELECT * FROM OPENQUERY(<LinkedServerName>, 'select * from<DatabaseName>.<schema>.<ViewName>')

你可能感兴趣的:(sql,sql,windows,server,Microsoft,服务器,sqlserver)