2010-03-15 1 views
3

В качестве части моих заданий мне нужно написать SQL-запросы для подключения к нашей базе данных PI. Чтобы сгенерировать запрос, мне нужно передать массив тегов (по существу первичных ключей), но они должны быть вставлены в виде строк.Заполнитель SQL в WHERE IN проблема, вставленные строки сбой

Поскольку это будет модульный запрос и используется для нескольких тегов, используется заполнитель.

Запрос основывается на использовании WHERE IN заявление, которое когда заполнитель, как показано ниже:

SELECT SUM(value * 5/1000) as "Hourly Flow [kL]" 
    FROM piarchive..pitotal 
WHERE tag IN (?) 
    AND time between ? and ? 
    AND timestep = '1d' 
    AND calcbasis = 'Eventweighted' 
    AND value <> '' 

Вопрос формат, в котором метки должны быть переданы в качестве. Если добавить их непосредственно в запрос (для тестирования), они идут в формате (это номер примеров): '000000012','00000032','005050236','4560236' и запрос выглядит следующим образом:

SELECT SUM(value * 5/1000) as "Hourly Flow [kL]" 
    FROM piarchive..pitotal 
WHERE tag IN ('000000012','00000032','005050236','4560236') 
    AND time between ? and ? 
    AND timestep = '1d' 
    AND calcbasis = 'Eventweighted' 
    AND value <> '' 

... который работает.

Если я попытаюсь добавить те же теги в заполнитель, запрос не удастся. Если я добавляю только 1 тег, без кавычек (с использованием заполнителя), запрос работает.

Почему это происходит? Во всяком случае, вокруг?

+0

Для какой базы данных? В предложениях Dynamic IN требуется использовать динамический SQL или функцию для преобразования предложения IN в таблицу для присоединения к. –

+0

Это для базы данных PI, от OSIsoft. На самом деле это не реляционная БД, но драйвер OLEDB позволяет использовать обычный SQL –

+0

@Alistair Pitts: если в PI нет встроенной поддержки динамического SQL, вы можете построить запрос как строку на любом используемом вами языке приложения. –

ответ

1

Мы допросили поставщика и получили этот ответ, который позволяет нам передавать группу тегов, разделенных запятыми.

select * 
from pitotal 
where tag IN (SELECT tag from pipoint WHERE INSTR(?, tag) <> 0) and time between 'y' and 't' 

В основном, производя кучу строк сравнения.

Надеюсь, это кому-то полезно

1

Когда вы пытаетесь поместить все числа в заполнитель, это рассматривается как одна строка, а не как список элементов, разделенных запятыми. Итак, если у вас не будет значения в вашей таблице, которое точно соответствует этой «строке», оно никогда не будет работать.

Растворы либо использовать заполнитель для каждый элемент, который нужно соответствовать (три предмета, три заполнители, примеры), или, не использовать заполнитель и, вместо этого, сцепить весь SQL строка и выполнить. (Конечно, это не рекомендуется из-за возможности SQL-инъекции).

+0

Да, это было то, чего я боялся. К сожалению, SQL является статическим, и я не могу его динамически строить, когда это необходимо. И количество тегов будет меняться, и это то, что я надеялся обойти там, где –

1

Я столкнулся с этой проблемой ранее в нашем решении для отчетов, где пользователь хотел иметь возможность вводить до 5 значений в независимых элементах раскрывающегося списка. Эти элементы управления были заполнены возможными значениями и значением NULL, означающим «не использовать» (первый элемент управления не разрешал NULL, так как у вас есть верхний выбор один возможность как минимум).

Наш запрос имеет фрагмент (переведенный к вашей ситуации):

WHERE tag IN (?,?,?,?,?) 

Затем, когда мы устанавливаем местоблюститель, мы присвоили значения из раскрывающихся их соответствующего места держателя с одним Оговорка: если в раскрывающемся списке содержится NULL, мы заполнили место с содержимым первого раскрывающегося списка.

Таким образом, если вы входите 7,3,1,8,9, вы в конечном итоге с:

WHERE tag IN (7,3,1,8,9) 

Если вы входите 7,NULL,1,NULL,9, вы получите:

WHERE tag IN (7,7,1,7,9) 

и так далее. СУБД, которую мы использовали, достаточно умен, чтобы свернуть операторы IN до их наиболее эффективной формы, прежде чем выполнять их, чтобы не было реального наказания за это. Ваш пробег может отличаться.

Одна из проблем с этим kludge заключается в том, что вы должны установить верхнюю границу числа возможных записей в предложении IN, но это не проблема в нашей ситуации.