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

时间:2018-08-23 22:33:44

标签: sql sql-server informix openquery

我正在尝试与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)

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

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

这看起来是正确的,但显然不是因为我在'08'附近收到语法错误。我在此上花费了更多的时间!任何和所有建议将不胜感激!

2 个答案:

答案 0 :(得分:2)

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]

结果是:

Results of above code

答案 1 :(得分:0)

@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)