Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Базы данных
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 30.07.2011, 18:43
delphicoding delphicoding вне форума
Активный
 
Регистрация: 04.07.2011
Сообщения: 206
Репутация: -461
Восклицание Странные баги в FB

Здравствуйте!

Возникло не сколько странных проблем с СУБД/БД никак не могу решить, может сможете что-то подсказать... IBExpert + FB2.5

1. Не воспринимает CASE, ругается на строке (!) Parsing error! Пробовал в конце каждой строки when ставить ";" без разницы. Переделал на IF всё сразу заработало.
Код:
begin
 case TYPE
  when 1 then a_shift=:shift (!)
  when 2 then b_shift=:shift
  when 3 then c_shift=:shift
 end
end
2. Из программы посылается запрос в БД ввиде списка через запятую номеров строк нужной таблицы (проверено список правильный, перед отправкой отображается в программе в тестовом поле), список разбивается в БД спец процедурой (процедура проверена вручную - список разбивается на таблицу):
Код:
create or alter procedure LIST_TO_VALUES (
    LST blob sub_type 1 segment size 80)
returns (
    ID varchar(100))
as
declare variable I integer = 1;
declare variable J integer = 1;
begin
  while (i <= char_length(lst)) do begin
    if (substring(lst from i for 1) = ',') then begin
      if (i > j) then
          id = trim(leading from substring(lst from j for i - j));
      else
        id = null;
      if (id is not null) then   suspend;
      j = i+1;
    end
    i = i+1;
  end
 
  if (i > j) then
      id = trim(leading from substring(lst from j for i - j));
  else
    id = null;
 
  if (id is not null) then   suspend;
end
Список обрабатывается двумя хранимыми процедурами в БД:
А. Первая совершает определённое действие над всем списком, корректировка данных в БД для строк из списка. Увы, почему-то обрабатывает только последний (!) номер из списка. Содержит конструкцию:
Код:
for
  select id from list_to_values (:list_value) into :id
  do < далее код обработки >
Б. Вторая процедура должна возвращать таблицу данных собранных из нескольких таблиц на основе номеров из списка. Увы, возвращает пустую таблицу только с названиями полей, но данных нет!
Код:
create or alter procedure RPR_OFFICES (
    LIST_ID NOTE_BLOB)
returns (
    "Компания" NAME,
    "Офис" NAME,
    "ОфисНомер" NUM)
as
begin
 for
 select
 c.company_name, o.name, o.number
 
 from
  list_to_values(:list_id) l
  left join offices o on l.id = o.office_id
  left join companies c on o.company_id=c.company_id
 
 order by 1,2,3
 into :"Компания", :"Офис", :"ОфисНомер"
 do begin
  suspend;
 end
end

Ковыряюсь над этими проблемами уже два дня не могу понять что неправильно... ?! Может СУБД работает в режиме старой версии типа FB1.0? Как это проверить в IBExpert???
Ответить с цитированием
  #2  
Старый 30.07.2011, 18:50
delphicoding delphicoding вне форума
Активный
 
Регистрация: 04.07.2011
Сообщения: 206
Репутация: -461
По умолчанию

PS Админам и модераторам - советую подкорректировать тег кода на форуме, чтобы в конце кода не добавлял лишние три пустые строки. Если сделано специально для отделения и одной строки хватит. Сейчас выглядит неаккуратно.
Ответить с цитированием
  #3  
Старый 30.07.2011, 21:10
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,020
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

1. CASE пишется так:
Код:
CASE 
  WHEN [BOOL CONDITION 1] THEN [DO SOMETHING 1]
  WHEN [BOOL CONDITION 2] THEN [DO SOMETHING 2]
  ...
  ELSE [DO SOMETHING ELSE]
END

Как не трудно заметить у тебя в WHEN не условие, а просто значение.
Соответсвенно надо писать что-то типа:
Код:
   WHEN MyField = 1 THEN a_shift = :shift

2. Есть подозрение, что вот так:
Код:
create or alter procedure LIST_TO_VALUES (
    LST blob sub_type 1 segment size 80)
returns (
    ID varchar(100))

У тебя возвращается не таблица, а именно одно значение. вообще не уверен, что в FB можно из сторки возвращать таблицу. И вооюще не понимаю, почему бы не сделать сразу вызов из клиента одного запроса на обработку всего списка через IN.
Ответить с цитированием
  #4  
Старый 30.07.2011, 22:15
delphicoding delphicoding вне форума
Активный
 
Регистрация: 04.07.2011
Сообщения: 206
Репутация: -461
По умолчанию

Цитата:
Как не трудно заметить у тебя в WHEN не условие, а просто значение.
Странно, вот там в примерах написано: http://www.firebirdsql.su/doku.php?id=case
Код:
  case sl.order_status
    when 'open' then 'открыт'
    when 'waiting' then 'в ожидании'
    when 'shipped' then 'отгруженный'
Аналогично написал я в своей процедуре. то есть писать в каждой строке параметр значение которого проверяется НЕ нужно!
Цитата:
У тебя возвращается не таблица, а именно одно значение.
Это невозможно, тк при ручной проверке прямо в БД этой процедуры например "1,2,3" на выходе получается табличка с одной колонкой и строками: [1][2][3]. То есть процедура при ручной проверке работает...
Ответить с цитированием
  #5  
Старый 31.07.2011, 13:06
delphicoding delphicoding вне форума
Активный
 
Регистрация: 04.07.2011
Сообщения: 206
Репутация: -461
По умолчанию

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

Проверил в БД все входящие данные, всё передано из программы верно.
Код:
   insert into "_TEST_TEMP" (TEXT) VALUES (:list_value); (1)
for
  select id from list_to_values (:list_value) into :id
  do
   insert into "_TEST_TEMP" (TEXT) VALUES (:id); (2)
    if (:status_id=5) then
      update Offices set OFFICE_STATUS_ID=5
      where OFFICE_ID=:ID;
    if (:status_id=3 or :status_id=4) then
      update Offices set OFFICE_STATUS_ID=3
      where OFFICE_ID=:ID;
Положим передаём список из 3х номеров "100,101,102"...
Главная процедура п.2.А получила весь список "100,101,102" (1), процедура разбиения списка п.2 разбила список и вернула таблицу (проверено вручную запросом и проверкой результата), после чего процедура п.2.А отработала (2) - согласно проверочной записе вставленной после слова "do" - 3 раза, тк при каждом цикле в тестовую таблицу добавлялись номера "100","101","102"... но в реальности данные изменились только у последней записи номер "102"!

Впечатление, что у конструкции функция корректировки записей работает после ВСЕХ циклов, а не в каждом цикле...

Или же наоборот - начинается цикл с конца списка и сразу после обработки первой в исполнении записи (последней в списке - "102") цикл работает вхолостую не корректируя нужные записи...

Подскажите что нужно скорректировать для этого...

Последний раз редактировалось delphicoding, 31.07.2011 в 13:21.
Ответить с цитированием
  #6  
Старый 31.07.2011, 14:32
delphicoding delphicoding вне форума
Активный
 
Регистрация: 04.07.2011
Сообщения: 206
Репутация: -461
По умолчанию

=== вопрос 1 решён только с использованием IF, CASE не принимает ни в каком виде! странно.
=== вопрос 2.А решён добавлением else в каждую строку.

По поводу вопроса 2.Б тоже нашёл где проблема - с процедурой в БД написанной в первом постинге всё в порядке, список просто не доходит до процедуры. Проблема в конструкции:
Код:
spDS1: TpFIBDataSet;
With spDS1 do begin
    close;
    Prepare;
    InsertSQL.Text:='insert into "_TEST_TEMP" (TEXT_BLOB, TEXT) VALUES (:list_id, 10)';
    Params[0].Value:=pList; (проверено, что pList содержит список)
    open;
end;
Процедура якобы выполняется, но ничего не происходит, возможно запрос просто не передаётся... что неправильно???

Последний раз редактировалось delphicoding, 31.07.2011 в 16:12.
Ответить с цитированием
  #7  
Старый 31.07.2011, 16:47
delphicoding delphicoding вне форума
Активный
 
Регистрация: 04.07.2011
Сообщения: 206
Репутация: -461
По умолчанию

Решён вопрос 2.Б!
Заработала такая конструкия:
Цитата:
With spDS1 do begin
Prepare;
spDS1.Params[0].Value:=pList;
Open;

=============================

Осталось лишь непонятно почему IBExpert+FB2.5 никак не хочет пропускать CASE ???
Ответить с цитированием
  #8  
Старый 31.07.2011, 21:56
Vocabulary Vocabulary вне форума
Новичок
 
Регистрация: 17.09.2009
Сообщения: 85
Репутация: 9
По умолчанию

Потому и "не пропускает", что после then не может быть присвоения.
Ответить с цитированием
  #9  
Старый 31.07.2011, 23:45
delphicoding delphicoding вне форума
Активный
 
Регистрация: 04.07.2011
Сообщения: 206
Репутация: -461
По умолчанию

Блин фигня то какая, а почему не может то?!
то есть в таком случае писать можно только через конструкцию:
Код:
IF TYPE=1 THEN a_shift=:shift; else
IF TYPE=2 THEN b_shift=:shift; else
IF TYPE=3 THEN c_shift=:shift; 
Криво как-то!
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 20:22.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter