MS SQL/OPENQUERY 调用 Informix -- 单引号太多?太少了?

MS SQL/OPENQUERY call to Informix -- too many single quotes? too few?

我正在尝试与来自 MS SQL 2016 数据库实例的外部 Informix 数据源通信以发出日期绑定查询。为此,我正在执行以下操作:

--enter code here
declare @date_string varchar(10)
set @date_string = '08/01/2018'
-- this statement works
SELECT * FROM OPENQUERY ([ExternalLinkedServer], 'SELECT FIRST 10 * FROM informix.anydetailtable');
-- this does not work
SELECT * FROM OPENQUERY ([ExternalLinkedServer], 'SELECT FIRST 10 * FROM informix.anydetailtable WHERE eventdatetime between TODAY and date(' + @date_string + ')' );

已编辑(自我回答):在 David Dubois 提醒 OPENQUERY 不接受变量后,这里是 解决方法:

enter code here
set @date_string = '''08/01/2018'''
declare @openquery nvarchar(4000), @TSQL nvarchar(4000), @LinkedServer nvarchar(4000)
SET @LinkedServer = '[ExternalLinkedServer]'
SET @OPENQUERY = 'SELECT * FROM OPENQUERY('+ @LinkedServer + ','''
SET @TSQL = 'SELECT count(*) FROM informix.anydetailtable WHERE eventdatetime between TODAY and date(' + @date_string + ')'')'
print @openquery+@tsql
EXEC (@OPENQUERY+@TSQL)

print @openquery+@tsql 的输出如下所示:

SELECT * FROM OPENQUERY([ExternalLinkedServer],'SELECT count(*) FROM informix.anydetailtable WHERE eventdatetime between TODAY and date('08/01/2018')')

这看起来是正确的,但显然不是因为我在“08”附近遇到语法错误。我在这上面花的时间比我应该花的多得多!任何和所有建议将不胜感激!

OpenQuery 的第二个参数必须是字符串常量。 你不能在这里放一个表达式。

但是你可以构建一个包含OpenQuery的字符串,然后执行那个字符串。

declare @q nvarchar(max)

declare @x nvarchar(200)

set @x = 'The Criterion'

set @q = QuoteName ( @x, '''' )

set @q = 'select BookID from Books where Title=' + @q

set @q = QuoteName ( @q, '''' )

set @q = 'select * from OpenQuery ( OracleServer, ' + @q + ')'

select @q

exec sp_executesql @q

计算报价可能会让开发人员感到沮丧。很容易弄错。

我在这个例子中演示了 QuoteName 以展示它在处理嵌入引号方面的作用。如图所示调用 QuoteName 会将引号添加到字符串的开头和结尾,但也会将嵌入字符串中的任何引号加倍。这意味着开发人员无需计算需要多少报价。让 SQL 为您完成。

create table Books ( BookID int, Title nvarchar(200) )

insert into Books ( BookID, Title ) values ( 381, 'Charlotte''s Web' )

declare @a nvarchar(200)
declare @b nvarchar(200)
declare @c nvarchar(200)
declare @d nvarchar(200)
declare @e nvarchar(200)

select top 1 @a = Title from Books

set @b = QuoteName ( @a, '''' )

select @a as [Title]

select @b as [Quoted Title]

set @c = 'select BookID from Books where Title=' + @b

set @d = QuoteName ( @c, '''' )

select @c as [Query]

select @d as [Quoted Query]

set @e = 'select * from OpenQuery ( OracleServer, ' + @d + ')'

select @e as [OpenQuery to be executed]

结果是:

@David Dubois 提供的方法是正确的,但是,对于任何寻求具体答案的人来说,这个方法是模糊的。这才是真正有效的。请记住要特别注意无数的单引号,以便传递文字值,例如日期。

    declare @openquery nvarchar(4000), @TSQL nvarchar(4000), @LinkedServer nvarchar(4000)
    SET @LinkedServer = '[ExternalLinkedServer]'
    SET @OPENQUERY = 'SELECT * FROM OPENQUERY('+ @LinkedServer + ','''
    SET @TSQL = 'SELECT count(*) FROM informix.anydetailtable WHERE eventdatetime between ' + '''''2018-08-27 00:00:00''''' + '' + ' and TODAY' + ''')'
    -- print @openquery+@tsql   -- use this to examine your query, comment out when it is working
    EXEC (@OPENQUERY+@TSQL)