Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Уведомление


Страницы:   1 2

delphino ©   (2007-11-12 07:56:00) 

Есть две таблицы (клиенты и договора), связанные в отношении 1 ко многим (одному клиенту соответствует много договоров, т.е.срок договора заканчивается вносится другой договор и т.д.). Хочется, чтобы отслеживались срок окончания договоров и выдавалось уведомление за месяц до окончания.
Я сделала SQL выборку договоров таких, чтобы срок окончания попадал в интервал от Now-30 до Now. Проблема в том, что если пользователь вносит для какого-то клиента новый договор, то прежний договор продолжает попадать в этот интервал и программа соответственно продолжает выдавать уведомление об истекающем сроке договора.


ЮЮ   (2007-11-13 10:24:00) [1]

> [22] delphino   (13.11.07 10:15)

> [18] ЮЮ ©   (13.11.07 08:43)
> Тогда участок кода, формирующий запрос - в студию - ошибка
> может быть только там.


delphino   (2007-11-13 10:15:00) [2]


> А в таком, к конкретными константами, варианте работает?

Да если дату явно задавать - все работает.

> Проще Date() + 30 "вычислить" на клиенте, а в запросе упростить
> до
>  Max(CO.CO_End) BETWEEN 'xx.yy.zzzz' AND 'aa.bb.cccc'

Да нужна всего одна дата - текущая, я пробовала получить ее из DateTimePicker.Date - ошибка
Invalide use keyword
Почему не воспринимается обкавыченная дата, если ее вводить неявно, я думала в синтаксисе проблема?


Anatoly Podgoretsky   (2007-11-13 09:49:00) [3]

Увидел -30
Вычислить так IncMonth(Date) и соотношение меньше или равно заменить на меньше.


ЮЮ   (2007-11-13 09:38:00) [4]

> [19] Anatoly Podgoretsky ©   (13.11.07 09:24)


Этот запрос соответствует Max(CO.CO_End) BETWEEN '12.12.2007' AND '12.12.2007' + 30, а это 31 вариант вощможных значений.

Capability not supported возможно из-за использования переменых сразу трех типов в выражении
Max(CO.CO_End) -30<='12.12.2007'

Проще Date() + 30 "вычислить" на клиенте, а в запросе упростить до
 Max(CO.CO_End) BETWEEN 'xx.yy.zzzz' AND 'aa.bb.cccc'


Anatoly Podgoretsky   (2007-11-13 09:24:00) [5]

> delphino  (13.11.2007 06:58:17)  [17]

Во первых тебе Now совсем не нужен, получишь только ошибки выполнения запроса, а нужно DATE
А в запросе примени параметры, но твой запрос очень странный он даст результат только если есть дата строго равная 12.12.2007 00:00:00,000, допустим такая дата у тебя есть, но зачем де тогда дважды вычислят >= и <=, когда можно один раз и оператор =


ЮЮ   (2007-11-13 08:43:00) [6]

>Только вместо '12.12.2007' нужно подставить текущую дату.

А в таком, к конкретными константами, варианте работает?  Capability not supported только при формировнии строки? Тогда участок кода, формирующий запрос - в студию - ошибка может быть только там.

З.Ы. Клиентов - полных тезок нет и быть не может? Если могут быть, не мешает C.C_Code в группировку добавить


delphino   (2007-11-13 06:58:00) [7]

окончательно запрос выглядит так:

select C.C_Name, Max(CO.CO_End) MaxCoEnd
from contracts CO, clients C where C.C_Code=Co.C_Code
GROUP BY C.C_Name Having (Max(CO.CO_End) >='12.12.2007')  and (Max(CO.CO_End) -30<='12.12.2007')

Только вместо '12.12.2007' нужно подставить текущую дату.


ЮЮ   (2007-11-13 06:01:00) [8]

> Только один вопрос, как вместо ControlDate подставить значение
> Now?

Не надо вмест о, надо вмест е. Для float, string и datetime полей всяко лучше использовать параметры.
В тексте запроса оставить параметр :ControlDate, а перед открытием запроса проставлять параметру значение
Query.Params[0].asDateTime := Date(); // Now() ещё и время содердит, а оно тебе надо ???


> Capability not supported

Какой вариант выбрала? Как окончательно выглядит запрос?


delphino   (2007-11-13 05:10:00) [9]

ЮЮ спасибо огромное ты как всегда выручил!
Только один вопрос, как вместо ControlDateподставить значение Now?
Пробовала QuotedStr(FormatDateTime('dd.mm.yyyy ', Now))- выдает ошибку Capability not supported


ЮЮ   (2007-11-12 10:38:00) [10]

Select C_Code, Max(CO_End) FROM contracts GROUP BY C_Code HAVING Max(CO_End) + 30 < :ControlDate

Для любителей фильтровать: HAVING можно опустить и фильтровать на клиенте.

Поля из clients слелать Lookup-ными на клиенте.

Для желающих получить поля из clients и  contracts  в ожном запросе оформить local view, например

Select C_Code, Max(CO_End) MaxCoEnd FROM contracts GROUP BY C_Code

и тогда запрос примет вид

select
 C.C_Name, CO.CO_Begin, CO.CO_End
from
 "MaxCoEnds.sql" lastCo
 JOIN contracts CO On (CO.C_Code=lastCo.C_Code) And (CO.CO_End = lastCo.MaxCoEnd)
 JOIN clients C On C.C_Code=lastCo.C_Code
where
 lastCo.C_Code ...


Для любителей фильтровать: WHERE можно опустить и фильтровать на клиенте.


Anatoly Podgoretsky   (2007-11-12 10:25:00) [11]

> delphino  (12.11.2007 10:15:12)  [12]

Значит нужно дополнительное поле - номер нового договара, иначе никак не реализуешь задачу, да и удобнее работать с подобной структурой, можно просмотреть цепочки договоров.


delphino   (2007-11-12 10:15:00) [12]


> т.е. получается в определенный момент времени одному клиенту
> соответствует только один договор (текущий), хотя этому
> же клиенту принадлежит несколько договоров в таблице с договорами
> (истекшие договора ведь не удаляются???)???
>
> Если так, то я предположу, что раз в таблице есть дата истечения,
>  то есть и дата подписания???

Абсолютно верно! Причем номера нового и предыдущего договора не совпадают


delphino   (2007-11-12 10:14:00) [13]

Структура таблицы договора (paradox) такая:
1.CO_Code - ключ
2.CO_Number - номер договора (тип - Alpha)
3.CO_Year - год договора (Integer)
4.C_Code - ключ к таблице клиенты
5.CO_Begin - дата начала действия
6.CO_End - дата окончания действия

SQL -запрос: select C.C_Name, CO.CO_Begin, CO.CO_End from clients C, contracts CO where CO.C_Code=C.C_Code

И далее фильтрую Query:
Query1.Filter := Format('CO_End < %s', [QuotedStr(FormatDateTime('dd.mm.yyyy ', Now))])+' and '+Format('CO_End > %s', [QuotedStr(FormatDateTime('dd.mm.yyyy ', Now-30))]);

Хотя по идее это не очень правильно вместо Now-30 должно быть CO_End-30 (для того чтобы уведомление выдавалось за месяц до окончания).


mufan   (2007-11-12 10:08:00) [14]


> срок договора заканчивается вносится другой договор


т.е. получается в определенный момент времени одному клиенту соответствует только один договор (текущий), хотя этому же клиенту принадлежит несколько договоров в таблице с договорами (истекшие договора ведь не удаляются???)???

Если так, то я предположу, что раз в таблице есть дата истечения, то есть и дата подписания???


ЮЮ   (2007-11-12 09:59:00) [15]

> Я сделала SQL выборку договоров таких, чтобы срок окончания
> попадал в интервал от Now-30 до Now. Проблема в том,


Чтобы решать проблему, надо хотя бы запрос видеть.


Anatoly Podgoretsky   (2007-11-12 09:58:00) [16]


> А как их брать? Брать каждого клиента и проверять все договора?
>  Трудоемкая задача...

Я думаю что никак, но ты и не привела примера данных.
Например новый договор имеет новый номер или старый, если старый то возможно через группирование и функцию MAX, если новый то без связи никак.

> Это как? Ввести еще одно поле в таблицу договоров? Вряд
> ли это возможно, т.к.пользоватеди с программой уже работают

Недостаточно данных для ответа.


Sergey13   (2007-11-12 09:55:00) [17]

> [6] delphino   (12.11.07 09:50)
> А как их брать?

Учить SQL и брать.


delphino   (2007-11-12 09:50:00) [18]


> надо брать только последние договора клиента

А как их брать? Брать каждого клиента и проверять все договора? Трудоемкая задача...


> Проще всего ввести понятие продление договора или замена
> новым договором, тогда запрос будет простой Date < and not
> new contract

Это как? Ввести еще одно поле в таблицу договоров? Вряд ли это возможно, т.к.пользоватеди с программой уже работают


Anatoly Podgoretsky   (2007-11-12 09:40:00) [19]

Это тоже не верно, надо брать только те договора, у которых нет продления, у клиента много договоров, у части срок уже закончился, у части еще нет, осталось менее месяца и нет продление. Проще всего ввести понятие продление договора или замена новым договором, тогда запрос будет простой Date < and not new contract
В данном поле просто писань новый номер, если заключается новый договор или тот же самый если продляется


Sergey13   (2007-11-12 09:24:00) [20]

> [3] delphino   (12.11.07 09:19)
> Да ошибки нет.

Нет ошибки синтаксиса. Но раз результат работы программы неправильный - там ошибка. Например ты берешь просто все договора, а надо брать только последние договора клиента.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо