Как динамически указывать значения в «использовании» в Informix ESQL / C? - PullRequest
3 голосов
/ 08 сентября 2011

Наша программа 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

У нас есть все значения в целочисленном массиве.Поскольку мы не уверены в количестве параметров, мы застряли при подготовке оператора execute.

Команда ниже не сработала

exec sql execute :select_prepare using :val_array 

Может ли кто-нибудь предложить какое-либо решение для этого?

Ответы [ 2 ]

2 голосов
/ 09 сентября 2011

Это кажется очень неловким. Ах, Джонатан прибыл с окончательным ответом.Тем не менее, мое предложение - это альтернатива для левого поля .

Один из способов решить эту проблему - сделать что-то вроде этого: Примечание: непроверенный, концептуальный код следует

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;
2 голосов
/ 09 сентября 2011

Вам потребуется создать дескриптор - либо дескриптор sqlda (см. DESCRIBE и sqlda.h), либо SQL DESCRIPTOR.Я хотел сказать «проще использовать дескриптор 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 (исходный), а не версия Microsoft «Джонни пришедший в последнее время») использует sqlda.

В обоих случаях поиск DESCRIPTOR (заглавные буквы) дает вам сильные указатели в правильном направлении.

(Замечу, что вам все еще нужно динамически готовить SQL; если вы не используете временную таблицупредложенный @ RET , текст SQL будет варьироваться в зависимости от количества диапазонов, которые необходимо протестировать.)

...