Модераторы: Akella
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите написать триггер или UDF, [Firebird 2.0] 
V
    Опции темы
Urvin
Дата 11.2.2008, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 1.6.2006

Репутация: нет
Всего: нет



Если честно, даже не знаю в какую сторону смотреть....

Суть: заказы в базе данных помимо собственного ID имеют более гуманный "номер",
составляющийся из цифр текущего года, месяца и порядкового номера заказа
в этом месяце вида ММГГ-ННН.

т.е. Например, за последние два месяца заказы могут выглядеть так:
0108-001 // январь
0108-002
0108-003
0108-004
0208-001 // февраль пошел
0208-002
0208-003
...

Хотелось бы, чтобы при добавлении нового заказа автоматически на стороне СУБД
генерировался не только ID, но и этот номер заказа.

Подскажите, как реализовать данную хотелку?

На дельфях функцию NextNumber(PreviousNumber: string) реализовал.
PM MAIL   Вверх
Urvin
Дата 11.2.2008, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 1.6.2006

Репутация: нет
Всего: нет



Я сделал библиотечку на Delphi:
Код

library v_number;

uses
  SysUtils,
  DateUtils,
  Classes;

{$R *.res}
// Добавление ведущих нулей
function AddNill(value: integer; digs: integer): string;
begin
  result:=IntToStr(value);
  while length(result) < digs do begin
    result:= '0' + result;
  end;
end;

// главная функция - возвращает следующий номер в зависимости от предыдущего
procedure Next_Number(OldNumber, NewNumber: PChar); cdecl export;
var
  LfNumber,NewN: string;
begin
  LfNumber:= AddNill(MonthOf(Now),2) + Copy(IntToStr(YearOF(now)),3,2);
  if LfNumber <> Copy(OldNumber,1,4) then
    NewN:='000'
  else
    NewN:=Copy(OldNumber,6,length(OldNumber)-5);

  NewN:=LfNumber + '-' + AddNill(StrToInt(NewN)+1,3);

  NewNumber:=PChar(NewN);
end;


exports
  Next_Number;
begin
  isMultiThread:=True;
end.


Cкомпилировал в v_number.dll, которую кинул её в .../firebird_2_0/UDF

В базу добавил так:
Код

DECLARE EXTERNAL FUNCTION Next_Number
    CSTRING(10), CSTRING(10)
    RETURNS PARAMETER 2
ENTRY_POINT 'Next_Number'  MODULE_NAME 'v_number'


и даже написал триггер:
Код

CREATE OR ALTER trigger bef_ins_ord for orders
active before insert position 0
AS
    declare variable oldn varchar(10);
begin
    if (new.cid is null) then
        new.cid=gen_id(gen_ord,1);
    if (new.cnumber1 is null) then begin
        SELECT cnumber1
        FROM orders
        WHERE cid = (SELECT MAX(cid) from orders)
        into :oldn;

        new.cnumber1=Next_Number(:oldn);

    end
end



К сожалению, оно даже не работает с запросом
Код
select Next_Number(cnumber1) from orders where cid=1;



Где я наврал?

Это сообщение отредактировал(а) Urvin - 11.2.2008, 22:20
PM MAIL   Вверх
Urvin
Дата 11.2.2008, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 1.6.2006

Репутация: нет
Всего: нет



Код

library v_number;

uses
  SysUtils,
  DateUtils,
  Classes,
  ib_util in 'C:\Program Files\Firebird\Firebird_2_0\include\ib_util.pas';

{$R *.res}
// Добавление ведущих нулей
function AddNill(value: integer; digs: integer): string;
begin
  result:=IntToStr(value);
  while length(result) < digs do begin
    result:= '0' + result;
  end;
end;



// главная функция - возвращает следующий номер в зависимости от предыдущего
function Next_Number(OldNumber: PChar):PChar; cdecl export;
var
  LfNumber,NewN: string;
begin
  LfNumber:= AddNill(MonthOf(Now),2) + Copy(IntToStr(YearOF(now)),3,2);
  if LfNumber <> Copy(OldNumber,1,4) then
    NewN:='000'
  else
    NewN:=Copy(OldNumber,6,length(OldNumber)-5);

  NewN:=LfNumber + '-' + AddNill(StrToInt(NewN)+1,3);

  Result := ib_util_malloc(Length(NewN) + 1);
  StrPCopy(Result, NewN);
end;

exports
  Next_Number;
begin
  isMultiThread:=True;
end.


Код

DECLARE EXTERNAL FUNCTION NEXT_NUMBER
    CSTRING(10)
RETURNS CSTRING(10) FREE_IT
ENTRY_POINT 'Next_Number' MODULE_NAME 'v_number';



простите, был напуган

Это сообщение отредактировал(а) Urvin - 11.2.2008, 23:45
PM MAIL   Вверх
Akella
Дата 12.2.2008, 01:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



почитай про extract и про Copy

Добавлено через 13 минут и 55 секунд
сеглдня лень тебе написать процедуру, напомни завтра в PM, постараюсь дать код  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Interbase"
Alex

Обязательно указание:

1. Версию InterBase (Firebird, Yaffil)

2. Способа доступа (ADO, BDE, IBX и т.д.)

  • КАК ПРАВИЛЬНО ОФОРМИТЬ КОД - ЗДЕСЬ
  • КАК ПРАВИЛЬНО УКАЗАТЬ ТЕКСТ ОШИБКИ - ЗДЕСЬ
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • FAQ раздела лежит здесь!

Если Вам понравилась атмосфера форума, заходите к нам чаще! С Уважением, Akella.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Firebird, Interbase | Следующая тема »


 




[ Время генерации скрипта: 0.0689 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.