对引用的项目使用 Open Query

Use Open Query with quoted items

我正在尝试使用 openquery 访问链接服务器。但是,这似乎是不可能的,因为您无法获得正确数量的单引号。我需要传递一个变量开始和结束日期,所以我不能使用基本的 openquery 方法,而必须使用 EXEC(@OPENQUERY+ @SQL) 方法。问题是,要通过 @SQL 变量传递日期,我必须使用 ''' 所以它有 1 个引号,但是当它传递给 EXEC(OPENQUERY+@SQL) 打开查询时这引入了另一个级别的引号,导致现在不引用日期并且我收到错误消息。如果我添加另一层引号,则会导致它们成为导致该错误的双引号。不能在打开的查询中使用引号吗?我有同样的问题,甚至传递像 Where Username = 'Jack' 这样的东西。我永远无法获得正确数量的引号。

DECLARE @STARTDT NVARCHAR(10) = '2019-01-01'
        ,@ENDDT NVARCHAR(10) = '2019-03-01'

DECLARE @SQL NVARCHAR(4000)
DECLARE @OPENQUERY nvarchar(4000)
        , @LinkedServer nvarchar(4000)

SET @LinkedServer = 'ProductionSvr'

SET @SQL =
'select  *
from SalesData a
where a.Sale_date between ''' + @StartDt + ''' and ''' + @ENDDT + ''')
'''

print @SQL

SET @OPENQUERY = 'SELECT * FROM OPENQUERY('+ @LinkedServer + ','''

EXEC (@OPENQUERY+@SQL)

这个怎么样:

DECLARE @STARTDT NVARCHAR(10) = '2019-01-01'
        ,@ENDDT NVARCHAR(10) = '2019-03-01'

DECLARE @SQL NVARCHAR(4000)
DECLARE @OPENQUERY nvarchar(4000)
        , @LinkedServer nvarchar(4000)

SET @LinkedServer = 'ProductionSvr'

SET @SQL =
'SELECT * FROM OPENQUERY(' + @LinkedServer + ',''select  *
from SalesData a
where a.Sale_date between ''' + @StartDt + ''' and ''' + @ENDDT + ''')'

print @SQL

您只需要记住 引号内,双单引号表示 1 个单引号。所以,''')' 本质上翻译为“')”。希望这有帮助。

在带引号的字符串中,您必须用一个额外的单引号转义一个单引号,这是您开始看到连续四个和五个单引号的地方。为了帮助简化事情,我会提出一些建议。

首先,让您的字符串在职责上更加分离。您的 @SQL 变量包含 OPENQUERY 必要的结尾标点符号,但开头标点符号在 @OPENQUERY 变量中。 (这在下面的代码中可能会更清楚。)

此外,我建议使用适当的数据类型(例如您的日期),然后使用 CONCAT 函数,它可以方便地为您处理所有数据类型转换。

因此,您开始时的修改版本如下所示:

DECLARE @OPENQUERY nvarchar(4000)
      , @LinkedServer nvarchar(256)
      , @SQL NVARCHAR(4000);

--Set your dates. Use the right data type to avoid sending 
--invalid dates into your query. Easier to debug them here.
DECLARE @STARTDT DATE = '2019-01-01'
        ,@ENDDT DATE = '2019-03-01';

--Set your server.
SET @LinkedServer = 'ProductionSvr';

--Then set up the inner query.
SET @SQL =
CONCAT(
'select  *
from SalesData a
where a.Sale_date between ''', @StartDt, ''' and ''', @ENDDT,'''');

--Set up the OPENQUERY variable with all of the punctuation that it needs,
--so you just need to drop in your LinkedServer name and your SQL statment.
--Use CONCAT because it handles the data type conversions for you.
SET @OPENQUERY = CONCAT('SELECT * FROM OPENQUERY(',@LinkedServer,',''(',@SQL,')'')');

PRINT @OPENQUERY;

结果:

SELECT * FROM OPENQUERY(ProductionSvr,'(select  *
from SalesData a
where a.Sale_date between '2019-01-01' and '2019-03-01')')