--SQL中访问不同电脑上的数据库(远程只要联好网就一样)--如果经常访问或数据量大,建议用链接服务器--创建链接服务器
exec sp_addlinkedserver  'srv_lnk','','SQLOLEDB','远程服务器名或ip地址'
exec sp_addlinkedsrvlogin 'srv_lnk','false',null,'用户名','密码'
go--查询示例
select * from srv_lnk.数据库名.dbo.表名--导入示例
select * into 表 from srv_lnk.数据库名.dbo.表名go
--处理完成后删除链接服务器
exec sp_dropserver 'srv_lnk','droplogins'
--如果只是临时访问,可以直接用openrowset
--查询示例
select * from openrowset('sqloled'
,'sql服务器名';'用户名';'密码'
,数据库名.dbo.表名)
--导入示例
select * into 表 from openrowset('sqloled'
,'sql服务器名';'用户名';'密码'
,数据库名.dbo.表名)

解决方案 »

  1.   

    --SQL中的分布式事务使用示例--用触发器即时同步两个表的实例:--测试环境:SQL2000,远程主机名:xz,用户名:sa,密码:无,数据库名:test--创建测试表,不能用标识列做主键,因为不能进行正常更新
    --在远程主机上建表
    if exists (select * from dbo.sysobjects where id = object_id(N'[test]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [test]create table test(id int not null constraint PK_test primary key
    ,name varchar(10))
    go--以下操作在本机进行
    --在本机上建表及做同步处理的工作
    if exists (select * from dbo.sysobjects where id = object_id(N'[test]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [test]create table test(id int identity(1,1) primary key
    ,name varchar(10))
    go--创建同步的触发器
    create trigger t_test on test
    for insert,update,delete
    as
    set  XACT_ABORT on
    --启动远程服务器的MSDTC服务
    exec master..xp_cmdshell 'isql /S"xz" /U"sa" /P"" /q"exec master..xp_cmdshell ''net start msdtc'',no_output"',no_output--启动本机的MSDTC服务
    exec master..xp_cmdshell 'net start msdtc',no_output--进行分布事务处理,如果表用标识列做主键,用下面的方法
    BEGIN DISTRIBUTED TRANSACTION
    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
    go--插入数据测试
    insert into test
    select 1,'aa'
    union all select 2,'bb'
    union all select 3,'c'
    union all select 4,'dd'
    union all select 5,'ab'
    union all select 6,'bc'
    union all select 7,'ddd'--删除数据测试
    delete from test where id in(1,4,6)--更新数据测试
    update test set name=name+'_123' where id in(3,5)--显示测试的结果
    select * from test a full join
    openrowset('sqloledb','xz';'sa';'',test.dbo.test) b on a.id=b.id
      

  2.   

    使用SQL分布式事务的一般问题解决办法http://expert.csdn.net/Expert/topic/2835/2835706.xml?temp=.1959955
    回复人: j9988(j9988) 一.A.不用事务,关用SELECT 语句.是否可以分布式查询?   B.LINKSERVER 在做分布式更新事务时不能对本机操作.(就是不能环回分布式事务)   C.DBCC TRACEON (3604, 7300)--用跟踪看更详细错误信息.
      
       D.下载MS提供的DTCPing.exe 分装在两台机上,按README说明来运行它.看出错信息.
    http://download.microsoft.com/download/complus/msdtc/1.7/nt45/en-us/DTCPing.exe二.两台机的MSDTC是否都打开了.三.MSDTC设置是否正确.
    1.打开命令提示,运行"net stop msdtc",然后运行"net start msdtc"。
    2.转至"组件服务管理工具"。
    3.浏览至"启动管理工具"。
    4.选择"组件服务"。
     a.展开"组件服务"树,然后展开"我的电脑"。
     b.右键单击"我的电脑",然后选择"属性"。
     C.在 MSDTC 选项卡中,确保选中了下列选项: 网络 DTC 访问
    网络管理
    网络事务
        XA 事务
     e.另外,"DTC 登录帐户"一定要设置为"NT Authority\NetworkService"。
    5.单击"确定"。这样将会提示您"MS DTC 将会停止并重新启动。
      所有的依赖服务将被停止。请按'是'继续"。单击"是"继续。
    6.单击"确定"关闭"我的电脑"属性窗口。四.
    MSDTC依赖于RPC,RPC使用的端口是135,测试135端口是否打开.是否有防火墙?如果有先关了防火墙.
    telnet IP 135
    如果是关闭的打开它.五.
    有的机由于各种原因),SQLOLEDB不能使用分布式事务,更改为"MSDASQL" 的ODBC方式联接.
    使用RRAS而不是RAS.(控制面版--管理工具--远程服务管理器)
    Check whether you are using Remote Access Server (RAS) to access remote servers. If so, make sure that you have implemented Routing RAS (RRAS). Linked server does not work on RAS because RAS allows only one way communication.
    七.检查你的两台服务器是否在同一个域中.
    如果不在同一个域中,是否建立可信任联接.八.如果是WIN2000,升级到SP4九.升级MDAC到2.6以上,最好是2.8.
      

  3.   

    多谢,请问zjcxc(邹建):
    1,三.MSDTC设置是否正确.问题:在哪里设置?是SQL企业管理器中还是哪里?
    2,MSDTC依赖于RPC,RPC使用的端口是135,测试135端口是否打开.是否有防火墙?如果有先关了防火墙.问题:如何更改RPC?
    3,你的意思是要实现分布式管理是需要另外编程的?如果对于不同的用户同时访问同一数据,如何处理呢?
      

  4.   

    1. 我的电脑--控制面板--管理工具--服务--Distributed Transaction Coordinator--启动它,并将启动类型设置为自动启动2.当然也是在服务中:
    Remote Procedure Call (RPC)
    Remote Procedure Call (RPC) Locator3.不同用户同时访问同一数据库没有什么控制,SQL自己会管理.
      

  5.   

    当然,如果不同用户同时访问同一数据库.那你在程序设计时,就要注意你自己的业务处理逻辑.比如,业务单据的编号,一般是取最大号+1
    如果在单用户环境下,这个没什么问题,如果在多用户环境下,你就要考虑,如果你取出了最大号后,还没有保存,另一个用户又来取这个最大号,那么这两个用户生成的编号就会重复因为这个是属于你自己的业务处理,所以SQL对这种情况不会自动处理,就要求你自己控制了.
      

  6.   

    多谢,请问zjcxc(邹建) :业务处理逻辑?
      业务单据是否是支持多少用户同时访问的问题?那应该怎么确定最大号呢?
      如果取出了最大号,程序就不允许用户访问,这个不难实现。但如何随时刷新呢?比如说如果一个用户对一个数据进行修改了,另一个用户也在观察这个数据,如何让这个数据变化呢?因为第二个用户观察的数据是那个数据没有被修改前的状态。这个问题如何解决?
      请赐教!
      

  7.   

    --自己做编号,防止冲突的处理--处理示例1(用主键/唯一键)--得到最新编号的函数
    create function f_newid()
    returns char(7) --编号位数固定,用char的检索效率高于varchar
    as
    begin
    declare @re char(7)
    select @re=max(BHID) from 表 
    return(
    case when @re is null then 'BH00001'
    else 'BH'+right('0000'+cast(cast(right(@re,5) as int)+1 as varchar),5) 
    end)
    end
    go--测试的表,表名与函数中的表名对应
    create table 表(
    BHID char(7) default dbo.f_newid() --设置默认值,自动生成编号
    primary key,  --设置成主键,防止编号冲突
    -- constraint UNIQUE_BHID_表 unique, --如果用唯一约束,则删除上面的主键约束语句,改用此句
    txt1 varchar(10),
    txt2 varchar(10),
    num  float)
    go/*--插入数据时,就可以不理会编号字段,直接用这样的语句
    多用户同时插入时,如果编号重复,就会有错误发生
    此时,前台程序拦截错误,如果是违反约束的错误
    只需要重新执行插入的语句即可,此时的编号会自动再重新生成
    而重新执行插入语句也很方便,因为根本就不需要改语句
    --*/
    insert 表(txt1,txt2,num) values('aa','bb',1)go
    --删除测试
    drop table 表
    drop function f_newid
      

  8.   


    --处理示例2(用表级锁)--得到最新编号的函数
    create function f_newid()
    returns char(7) --编号位数固定,用char的检索效率高于varchar
    as
    begin
    declare @re char(7)
    select @re=max(BHID) from 表(tablockx) --加表级锁
    return(
    case when @re is null then 'BH00001'
    else 'BH'+right('0000'+cast(cast(right(@re,5) as int)+1 as varchar),5) 
    end)
    end
    go--测试的表,表名与函数中的表名对应
    create table 表(
    BHID char(7) default dbo.f_newid() --设置默认值,自动生成编号
    txt1 varchar(10),
    txt2 varchar(10),
    num  float)
    go--用事务/配合函数中的锁,就可以实现在插入时锁定表
    begin tran
    insert 表(txt1,txt2,num) values('aa','bb',1)
    commit trango
    --删除测试
    drop table 表
    drop function f_newid/*--关于两种方法:设置主键或唯一键的处理效率是最高的,因为在处理数据的同时,其他用户还可以浏览数据,如果不用主键或唯一键,就要用表级锁,而用表级锁,在锁定时,其他用户是不能做任何操作的,这样在多用户环境下,进程肯定容易堵塞,造成千军万马过独木桥的情况.
    --*/