2014-01-28 231 views
0

我有一个本地存储过程在远程链接服务器上调用另一个。问题是我的本地存储过程使用openquery来调用远程存储的proc并传递两个参数DATETIME通过openquery传递连接的日期时间参数

我能够成功调用远程存储过程的唯一方法是连接查询及其参数,然后使用sp_executesql - 注意RPC未在远程服务器上启用,它仅限制成功的方法。

问题是连接日期时间以将它们作为变量传递在远程过程中导致问题,该过程期望datetime params而不是nvarchar,这是串联正在进行的过程。

有没有办法解决这个问题?最后的办法是修改远程过程并让它接受nvarchar,然后立即将它们转换为datetime。由于远程过程在其他系统中使用,这不是一种可行的方法。

本地SP

ALTER PROCEDURE [dbo].[GetAttendanceReport] 
    @StartDate datetime, 
    @EndDate datetime, 
    @paramDef nvarchar(500) = N'@StartDate datetime, @EndDate datetime', 
    @query nvarchar(500) = null 
AS 
BEGIN 
    SET NOCOUNT ON; 

    set @query = N'select * from OPENQUERY([REMOTE-SRV], ''EXEC db.dbo.ReportAttendance_sp ' + convert(nvarchar(30), @StartDate, 112) + ',' + convert(nvarchar(30), @EndDate, 112) + ''')' 
    exec sp_executesql @query, @paramDef, @StartDate, @EndDate 
END 

远程SP

ALTER PROCEDURE [dbo].[ReportAttendance_sp] 
    @VenueID int = null, 
    @StartDate datetime = null, 
    @EndDate datetime = null, 
    @AttendanceStatusID int = null 
AS 
BEGIN 
... 

我通过以下PARAMS:

@StartDate = N'2011-01-01', 
@EndDate = N'2012-01-01' 

执行的SP我从一开始的错误远程SP:

将数据类型int转换为datetime时出错。

回答

1

您需要传递这些连接的参数,就好像它们是字符串一样。目前,它们看起来像整数,因为错误消息意味着 - 您需要将单引号加倍以将它们嵌入为字符串分隔符,然后再次,因为它们在动态SQL内。另外,没有理由为这些文字特别使用NVARCHAR,也不需要30个字符来表示样式112.您只需使用CHAR(8)。最后,如果你实际上没有将它们中的任何一个用作强类型参数(我认为你可以在动态SQL下与OPENQUERY结合使用),则不需要将参数传递给sp_executesql。所以:

SET @query = N'SELECT * from OPENQUERY([REMOTE-SRV], 
    ''EXEC db.dbo.ReportAttendance_sp ''''' + convert(char(8), @StartDate, 112) 
     + ''''',''''' + convert(char(8), @EndDate, 112) + ''''';'');'; 

EXEC sp_executesql @sql; 

(当然,你真的应该明确命名的参数,它至少可以保护你免受后来有人改变接口,例如,通过添加参数帕拉姆列表的开头。)

然而,这引出了一个问题,为什么不解决RPC问题,然后:

EXEC [REMOTE-SRV].db.dbo.ReportAttendance_sp @StartDate, @EndDate; 
+0

为什么IT部门去决定你是否可以在链接的服务器,这似乎是你的实际业务需求,执行存储过程这里? –

+0

我没有意识到启用RPC与在属性下将其设置为true一样微不足道。从现在起将是多么简单的事情:) – Lee