Opendatasource函数不接受变量做为参数的问题

makel 2006-06-29 12:35:57
对于opendatasource的调用,我们可以直接作为数据源处理
如:select * from opendatasource(........)
但是opendatasource的参数不能是变量,只能是字符串
而实际情况中我的远端服务器的信息是不定的,这次可能调用这台远端服务器上的,而下次就可能调用另一台服务器上的,这些信息我都保存在一张表中,动态来获取.
因此只能将这些信息先合成一个字符串,然后再通过exec来调用
如:exec('select * from opendatasource(''SQLOLEDB'','''+@DBstr+''')'+@DBname+'')....
这样调用可以成功,但是却不能将exec的执行结果作为数据源来处理,
如:select * from exec(.........)

报错
服务器: 消息 156,级别 15,状态 1,行 1
在关键字 'Exec' 附近有语法错误。

请问有什么方法可以解决这种问题吗?
...全文
468 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
makel 2006-07-03
  • 打赏
  • 举报
回复
。。。。。。。。。。。

是个好办法,不过感觉事情变得越来越复杂了。。。。。 ^_^
lzhs 2006-07-03
  • 打赏
  • 举报
回复
呵呵。
你的要求是这样的嘛 :)
makel 2006-06-30
  • 打赏
  • 举报
回复
现在我的问题是需要执行远端服务器上的存储过程,该存储过程执行一系列复杂的操作,然后取得返回结果.
本想用openrowset的,但是因为存储过程中的操作较多,用openrowset取不到返回值,我的做法是用opendatasource调用远端存储过程,将执行结果存入一张物理的临时表内,然后在用openrowset来获取远端服务器上该表的内容.
功能基本上都实现了,现在最大的问题是分布式事务不支持嵌套调用,又无法获取opendatasource调用的存储过程执行过程中的错误信息,也就是说捕捉不到远端存储过程执行过程中的错误信息.
以至当有错误发生时不能执行相应的操作,这个有什么办法解决么?
lzhs 2006-06-30
  • 打赏
  • 举报
回复
。。。

觉得可以再添加一张物理的临时表Table2:
远端存储过程在执行前,先清空Table2中的数据,出错的时候,就往Table2中写入一些信息。

本地在读取“opendatasource调用远端存储过程,将执行结果存入一张物理的临时表内”这张临时表之前,先读取Table2中的信息。进行一定的判断 。。。
LouisXIV 2006-06-29
  • 打赏
  • 举报
回复
貌似表变量还不能用在sp_excutesql上^^;
LouisXIV 2006-06-29
  • 打赏
  • 举报
回复
简单点的还是直接写入一张新表好了^^
fcuandy 2006-06-29
  • 打赏
  • 举报
回复
表变量总是需要定义结构的,对于opendateasource来说,这个结构不一定知道,,,总之比较麻烦.
fcuandy 2006-06-29
  • 打赏
  • 举报
回复
exec ('select * into newtable from opendatasource(.....)')
先写到一个新表中,用完后再DROP吧。
LouisXIV 2006-06-29
  • 打赏
  • 举报
回复
用系统存储过程sp_excutesql将结果集输出至表变量,

再以表变量为源做查询
lzhs 2006-06-29
  • 打赏
  • 举报
回复
。。。
这样做也不是最好的办法。
因为OpenDataSource和Insert Into操作可以会引发分布式事务,而这一块SQL Server处理的非常不好。

建议不要用OpenDataSource。

改用定义一个@Sql NVarchar(2000)
Set @Sql = 'Select * From ' + @Server + '.' + @Db + '.dbo.' + @Table
然后
Insert Into #Temp Exec(@Sql)

当然,要求先建好#Temp表
lzhs 2006-06-29
  • 打赏
  • 举报
回复
如果己经知道数据源返回的结果的列,而且这些列是确定的话。
可以先建一个临时表#Temp,然后用
Insert Into #Temp
Exec('select * into newtable from opendatasource(.....)')
makel 2006-06-29
  • 打赏
  • 举报
回复
恩,这样说来,还是得用物理表,弄两个标识位
fcuandy 2006-06-29
  • 打赏
  • 举报
回复
注意,最好在EXEC的语句里加上一句,你要生成的新表的表名是否已在当前库中存在。若存在则删除。 否则会出错。
不过也会有问题,如果几个地方同时执行了 EXEC ...
比如 A 刚执行生成了NewTable,还未来得及对NewTable进行查询或其它处理时,B也执行了EXEC,此时A对NewTable操作时,就没有表,或者看到的是 按B的条件 获得的那个 NewTable.

也就是并发时会有问题。
makel 2006-06-29
  • 打赏
  • 举报
回复
我还是建个临时表试试先
谢谢各位大大 ^_^

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧