基于答案here,我已经开始测试SP,我计划最终建立多次调用,具有更多的临时表和不同的值#34;单元"参数。但是@BegDate,@ EndDate和@SortBy参数总是相同的 - 用户提供的那些。
这是我到目前为止所做的:
IF OBJECT_ID ( 'testSP', 'P' ) IS NOT NULL
DROP PROCEDURE testSP;
GO
CREATE PROC [dbo].[testSP]
@BegDate datetime,
@EndDate datetime,
@SortBy varchar(20)
AS
BEGIN
SELECT * FROM sys.databases
END
GO
sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO
SELECT * INTO #MyTempTable FROM OPENROWSET('SQLNCLI', 'Server=(local)\SQL2008;Trusted_Connection=yes;',
'EXEC SP2BCalled @Unit = "FirstUnit"; @BegDate = @BegDate; @EndDate = @EndDate; @SortBy = @SortBy; ')
SELECT * FROM #MyTempTable
我的问题:这是将params传递给现有存储过程(SP2BCalled)的正确方法:
'EXEC SP2BCalled @Unit = "Abuelos"; @BegDate = @BegDate; @EndDate = @EndDate; @SortBy = @SortBy; ')
IOW,被调用的SP需要将@BegDate,@ EndDate和@SortBy参数传递给它,所以新的SP会收集那些要传递的参数,但这样做的正确语法是什么?
我应该这样做:
CREATE PROC [dbo].[testSP]
@BegDateLocal datetime,
@EndDateLocal datetime,
@SortByLocal varchar(20)
...然后像这样调用现有的SP:
SELECT * INTO #MyTempTable1 FROM OPENROWSET('SQLNCLI', 'Server=(local)\SQL2008;Trusted_Connection=yes;',
'EXEC SP2BCalled @Unit = "FirstUnit"; @BegDate = @BegDateLocal; @EndDate = @EndDateLocal; @SortBy = @SortByLocal; ')
SELECT * INTO #MyTempTable2 FROM OPENROWSET('SQLNCLI', 'Server=(local)\SQL2008;Trusted_Connection=yes;',
'EXEC SP2BCalled @Unit = "SecondUnit"; @BegDate = @BegDateLocal; @EndDate = @EndDateLocal; @SortBy = @SortByLocal; ')
SELECT * INTO #MyTempTable3 FROM OPENROWSET('SQLNCLI', 'Server=(local)\SQL2008;Trusted_Connection=yes;',
'EXEC SP2BCalled @Unit = "ThirdUnit"; @BegDate = @BegDateLocal; @EndDate = @EndDateLocal; @SortBy = @SortByLocal; ')
......?或者怎么样?
然后我将需要UNION所有临时表(#MyTempTable1,#MyTempTable2和#MinTempTable3)并将其作为最终结果返回。
配置选项'显示高级选项'从0更改为1.运行RECONFIGURE语句进行安装。 配置选项' Ad Hoc Distributed Queries'从0更改为1.运行RECONFIGURE语句进行安装。 OLE DB提供程序" SQLNCLI11"对于链接服务器"(null)"返回消息"登录超时已过期"。 OLE DB提供程序" SQLNCLI11"对于链接服务器"(null)"返回消息"建立与SQL Server的连接时发生了与网络相关或特定于实例的错误。找不到服务器或无法访问服务器。检查实例名称是否正确以及SQL Server是否配置为允许远程连接。有关详细信息,请参阅SQL Server联机丛书。"。
答案 0 :(得分:3)
本地参数是否与要调用的过程的参数同名并不重要。所以你要求这两种方式没有区别。
重要的是你不应该用分号分隔参数。你应该使用逗号。
'EXEC SP2BCalled @Unit = ''FirstUnit'', @BegDate = @BegDateLocal, @EndDate = @EndDateLocal, @SortBy = @SortByLocal, ')
答案 1 :(得分:1)
据我所知,你赢了'能够直接将参数传递给OPENROWSET
调用。您需要创建一个动态SQL字符串并执行它,例如
DECLARE @SQL VARCHAR(MAX)
SET @SQL = 'SELECT * FROM OPENROWSET(''SQLNCLI'', ''DRIVER={SQL Server}; Server=127.0.0.1;'',''EXEC [Test].[dbo].[Test] @var1 = ' + @var1 + ''')'
EXEC(@SQL)
另外,根据提供的代码,
SELECT * INTO #MyTempTable FROM OPENROWSET(..
部分永远不会作为存储过程的一部分运行,因为有多个GO结束了定义。
您也没有指定要在OPENROWSET
中使用的数据库。
是否有使用OPENROWSET
的具体原因,而不是使用链接服务器的FQDN,[server].[database].[schema].[table]
?
答案 2 :(得分:1)
如果您知道返回的数据集的结构是什么,那么您可以使用以下内容:
-- Making assumptions about the data set
CREATE TABLE #MyTempTable1
(
Col1 int not null
,Col2 datetime not null
,ColEtc nvarchar(max) not null
)
INSERT #MyTempTable1 (Col1, Col2, ColEtc)
EXECUTE SP2BCalled
@Unit = 'Abuelos'
,@BegDate = @BegDate
,@EndDate = @EndDate
,@SortBy = @SortBy
答案 3 :(得分:1)
OPENROWSET
只接受文字字符串。要使用它,您需要在动态SQL中构建整个命令,然后exec
该命令。
在exec
内创建的临时表仅存在于exec
的范围内 - 它们在返回时会消失。
您可以使用全局临时表## MyTempTable1等,但如果多个用户同时调用它,它们将全部写入相同的全局临时表。
NEWID技巧使得一个独特的全局临时表可以避免这种情况,但是更难以管理。
使用双引号"
仅在远程服务器上SET QUOTED_IDENTIFIER
为OFF时有效。如果它为ON,则双引号中的任何内容都不会被视为字符串。
相反,它被视为对象名称,如列或表。
为避免担心这一点,请使用一对单引号''
来表示字符串中的单引号。但是,以这种方式处理嵌套引号确实令人难以置信。
您只需要将远程服务器配置为接受ad-hoc分布式查询一次,这样您就可以预先执行,而不是每次调用。
stackoverflow
是持有远程存储过程的数据库的名称。只需替换正确的名称即可。
Declare @Unit varchar(max) = 'FirstUnit', @BegDateLocal datetime = '01-jun-2016', @EndDateLocal datetime = '30-jun-2016', @SortBy varchar(max) = 'X'
Declare @sql nvarchar(max)
Declare @exec nvarchar(max) = 'EXEC stackoverflow.dbo.SP2BCalled @Unit = ''''FirstUnit'''', @BegDate = ''''' + convert(varchar(max), @BegDateLocal, 120) + ''''''
+ ', @EndDate = ''''' + convert(varchar(max), @EndDateLocal, 120) + ''''''
+ ', @SortBy = ''''' + @SortBy + ''''''
Declare @GlobalTemp varchar(max) = '##MyTempTable1'
Declare @GlobalTempNEWID varchar(max) = '[##' + cast(newid() as char(36)) + ']'
Declare @DropCheck varchar(max) = 'IF object_id(''tempdb..' + @GlobalTemp + ''') is not null drop table ' + @GlobalTemp
Set @sql = @DropCheck + '; SELECT * INTO ' + @GlobalTemp
+ 'FROM OPENROWSET(
''SQLNCLI'',
''Server=(local)\SQL2008;Trusted_Connection=yes;'','
+ '''' + @exec + ''')'
Print @sql
exec (@sql)
SELECT * FROM ##MyTempTable1