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

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

Функция в MSSQL2000 [D7, XP]


Страницы:   1 2

deras ©   (2008-05-30 01:34:00) 

Описание. Есть таблица: ID, ContrNum (int), Name
Задача.
Создать функцию, которая возвращает номер контракта (ContrNum = ID + 100000), предварительно проверив, нет ли такого номера контр. в таблице.

Спасибо


ANB   (2008-05-30 19:22:00) [1]


> Нумеровать документы вообще и контракты в частности - преррогатива
> того, кто занимается делопроизводством и не целесообразно
> (а часто даже категорически нельзя) вычислять их программно.
>  
> Как Ваша система "плюс один" будет работать если, к примеру,
>  все документы с нового года нумеруются заново с единицы
> ? А бывает, что в номере документа присутствуют год и даже
> месяц.
> Контракт не вводится сразу в комп, он сначала готовится
> (например, в ворде), потом подписывается, штампуется, регистрируется
> в делопроизводстве. И только после этого вводится "с бумаги"
> как готовый документ в БД
> Очевидно, "тетенька" попросила Вас сделать ей хорошо, не
> представляя себе как это "хорошо" плохо в действительности.
>

Насчет нумерации - согласен, что это более хитрая штука, чем ПК.
Но :
1. Почему запрет на генерацию документов програмно ? Есть продукты, которые целые пакеты документов сами генерят. Для того и предназначены.
2. А уж если в организации документы генерятся автоматизированно, за каким их ручками в журнале нумеровать ? Почему бы не попросить это сделать программу ? А заодно вести и электронный журнал документов.

ЗЫ. Кистате, у нас как раз документы автоматически нумеруются. И мона настраивать период нумерации (т.е. раз в год, месяц, неделю, день начинать с 1)


Ega23   (2008-05-30 18:41:00) [2]


> а, ну... если в плане существования триггеров рассматривать,
>  то конечно твоя правда...


Ну реально в данный момент их может и не быть. Но потом бах - и появятся. Так что лучше сразу соломки подстелить...


Palladin   (2008-05-30 18:39:00) [3]

а, ну... если в плане существования триггеров рассматривать, то конечно твоя правда...


Ega23   (2008-05-30 18:19:00) [4]


> чем?


SCOPE_IDENTITY and @@IDENTITY will return last identity values generated in any table in the current session. However, SCOPE_IDENTITY returns values inserted only within the current scope; @@IDENTITY is not limited to a specific scope.

For example, you have two tables, T1 and T2, and an INSERT trigger defined on T1. When a row is inserted to T1, the trigger fires and inserts a row in T2. This scenario illustrates two scopes: the insert on T1, and the insert on T2 as a result of the trigger.

Assuming that both T1 and T2 have IDENTITY columns, @@IDENTITY and SCOPE_IDENTITY will return different values at the end of an INSERT statement on T1.

@@IDENTITY will return the last IDENTITY column value inserted across any scope in the current session, which is the value inserted in T2.

SCOPE_IDENTITY() will return the IDENTITY value inserted in T1, which was the last INSERT that occurred in the same scope. The SCOPE_IDENTITY() function will return the NULL value if the function is invoked before any insert statements into an identity column occur in the scope.



И, по-хорошему, надо как-то так делать:
SET NOCOUNT ON;
INSERT INTO ... VALUES....;
SEELECT SCOPE_IDENTITY();


И всё это одним Open вызывать.
А то ты в два захода рискуешь совсем не те данные получить...


Palladin   (2008-05-30 17:59:00) [5]


>Ega23 ©   (30.05.08 14:50) [33]

чем?


Azize   (2008-05-30 15:45:00) [6]


> Очевидно, "тетенька" попросила Вас сделать ей хорошо, не
> представляя себе как это "хорошо" плохо в действительности.
>


> мне кажется, что паренёк делает лабу


MsGuns   (2008-05-30 15:40:00) [7]

Нумеровать документы вообще и контракты в частности - преррогатива того, кто занимается делопроизводством и не целесообразно (а часто даже категорически нельзя) вычислять их программно.
Как Ваша система "плюс один" будет работать если, к примеру, все документы с нового года нумеруются заново с единицы ? А бывает, что в номере документа присутствуют год и даже месяц.
Контракт не вводится сразу в комп, он сначала готовится (например, в ворде), потом подписывается, штампуется, регистрируется в делопроизводстве. И только после этого вводится "с бумаги" как готовый документв БД
Очевидно, "тетенька" попросила Вас сделать ей хорошо, не представляя себе как это "хорошо" плохо в действительности.


Ega23   (2008-05-30 14:50:00) [8]


> q.SQL.Text:='select @@Identity';


лучше select scope_identity()


deras   (2008-05-30 14:46:00) [9]


> Palladin ©   (30.05.08 14:32) [30]


> Ega23 ©   (30.05.08 14:37) [31]


Благодарю!


Ega23   (2008-05-30 14:37:00) [10]


>
> Супер! Вот на этом меня и заклинило :-) А как оказывается
> просто. Надо читать мат часть...


Можно попробовать и функцией ISNULL воспользоваться, типа
SET @NUM = (SELECT ISNULL(IDENT_CURRENT('dbo.Sale'), 1)), но тут я не уверен. В смысле, не знаю, что IDENT_CURRENT при отсутствии записей вернёт - NULL или нет.
Надо смотреть. Первый вариант - более универсальный, второй - ИМХО более правильный. Но надо проверить.


Palladin   (2008-05-30 14:32:00) [11]

получить... да просто

таблица id(счетчик),name(что нибудь)

Var
q:TADOQuery;

q.SQL.Text:='insert into table (name) values (:PName)';
q.Parameters.ParamByName('PName').Value:='name';
q.ExecSQL;
q.SQL.Text:='select @@Identity';
q.Open;
ShowMessage('NewID:'+q.Fields[0].AsString);
q.Close;


deras   (2008-05-30 14:32:00) [12]


> Ega23 ©   (30.05.08 14:29) [28]

Супер! Вот на этом меня и заклинило :-) А как оказывается просто. Надо читать мат часть...
Спасибо всем за ответы!


Ega23   (2008-05-30 14:29:00) [13]


> Но если запись первая, то @NUM=NULL, что вызывает ошибку.
>  Вот я и не знаю, что делать


SET @NUM = (SELECT IDENT_CURRENT('dbo.Sale'))
IF @NUM IS NULL SET @NUM=1


deras   (2008-05-30 14:25:00) [14]


> Palladin ©   (30.05.08 14:16) [26]

согласен... сам виноват...


Palladin   (2008-05-30 14:16:00) [15]


> deras   (30.05.08 14:10) [25]

а теперь пепречитай свой первый пост. каким пОпом кто-то должен был догадаться, что тебе именно это и нужно? потому и стеб над тобой возник...


deras   (2008-05-30 14:10:00) [16]


> Для предварительного хватит и max(id)+1, а id обыкновенный
> счетчик, и реальный номер присвоившийся потом показывается
> после фиксации конктрака

вот это то, что мне и нужно. Если "Для предварительного хватит и max(id)+1" - это  реализует вышеописаная ф-ция, то как реализовать "реальный номер присвоившийся потом показывается после фиксации конктрака"?


deras   (2008-05-30 14:06:00) [17]


> Azize ©   (30.05.08 14:01) [22]

так не подойдет ибо надо ф-цией организовать

Я сделал так
CREATE FUNCTION dbo.GetContractNumber ()
RETURNS int
AS
BEGIN
DECLARE @NUM INT
SET @NUM = (SELECT IDENT_CURRENT('dbo.Sale'))
RETURN(@NUM+100000)
END
Но если запись первая, то @NUM=NULL, что вызывает ошибку. Вот я и не знаю, что делать


Palladin   (2008-05-30 14:02:00) [18]


> Ega23 ©   (30.05.08 13:58) [21]
> А он и не должен генериться автоматом на серверной стороне.

Если он естественный ключ, то конечно. Только если сидят 3 деффачки блондики, все 3 открыли форму ввода, а там один и тот же предлагаемый то они долго будут боротся между собой при сохранении и звать аффтора с воплями "программа зависла" :)

А если в качестве номера использовать суррогатный, то почему бы и нет. Только свистопляски с функцией нафик никому не нужны. Для предварительного хватит и max(id)+1, а id обыкновенный счетчик, и реальный номер присвоившийся потом показывается после фиксации конктрака.


Azize   (2008-05-30 14:01:00) [19]


> deras   (30.05.08 13:55) [19]

Так генерируй ты ID до вывода формы и проверяй

Пример

ID=Random(N);
While Kontrakt.Locate('ID',ID,[]) do ID=Random(N);
CreateForm(....)


Ega23   (2008-05-30 13:58:00) [20]


> это никак не решает проблему с предпросмотром номера незафиксированного
> контракта


А он и не должен генериться автоматом на серверной стороне. Максимум, чего бы я тут сделал - при добавлении нового предложилбы вариант номера (т.е. повесил бы функцию обращения к серверу на Create формы-добавления контракта).

Но это, конечно, ИМХО.


Страницы:   1 2

Наверх

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