Использовать открытый запрос с цитируемыми элементами - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь использовать openquery для доступа к связанному серверу. Однако это кажется невозможным, потому что вы не можете иметь правильное количество одинарных кавычек. Мне нужно передать переменные даты начала и окончания, поэтому я не могу использовать метод openquery basi c, а вместо этого должен использовать метод EXE C (@ OPENQUERY + @ SQL). Проблема в том, что для передачи даты через переменную @ SQL я должен использовать '' ', чтобы она имела 1 кавычку, но затем, когда она передается в EXE C (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)

Ответы [ 2 ]

0 голосов
/ 24 февраля 2020

Внутри строки в кавычках вы должны экранировать одинарную кавычку с дополнительной одинарной кавычкой, в которой вы начинаете видеть четыре и пять одинарных кавычек подряд. Чтобы упростить вещи, я бы сделал пару предложений.

Во-первых, держите свои струны более разделенными в своих обязанностях. Ваша переменная @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')')
0 голосов
/ 24 февраля 2020

Как насчет этого:

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 одинарную кавычку . Таким образом, '' ')' по сути переводится как "')". Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...