如何在 Informix ESQL/C 的“使用”中动态提供值?
Posted
技术标签:
【中文标题】如何在 Informix ESQL/C 的“使用”中动态提供值?【英文标题】:How to provide values dynamically in "using" in Informix ESQL/C? 【发布时间】:2011-09-08 14:54:05 【问题描述】:我们的 Informix ESQL/C (.ec
) 程序使用查询:
select count(*) from <table> where col >= val1 and col <= val2
在我们使用的程序内部:
select count(*) from <table> where col >= ? and col <= ?
现在,新要求是我们需要根据值列表进行搜索。该列表是动态生成的,我们不确定列表的大小。如果列表包含 2 列,则查询将类似于:
select count(*) from <table> where ((col >= ? and col <= ?) OR (col >= ? and col <= ?))
我们能够构建查询,但我们不确定如何执行。
当前执行如下:
exec sql execute :select_prepare using :val1, :val2
我们有一个整数数组中的所有值。由于我们不确定参数的数量,所以我们在准备执行语句时陷入了困境。
下面的命令不起作用
exec sql execute :select_prepare using :val_array
谁能为此提供任何解决方案?
【问题讨论】:
【参考方案1】:这确实看起来很尴尬。 啊,乔纳森已经给出了明确的答案。但是,我的建议是左场替代方案。
您可以解决这个问题的一种方法是按照以下方式做一些事情:注意:未经测试,概念代码如下
CREATE TEMP TABLE ranges (
lo INT,
hi INT
);
for(..)
INSERT INTO ranges (?,?) USING :var1, :var2;
SELECT COUNT(DISTINCT id) FROM table, ranges WHERE col BETWEEN lo AND hi
/* later.. */
DROP TABLE ranges;
【讨论】:
我在考虑是否建议将其作为替代方案,并决定不建议。作为一种风格,最好使用更现代的 JOIN 表示法:SELECT COUNT(DISTINCT id) FROM Table AS t JOIN Ranges AS r ON t.col BETWEEN r.lo AND r.hi
.
另一方面,我很惊讶地看到一个您尚未回答的 ESQL/C 问题。我的答案写到一半,就在那里。就 SQL 风格而言?我能说什么,我是老派 ;-)
谢谢 Jonathan 和 RET,你们给了我足够多的选择。我将同时提出这两个建议,并将决定权留给架构师。【参考方案2】:
您将需要创建一个描述符 - 一个 sqlda
描述符(请参阅 DESCRIBE
和 sqlda.h
)或一个 SQL 描述符。我的倾向是说“使用sqlda
描述符更容易”,但是(再想一想)我不确定这是真的。
使用 SQL 描述符,您将使用:
ALLOCATE DESCRIPTOR
DEALLOCATE DESCRIPTOR
GET DESCRIPTOR
SET DESCRIPTOR
使用sqlda
,您可以使用 DESCRIBE 获取信息,也可以自己制造描述符。
无论如何,最终结果将是你写的:
EXEC SQL EXECUTE :select_prepare USING SQL DESCRIPTOR :name;
或
EXEC SQL EXECUTE :select_prepare USING DESCRIPTOR sqlda_info;
请注意在 sqlda_info
之前不包含冒号的语法奇怪。
如果您需要说明这些内容的代码,那么:
DBD::Informix(Perl 模块,主要是源文件dbdimp.ec
)使用 SQL DESCRIPTOR。
SQLCMD(原版,不是微软的 johnny-come-lately 版本)使用sqlda
。
在这两种情况下,搜索 DESCRIPTOR(大写)都会为您提供正确的方向。
(我注意到您仍然需要动态准备 SQL;除非您使用 @RET 建议的临时表,否则 SQL 的文本将根据您需要测试的范围数量而有所不同。)
【讨论】:
以上是关于如何在 Informix ESQL/C 的“使用”中动态提供值?的主要内容,如果未能解决你的问题,请参考以下文章