Возможен ли такой запрос?

ЧАстые Вопросы и Ответы

Модераторы: kdv, CyberMax

Ответить
Leons
Сообщения: 29
Зарегистрирован: 24 фев 2006, 08:29

Возможен ли такой запрос?

Сообщение Leons » 05 фев 2007, 12:45

FireBird 1.5.3
ХП
Есть входной параметр Code. Через него передают значения следующего вида "1,2,10,15,20,21,22"

Нужно в таблице создать записи и в каждую из них вписать одно значение из Code в поле Value.

Возможно ли выйти из данной ситуации одним запросом? Или как решить данную проблему?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 фев 2007, 13:08

не вижу проблемы, как и "одного запроса". insert вставляет всегда только одну запись. Аминь.
если нужно разобрать параметры и выполнить нужное число insert - есть udf по разбору строк, циклы while и т.п.

Leons
Сообщения: 29
Зарегистрирован: 24 фев 2006, 08:29

Сообщение Leons » 05 фев 2007, 14:08

Вот откапал, вставка нескольких записей одним запросом)

Код: Выделить всё

insert into treader (rdnumb, rdname) 
   select cast(author as varchar(8)) || '-00', auname from 
tauthor 
   where auname<'Д';
Теперь осталось только правильно выбрать значения из Code

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 05 фев 2007, 15:30

Значит, ты сказал не всё, и Code = '1,2,10,15,20,21,22' не является собственно данными, вставляемыми в таблицу, а только фильтром для выборки из другой таблицы?
Тогда несложно. Правильно заданный вопрос - половина решения.

Leons
Сообщения: 29
Зарегистрирован: 24 фев 2006, 08:29

Сообщение Leons » 05 фев 2007, 15:49

Эти значения есть ID одной таблицы, но они в данном случае сохранаются как данные в иной таблице.

А фильтр уже сделал с вашей помощью) Выборка по такой строчке работает на ура

Slavik
Сообщения: 115
Зарегистрирован: 17 янв 2007, 11:52

Сообщение Slavik » 05 фев 2007, 19:00

Пример тела процедурки для разбора строки со списком целочисленных идентификаторов (символ разделителя не имеет значения):

Код: Выделить всё

while (CODE <> '') do begin
  while ((CODE <> '') and ('0123456789' not containing substring(CODE from 1 for 1)))
    do CODE = substring(CODE from 2 for 30000);
  S = '';
  while ((CODE <> '') and ('0123456789' containing substring(CODE from 1 for 1)))
  do begin
    S = S||substring(CODE from 1 for 1);
    CODE = substring(CODE from 2 for 30000);
  end
  if (S <> '') then begin
    ID = S;
    -- Делаем с очередным ID'шником то, что хотим...
    insert into MY_TABLE (ID) values (:ID);
  end
end
где S - varchar-переменная достаточной длины для хранения ID в текстовом виде.

У меня в базе есть одна такая универсальная процедура, которая возвращает из текстовой строки список идентификаторов (в примере заменить insert на suspend и ID сделать выходным параметром процедуры). Эту процедуру я соединяю с той таблицей, по которой надо сделать выборку. Тогда выборка идёт с использованием индекса.
Leons писал(а):...Выборка по такой строчке работает на ура
При select'е с помощью containing каждое значение ID желательно обрамить с обеих сторон нецифровыми символами, например, взять каждое значение в скобки или кавычки. И проверку делать с этими символами, например: '(1)(2)(10)(20)' containing '('||ID||')', тогда не нарвёшься на вхождение 1 в 21 и т.п. Сорри, если это замечание лишнее... :oops:

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 фев 2007, 19:19

на всякий случай - можно еще и с подобным способом что-нибудь сделать:
http://www.ibase.ru/ibfaq.htm#inparam

Leons
Сообщения: 29
Зарегистрирован: 24 фев 2006, 08:29

Сообщение Leons » 06 фев 2007, 09:51

Огромной респект) Вы меня выручили)

Ответить