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