Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.06.29;
Скачать: [xml.tar.bz2];

Вниз

Функция в MSSQL2000   Найти похожие ветки 

 
deras   (2008-05-30 01:34) [0]

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

Спасибо


 
Германн ©   (2008-05-30 01:45) [1]


> Функция в MSSQL2000 [D7, XP]
>
> deras   (30.05.08 01:34)
>
> Описание. Есть таблица: ID, ContrNum (int), Name
> Задача.
> Создать функцию, которая возвращает номер контракта (ContrNum
> = ID + 100000), предварительно проверив, нет ли такого номера
> контр. в таблице.
>
> Спасибо
>

Да не за что.


 
deras   (2008-05-30 02:02) [2]


> Германн ©   (30.05.08 01:45) [1]

а посерйезней


 
Германн ©   (2008-05-30 02:17) [3]


> deras   (30.05.08 02:02) [2]
>
>
> > Германн ©   (30.05.08 01:45) [1]
>
> а посерйезней
>
Посерйёзней. Хм. Кто бы мне сказал что это слово значит?

P.S. А вопрос то какой?


 
ЮЮ ©   (2008-05-30 04:06) [4]

> предварительно проверив, нет ли такого номера контр. в таблице.

И что делать функции в этом случае?


 
Palladin ©   (2008-05-30 10:26) [5]

функция в три-пять строк, фикли ее писать? может поручить это дело тому кто это дело и должен делать, то есть специалисту?


 
Плохиш ©   (2008-05-30 10:29) [6]


> deras   (30.05.08 01:34)  

Спасибо за описание, но мне лабораторные и контрольные уже не нужны.


 
Stas ©   (2008-05-30 12:28) [7]

Ну а в чем проблема?
как создаь функцию?

Create function fmyfunction ()
returns int
as
begin
return...
end


 
DiamondShark ©   (2008-05-30 12:53) [8]


> Создать функцию, которая возвращает номер контракта (ContrNum
> = ID + 100000), предварительно проверив, нет ли такого номера
> контр. в таблице.

Создать -- как два пальца об асфальт.
Беда в том, что значение, возвращаемое функцией, абсолютно не пригодно к какому-либо осмысленному использованию.
А если так, то нафига функция?


 
deras   (2008-05-30 12:54) [9]


> Stas ©   (30.05.08 12:28) [7]

проблема в том, что
нвдо знать  ID для этой записи (запись еще не сохранена), чтоб ном. нового контракта сделать ContrNum = ID + 100000. Но в момент сохранения опять проверить, нет ли такого номера контракта.
Т.е. схема такова: показали форму, есть 2 едита (1 - для ном. контракта, он Enable=false и в нем должен стоять предварительный номер контракта; 2- для ввода названия). После ввода названия, делаем insert записи, но перед этим проверить, нет ли уже такого названия в БД. Так вот проверить надо этой самой функцией. Она же и должна вернуть номер провереного контракта. Надо реализовать именно функцией MSSQL.
Оч. прошу без неприятных шуток - все когда-то начинали


 
Palladin ©   (2008-05-30 13:01) [10]

а в чем же конкретно то затруднения? SQL не знаешь? ну так возьми да узнай, почитай что нибудь про него.


 
Palladin ©   (2008-05-30 13:03) [11]

... а идея, кстати, порочна по сути своей да ты так и не определился с тем, что же должна вернуть функция если все таки номер существует...


 
deras   (2008-05-30 13:13) [12]


> Palladin ©   (30.05.08 13:01) [10]

да, оч. плохо знаю SQL.


> Palladin ©   (30.05.08 13:03) [11]

ф-ция должна вернуть номер контракта, которго нет в БД


 
Palladin ©   (2008-05-30 13:21) [13]


> Оч. прошу без неприятных шуток - все когда-то начинали

если ты считаешь себя начинающим, то я папа римский. пока непонятно, что ты хочешь конкретно.

кода?  - какого?
мыслей? - все уже сказали.


> ф-ция должна вернуть номер контракта, которго нет в БД

твои слова: "номер контракта сделать ContrNum = ID + 100000" и тут же говоришь "номер контракта которого нет в БД", но если есть ContrNum=ID+100000, то что же должна она вернуть? откуда вообще взялось это "магическое" +100000 ? почему не мильен?


 
Azize ©   (2008-05-30 13:34) [14]

смотря как у тебя генерируется ID это раз
2. если у тебя все записи в таблице подвержены такому правилу как ты описал, то ты просто не сможешь добавить эту запись ID совпадёт
3. исходя из 2. если ID генерируется случайно, просто генерируй его до того как открывается форма и ставь проверку на существование ID, если существует генерируй по новой
4. А по уму это всё бред, почему нельзя сделать номер контракта=ID?


 
Palladin ©   (2008-05-30 13:37) [15]


> Azize ©   (30.05.08 13:34) [14]
> 4. А по уму это всё бред, почему нельзя сделать номер контракта=ID?

потому что, показывать предварительный номер незафиксированного контракта это тоже бред, бо как сказал RME никакого функционала он не несет так как может на 10 раз поменятся...


 
Azize ©   (2008-05-30 13:47) [16]


> Palladin ©   (30.05.08 13:37) [15]

не ну человек просто настаивает чтобы номер контракта зависел от ID, вот я и предлагаю

> сделать номер контракта=ID?


> бо как сказал RME никакого функционала он не несет так как
> может на 10 раз поменятся...

мне кажется, что паренёк делает лабу или курсак поэтому номер контракта у него меняться не будет


 
Ega23 ©   (2008-05-30 13:48) [17]

Простой совет: хоть номер контракта и является семантически ключевым полем, делать его таковым не стоит.
Введи "суррогатный" ключ (ContractID int Identity (1,1)) и поле номер контракта (ContractNr varchar(255)) с уникальным индексом.
По опыту: номер контракта - штука сложная. Это может быть, к примеру,
ФДС № 05.2008/174
где ФДС - общий шифр документов (какая-нибудь Федеральная Дорожная Служба), 05.2008 - период за май 2008 года, а 174 - порядковый номер документа, относящегося к ФДС, сделанного в мае 2008.


 
Palladin ©   (2008-05-30 13:53) [18]


> не ну человек просто настаивает чтобы номер контракта зависел
> от ID, вот я и предлагаю

так если он зависит от ID, а ID это PK, на кой черт свистопляски с ID+100000 ? ведь ID+100000 тоже PK и тоже уникален, зачем функция?


> Ega23 ©   (30.05.08 13:48) [17]

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


 
deras   (2008-05-30 13:55) [19]


> 4. А по уму это всё бред, почему нельзя сделать номер контракта=ID?


а разве это меняет суть? Вот вывел я форму. Что я должен показать в поле "Номер контракта", если контракт еще не сохранен? А показать что-то надо. Пускай даже предварительный номер, который может при сохранении измениться "10 раз" (цит.) ID показывать или ID + 100000 - суть не поменяется.
Бред или не бред, а сделать-то надо


 
Palladin ©   (2008-05-30 13:58) [20]


> deras   (30.05.08 13:55) [19]

так выбирай максимально существующий номер+1 из таблицы и показывай предварительно, раз абсолютно не критично, что он поменяется...


 
Ega23 ©   (2008-05-30 13:58) [21]


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


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

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


 
Azize ©   (2008-05-30 14:01) [22]


> deras   (30.05.08 13:55) [19]

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

Пример

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


 
Palladin ©   (2008-05-30 14:02) [23]


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

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

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


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


> 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, что вызывает ошибку. Вот я и не знаю, что делать


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


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

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


 
Palladin ©   (2008-05-30 14:16) [26]


> deras   (30.05.08 14:10) [25]

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


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


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

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


 
Ega23 ©   (2008-05-30 14:29) [28]


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


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


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


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

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


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

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

таблица 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;


 
Ega23 ©   (2008-05-30 14:37) [31]


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


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


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


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


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


Благодарю!


 
Ega23 ©   (2008-05-30 14:50) [33]


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


лучше select scope_identity()


 
MsGuns ©   (2008-05-30 15:40) [34]

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


 
Azize ©   (2008-05-30 15:45) [35]


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


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


 
Palladin ©   (2008-05-30 17:59) [36]


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

чем?


 
Ega23 ©   (2008-05-30 18:19) [37]


> чем?


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 18:39) [38]

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


 
Ega23 ©   (2008-05-30 18:41) [39]


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


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


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


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

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

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



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2008.06.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.055 c
15-1210707407
Маэстро
2008-05-13 23:36
2008.06.29
Опрос (не программерский, относительно)


2-1212169529
VovKul
2008-05-30 21:45
2008.06.29
Как пользоватся консольными приложениями


15-1211164484
Slider007
2008-05-19 06:34
2008.06.29
С днем рождения ! 19 мая 2008 понедельник


15-1211189972
Сергей_А
2008-05-19 13:39
2008.06.29
Отображение VRML


2-1212491944
ZENsan
2008-06-03 15:19
2008.06.29
Interface...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский