通过openquery传递连接的datetime参数

时间:2014-01-28 16:53:10

标签: sql sql-server-2008

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

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

问题是连接日期时间以便将它们作为变量传递会导致远程proc中出现问题,而远程proc期望datetime参数不是nvarchar,这就是串联正在进行的操作。

这有什么办法吗?最后一种方法是修改远程proc并让它接受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
...

我通过以下参数:

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

执行SP我从远程SP获取错误:

  

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

1 个答案:

答案 0 :(得分:1)

你需要传递那些连接的参数,就好像它们是字符串一样。目前,它们看起来像int,正如错误消息所暗示的那样 - 您需要将单引号加倍,将它们嵌入为字符串分隔符,然后再次,因为它们位于动态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;