我通过sp_addlinkedserver语句创建一个链接服务器"RemoteServer"
执行以下查询语句,返回值正常。
select * from RemoteServer.master.dbo.spt_values 
go
但执行如下查询语句,返回错误。
select *
from RemoteServer.BB_data.dbo.my_table
go
服务器: 消息 7356,级别 16,状态 1,行 1
OLE DB 提供程序 'MSDASQL' 为列提供的元数据不一致。执行时更改了元数据信息。
OLE DB 错误跟踪[Non-interface error: Column 'my_time' (compile-time ordinal 26) of object '"BB_data"."dbo"."my_table"' was reported to have a DBCOLUMNFLAGS_ISROWVER of 0 at compile time and 512 at run time]。
经过核对,是因为my_table中有一个字段名my_time,所使用的数据类型是timestamp型。
如果从表结构中删除这个字段,查询就不会报错了。
但问题是,我现在的数据库中,所有的表中都有加了一个timestamp型字段名my_time,这个字段主要是用于防止同一条记录同时被多用户更新而特别添加的字段,绝对不能删除的。请问如何解决这里查询报错的问题?

解决方案 »

  1.   

    --不同服务器数据库之间的数据操作
    --************************************************************************************
    1、--创建链接服务器 
    exec sp_addlinkedserver   'ITSV', ' ', 'SQLOLEDB', '远程服务器名或ip地址 ' 
    exec sp_addlinkedsrvlogin  'ITSV', 'false ',null, '用户名', '密码' 
    2、启动两台服务器的MSDTC服务 
    MSDTC服务提供分布式事务服务,如果要在数据库中使用分布式事务,必须在参与的双方服务器启动MSDTC(Distributed Transaction Coordinator)服务。3、打开双方的135端口
    MSDTC服务依赖于RPC(Remote Procedure Call (RPC))服务,RPC使用135端口,保证RPC服务启动,如果服务器有防火墙,保证135端口不被防火墙挡住。
    使用“telnet IP 135”命令测试对方端口是否对外开放。也可用端口扫描软件(比如Advanced Port Scanner)扫描端口以判断端口是否开放
    4、--如要创建触发器   
    create   trigger   t_test   on   test   
    for   insert,update,delete   
    as 
    --加上下面两句,否则会提示新事务不能登记到指定事务处理器
    set    xact_abort   on  
    begin  distributed   tran 
        delete   from   openrowset('sqloledb','xz';'sa';'',test.dbo.test)   
        where   id   in(select   id   from   deleted)   
        insert   into   openrowset('sqloledb','xz';'sa';'',test.dbo.test)   
        select   *   from   inserted   
    commit tran--查询示例 
    select * from ITSV.数据库名.dbo.表名 --导入示例 
    select * into 表 from ITSV.数据库名.dbo.表名 --以后不再使用时删除链接服务器 
    exec sp_dropserver  'ITSV ', 'droplogins ' 
      

  2.   

    不好意思贴错了
    你这个问题主要是你的字段名称和表明称一致造成的,你给个名称就不会了另外你要是字段名称 是表名的一部分也会出错最后啊建议使用OPENQUERY来执行你的sql 语句 而不是使用 服务器。数据库。架构名。表名的方法关于OPENQUERY  参考http://msdn.microsoft.com/zh-cn/library/ms188427.aspx
      

  3.   

    my_time字段和表名有重复的部分会导致报错,你把my_time改个名字试试
      

  4.   

    如果真改用OPENQUERY,OPENROWSET来改写这个语句的话,麻烦就大了。OPENQUERY,OPENROWSET的写法,太烦琐,对我讲,那简直是一场灾难。
    再说在这里只是针对含有timestamp型字段的表,查询才会报错,如果一个表中不含有timestamp型字段,查询完全是正常的,没有问题。难道就没有好的方法解决这个问题吗?
      

  5.   

    你可以换成guid来确保唯一性
    用uniqueidentifier类型 保存 用 SELECT NEWID() 取值IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]
    GO 
    CREATE TABLE [tb]([name] uniqueidentifier)
    INSERT [tb] SELECT NEWID()SELECT * FROM [tb]
      

  6.   

    OPENQUERY只能用于生成临时表吧,好象不能执行delete, update语句。select *
    from OPENQUERY(RemoteServer, 'SELECT * FROM hr_test.dbo.amt_bum where id_bum=99999') 
    go
    下面两句,执行时,都报错。
    OPENQUERY(RemoteServer, 'delete FROM hr_test.dbo.amt_bum where id_bum=99999') 
    goOPENQUERY(RemoteServer, 'update a set bum_bh=888 FROM hr_test.dbo.amt_bum a where id_bum=99999') 
    go
    错误如下:服务器: 消息 156,级别 15,状态 1,行 1
    在关键字 'OPENQUERY' 附近有语法错误。
      

  7.   

    我的想法哦:在源数据库建立一个view,my_table_view,然后你把需要的字段写出来,把timestamp字段转换成bigint字段,试试看吧!
      

  8.   

    另外你可以使用下面的语法delete   from   openrowset('sqloledb','xz';'sa';'',test.dbo.test)   
        where   ..........    insert   into   openrowset('sqloledb','xz';'sa';'',test.dbo.test)   
        select   *   from   ...............