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

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

Работа уникальными значениями [D7, IB6.x, MSSQL]


Страницы:   1 2 3 4

den_777 ©   (2004-05-24 09:46:00) 

Пока мне приходилось работать только с INFORMIX и IB,FB. Поэтому приведу пример на этих базах.
Надо чтобы была возможность автоматической и ручной вставки значения в поле которое является PRIMARY KEY, т.е. для таблицы с полями ID и CNAME проходили оба SQL insert into tbl1(id,cname) values(0,"myname") и insert into tbl1(cname) values("myname")
Соответственно в INFORMIX я просто задаю этому полю тип SERIAL и все, больше ничего делать не надо. В первом случае INFORMIX просто проверяет не противоречит ли вставляемое мной значение уникальности и если нет то вставляет его во втором случае сам генерит следующее значение.
В IB,FB это решается с помощью генератора и триггера IF NEW.ID IS NULL THEN NEW.ID=GEN_ID(MY_GEN,1).
Вопрос как таких же действий добиться от MSSQL. И вопрос в догонку, если в других базах какой-либо функционал был заложен в триггер перед вставкой, то как этот же функционал реализовать в MSSQL.


den_777   (2004-05-24 13:45:00) [41]


> Всё-таки неясно, зачем самому вставлять ID ? Ведь это фактически
> суррогатный ключ, и в величине его значения никакого смысла
> нет.

Раз уж программисты написавшие INFORMIX (по моему мнению СУБД INFORMIX на порядок лучше чем MSSQL и по надежности, и по скорости работы, и по возможности настроек) сделали тип SERIAL  с функционалом, который я уже описывал, значит это кому-нибудь нужно.


> "Microsoft Sql Server 2000 Справочник администратора" стр.
> 519

Жаль, но данная книга у меня сейчас дома, так что прочесть сейчас не смогу. Подожду до завтра. Но вроде как совсем недавно я ее всю прочитал и ответы на заданные мной здесь вопросы не нашел. Интересно, что-же там на 519стр.


paul_k   (2004-05-24 13:09:00) [42]


> Это вроде как уже понятно. А вот есть ли мнение по поводу
>
> > den_777   (24.05.04 11:43) [14]

перепечатывать лень
"Microsoft Sql Server 2000 Справочник администратора" стр. 519
или BOL


Johnmen   (2004-05-24 13:05:00) [43]

>den_777

Всё-таки неясно, зачем самому вставлять ID ? Ведь это фактически суррогатный ключ, и в величине его значения никакого смысла нет.
Да и поведение его (Identity), естественно, "учитывает" многопользовательскую работу...


den_777   (2004-05-24 13:04:00) [44]


> следовательно  - либо значение по умолчанию либо через ХП
> организовывать добавление.


Это вроде как уже понятно. А вот есть ли мнение по поводу

> den_777   (24.05.04 11:43) [14]


paul_k   (2004-05-24 12:53:00) [45]

Виноват...
Если верить вумной книжке
"Если какой-либо оператор пытается выполнить операцию, которая нарушает какое -либо ограничение по таблице, или являеттся причиной какой-то другой ошибки, то связанный с ним триггер не будет активизирован"
то есть проверять непустые  поля надо раньше.
следовательно  - либо значение по умолчанию либо через ХП организовывать добавление.


den_777   (2004-05-24 12:25:00) [46]


> paul_k ©   (24.05.04 12:11) [15]


update insertedMSSQL в триггере писать не разрешает
"error286: The logical tables INSERTED and DELETED cannot be updated"


paul_k   (2004-05-24 12:11:00) [47]


>
> А как быть с тем, что в случае insert into tbl1(cname) values("myname")
> SERVER ругнется, что ID должно быть обязательно задано.
>

напиши то, что я советовал, в триггере и проверь... работы на 5 минут
создать таблицу с 2-мя полями и в триггере update inserted  написать :)


den_777   (2004-05-24 11:43:00) [48]


> ega23 ©   (24.05.04 11:35) [13]


Спасибо, я тоже думаю что это самый подходящий вариант.

Но вот вопрос про триггеры BEFORE INSERT остается открытым. Ведь в любой базе DEFAULT и CHECK constraints реализовываются с помощью системных триггеров перед вставкой и обновлением. И разработчику баз данных тоже предоставлено право пользоваться возможностью изменения данных в триггере до вставки и обновлений. Если в MSSQL такой возможности нет, то просто любопытно, а как же у них реализованы DEFAULT и CHECK constraints.


ega23   (2004-05-24 11:35:00) [49]

Тогда 3-й вариант - построить самому функцию вычисляющую новый ID и в свойствах поля указать её, как значение по умолчанию. ИМХО, разумнее всего будет. Я-то с точки зрения 7.0 советовал...


den_777   (2004-05-24 11:31:00) [50]


> ega23 ©   (24.05.04 11:21) [11]
> MS SQL-то какой?


2000


ega23   (2004-05-24 11:21:00) [51]

MS SQL-то какой?


den_777   (2004-05-24 11:18:00) [52]


> 1 -й вариант почитать про Identyty

надеюсь все что можно про Identyty я уже прочитал


> 2-й вариант - в написать свою процедуру - генерацию уникального
> ID, вызывать её в тригере
> Exec ap_get_id @new_id out
> update inserted set id = @new_id
> если вставка не по 1-й записи то делать это в курсоре по
> inserted


А как быть с тем, что в случае insert into tbl1(cname) values("myname") SERVER ругнется, что ID должно быть обязательно задано.


> 3-й вариант - построить самому функцию вычисляющую новый
> ID и в свойствах поля указать её, как значение по умолчанию.
>

Спасибо за вариант, стоит разобраться с этой возможностью


> 4-й вариант - использовать для ID тип uniqueidentifier (GUID)
> и функцию NewId()
> Если подумать и поковырятся в хелпе можно найти ещё N способов
> организовать уникальный ID.

Не подходит, нужен ID с типом INTEGER


den_777   (2004-05-24 11:11:00) [53]


> ega23 ©   (24.05.04 10:39) [5]


спасибо, но мы отсекаем возможность вставки в таблицу без ХП, так как в случае insert into tbl1(cname) values("myname")
SERVER ругнется, что ID должно быть обязательно задано.

Ну а насчет Identity в

> ega23 ©   (24.05.04 10:48) [7]

все написано.

Делать Set Identity_Insert ON/OFF при многопользовательской работе я думаю небезопасно.Одна транзакция будет действительно вставлять необходимые данные в ID, а вот что произойдет с другими транзакциями которые ожидали автоматической подстановки ID остается только догадываться.


> Хотя задачка сама по себе странновата...


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

Вопрос скорее всего адресован к тем, кто достаточно долго поработал с IB,FB и потом переходил на MSSQL. Какие стандартные замены привычной работе с генераторами и триггерами BEFORE INSERT нашел для себя этот человек в MSSQL.


paul_k   (2004-05-24 10:54:00) [54]

1 -й вариант почитать про Identyty
2-й вариант - в написать свою процедуру - генерацию уникального ID, вызывать её в тригере
Exec ap_get_id @new_id out
update inserted set id = @new_id

если вставка не по 1-й записи то делать это в курсоре по inserted

3-й вариант - построить самому функцию вычисляющую новый ID и в свойствах поля указать её, как значение по умолчанию.
4-й вариант - использовать для ID тип uniqueidentifier (GUID) и функцию NewId()
Если подумать и поковырятся в хелпе можно найти ещё N способов организовать уникальный ID.


ega23   (2004-05-24 10:48:00) [55]

А просто объявить поле Identity ?

Он хочет иметь возможность сам в него значения вставлять. Вопрос стоит в том, как часто он сам значения будет вставлять. Если операция редкая, то делать столбец как Identity и потом Set Identity_Insert ON/OFF ставить. Если частая, то IDENTITY очень неудобно будет.

Хотя задачка сама по себе странновата...


Johnmen   (2004-05-24 10:42:00) [56]

>den_777

А просто объявить поле Identity ?
:)


ega23   (2004-05-24 10:39:00) [57]

IF NEW.ID IS NULL THEN NEW.ID=54677
Причем поле ID NOT NULL.

Не слышал я в MS SQL про такую конструкцию. Реализовать - можно, повторюсь, что с помощью ХП:

Print  'S_PersEdit- модификация таблицы персонала'
go
if exists (select * from sysobjects where id = object_id(N'[S_PersEdit]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [S_PersEdit]
GO

CREATE PROCEDURE S_PersEdit
--режим работы процедуры
@mode int=-1,--1-add,2-edit,3-del,30 - проверка на удаление 4-New PinCod
            --11 -Generatior ADD, 12 --generator -CHK, 13 --generator -DEL
--Сведения об персоне
@persId int=-1  output, -- output для Генератора
@PersNam1 varchar(32)='',
@PersNam2 varchar(32)='',
@PersNam3 varchar(32)='',

As

declare  @result int,
        @cod int

if @mode=1
begin
if @PersID=-1 Select @PersID=Max(PersID)+1 from Persons
Insert into Persons (PersID, PersNam1, Persnam2, ....)
Values (@PersID, @PersNam1, @Persnam2, ... )

....

 -- Далее можно сразу же протоколирование произвести..

.....
Return(@Result)
end


den_777   (2004-05-24 10:30:00) [58]


> Неправильно тебе кажется. Триггер - последний рубеж перед
> операцией


Все может быть, только уточни как реализовать в MSSQL аналог

IF NEW.ID IS NULL THEN NEW.ID=54677
Причем поле ID NOT NULL.

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


> Только так и делается. Работать с таблицами напрямую - вредно.
> Только черех ХП. Более того, даже Select'ы через ХП.


Извини, не принимай за грубость, но это только твое мнение. У меня есть свой взгляд на работу с базами данных и опыт написания и поддержки программ взаимодействующих с разработанными мною большими и очень большими базами. Но все это не относится к теме вопроса, давай не будем дальше развивать эту тему.


ega23   (2004-05-24 10:13:00) [59]

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

Неправильно тебе кажется. Триггер - последний рубеж перед операцией.

да и писать на каждую таблицу хранимую процедуру только для того чтобы провести обычную вставку это как-то не хорошо

Только так и делается. Работать с таблицами напрямую - вредно. Только черех ХП. Более того, даже Select'ы через ХП.


den_777   (2004-05-24 10:04:00) [60]


> Точно так же, как и в других СУБД.


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

А по поводу ID, может есть другие варианты. Насчет процедуры - это слишком сильное орграничение себе делать.Все таки insert into намного проще, да и писать на каждую таблицу хранимую процедуру только для того чтобы провести обычную вставку это как-то не хорошо.


Страницы:   1 2 3 4

Наверх

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