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

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

автокрименентное значение [D7, MySQL]


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

{Alex} ©   (2006-04-05 16:51:00) 

маленький такой вопросик:

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

Используется MySQL&MDAC&Delphi


sniknik   (2006-04-06 12:30:00) [21]

> Не пойму, о какой таблице Вы говорите?

sSQLGetIdentity = 'select GEN_ID(%s, 1) from rdb$database';
таблица, системная. в ней 1 запись всегда, минимум. вот поэтому ее я и использовал если бы там была пустая таблица (с 0 записей) то возвращаемое значение было бы null независимо от значения счетчика/переменной.

а говориш знаеш IB больше меня... если учесть, что сам ститаю, что практически его не знаю... ;о))


Курдль   (2006-04-06 11:50:00) [22]


> sniknik ©   (06.04.06 11:37) [22]
> работает это компилится и выполняется? или получает значение счетчика при 0 записей в таблице вместо null


Работает, это получает правильное значение генераторапри вновь созданной БД (0 записей во всех таблицах). (Yaffil + Delphi c компонентами TIB...).
Не пойму, о какой таблице Вы говорите? Как генератор - отдельный и самостоятельный объект базы данных, живущий отдельной жизнью, связан с какой бы то ни было таблицей?


sniknik   (2006-04-06 11:37:00) [23]

> Все работает при нулевом количестве записей.
работает это компилится и выполняется? или получает значение счетчика при 0 записей в таблице вместо null (как оно обычно бывает. проверялось на ADO - OLEDB драйвер ZStyle - файребирд ембедед 1.5)


Johnmen   (2006-04-06 11:35:00) [24]


> > То, что ты привёл, как примеры [3] есть простое наращивание
>
> > значения последовательности или генератора. И не более
> того.
>
> Более того! Слово select означает то, что эти данные будут
> выбраны в набор данных, т.е. получены по запросу клиентом
> СУБД и могут быть использованы по его усмотрению.


Прошу в дальнейшем цитировать меня полностью, и на основании этого приводить свои высказывания.
А не выдирать из контекста.


Курдль   (2006-04-06 11:21:00) [25]


> ясно с IB знаком еще более поверхностно чем я.

Наверное, менее поверхностно. Имею в своем портфолио самолично сделанные, внедренные и до сих пор работающие проекты с использованием IB (правда очень давние). Не поленился отрыть исходники  sSQLGetIdentity = 'select GEN_ID(%s, 1) from rdb$database';
Все работает при нулевом количестве записей.


sniknik   (2006-04-06 11:08:00) [26]

ну все понятно. отстаивается позиция описаная (предугаданная ;) в [12].
с вариантом, не автоинкримента, но с переменной. но тогда и спорить глупо т.к. значение такой переменной является сушествующим а не предуганным о чем пост [1] (против которого такое "горячее" возражение)

кстати у меня стойкое впечатления о "непонимаемости" "возражателем" аргументов...
для примера (не буду опровергать все ;о)
> > sniknik ©   (05.04.06 18:37) [12]
> > - SELECT GEN_ID(ID_GENERATOR, 1) AS ID FROM RDB$DATABASE
> > //неважно с какой таблицы, в этой минимум одна запись
> должна быть
>
> Нет! Не должна быть!

чего не должно быть? ты понял вообще что там и зачем? прежде чем возражать. ясно с IB знаком еще более поверхностно чем я.
дело в том что написать аналогично как в MSSQL
SELECT GEN_ID(ID_GENERATOR, 1) AS ID
там нельзя, выборка даже из функций/переменных/чего там еще должна производится в контексте выборки из таблици (может есть и другой вариант, но я не в курсе) и поэтому необходимо подставить FROM any_table, и any_table долна быть не пустой иначе пустой рекордсет вернет, хотябы одна запись должна быть а в той что я подставил одна обязательно есть... о чем и коментарий

> Если подобная возможность и появилась в MSSQL, то лишь в последних версиях. Раньше было возможно
> только использование @@Identity.
это было, и есть, рекомендованным способом и тогда и сейчас. а "подобная возможность", есть и была раньше (не скажу за 6,5 но в 7.0 это практически наверняка было (читал обсуждение по этому поводу на sql.ru))


Курдль   (2006-04-06 10:32:00) [27]

Прошу извинения у автора топика за вмешательство, непосредственно не относящееся к его вопросу. Однако оно было вызвано только стремлением восстановить истину. Я не мог пропустить без ответа пост sniknik ©   (05.04.06 16:58) [1], который противоречит действительности.

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

> То, что ты привёл, как примеры [3] есть простое наращивание
> значения последовательности или генератора. И не более того.

Более того! Слово selectозначает то, что эти данные будут выбраны в набор данных, т.е. получены по запросу клиентом СУБД и могут быть использованы по его усмотрению.


> Причём, как ты сам понимаешь, полученное значение вовсе
> не означает того, что оно "будет присвоено следующей записи,
>  перед ее добавлением в таблицу".

А куда оно денется, если его явно присвоить идентификатору "следующей записи"?


> sniknik ©   (05.04.06 18:37) [12]
> - SELECT GEN_ID(ID_GENERATOR, 1) AS ID FROM RDB$DATABASE
> //неважно с какой таблицы, в этой минимум одна запись должна быть

Нет! Не должна быть!


> запись в то поле которое автоинкремент (в нормальном варианте обеспечивается тригером),

Не "в нормальном варианте" а в частном случае. Не все СУБД используют автоинкрементные поля.  И не триггером, а системным триггером.
Кстати, термин "автоинкрементное" не используется в ER-моделировании.


> и кстати такую схему также легко можно и в MSSQL сделать,
> только зачем? чесать левое ухо правой задней ногой...

Если подобная возможность и появилась в MSSQL, то лишь в последних версиях. Раньше было возможно только использование @@Identity. Кстати, Вы задумывались, почему добавили возможность получения следующего идентификатора? Может это кому-то понадобилось больше, чем чесание левого уха правой ногой? :)
Отвечу на вопрос "зачем". Если на клиенте требуется создать структурную единицу данных, состоящую из нескольких связанных записей.
Пример:  паспорт >-+  физ. лицо +-< номер телефона.
Так вот, если заранее знать "следующий" ID физ. лица, то можно спокойно создать записи в связанных таблицах, заполнив поля внешних ключей этим ID на клиенте и "отправить" их в нужной последовательности на сервер. Это хорошая альтернатива ХП.
Такой же механизм используется а ADO.NET, когда связанные таблицы многотабличного датасэта получают на клиенте псевдозначения PK и FK типа "-1", а потом эти псевдозначения подменяются реальными ID, полученными от генераторов, последовательностей и т.п.


sniknik   (2006-04-05 23:11:00) [28]

> Поясню суть проблеммы:
будем откровенны, ничего ты не поясняеш, т.к. до этого ничего сказано не было, по "проблеме", ты ее счас только излагаеш.

> Но маленькая проблема если пользователь добавляет файл, название которого совпадает ...
надуманная проблема, и решение не лучшее
не претендую, что мое будет идеалом, но делал бы по другому. использовал бы как основной уникальный идентификатор(и имя файла на сервере по совместительству) его хеш.

у тебя файловый сервер, а в базе справочник имен, и ссылка на путь/имя файла хранится? сделал бы поля (основные)  - оригинальное имя файла (пользовательское, неуникальное), время закачки, хеш файла (одновременно и его имя в файловой системе)  
вот хеш бы был уникальным полем (ну он по сути такой ;), поле можно обьявить ключем), рассчитавался бы по содержимому файла ("e-мул" так делает) и добавлялся бы файл только в том случае если расчитанного хеша в базе не оказалось.

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


Anatoly Podgoretsky   (2006-04-05 22:13:00) [29]

Тогда нет нужды в автоинкрименте, достаточно будет GUID или имя фильма + датавремя


{Alex}   (2006-04-05 20:46:00) [30]

упс.... не думал что тут так все развернется....
Поясню суть проблеммы:

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

Но маленькая проблема если пользователь добавляет файл, название которого совпадает с любым названием файла на сервере, то файл на сервере просто переписывается.
Добавление сведение о фильме в базу происходит только после успешной закачки.
Вот тут и приходит на ум, что бы программа автоматически переименновала файл, и называла его по индефикатору записи в базе.


Anatoly Podgoretsky   (2006-04-05 19:51:00) [31]

Курдль ©   (05.04.06 17:07) [3]
А MySql к таким относится?
Кроме того вопрос про автоинкриментные поля, а не генераторы или подобное. Я не в курсе насчет Оракла, но в ИБ это генератор, который косвенно относится к автоинкриментным полям, которых там просто нет.


Джо   (2006-04-05 19:23:00) [32]

В Postgres также есть подобные функции, currval & nextval для генераторов. Это так, до кучи.


sniknik   (2006-04-05 18:37:00) [33]

Johnmen ©   (05.04.06 18:03) [11]
возможно он имеет ввиду непересекаемость значений при (возьмем пример с IB, он мне всетаки ближе оракла)
получении
- SELECT GEN_ID(ID_GENERATOR, 1) AS ID FROM RDB$DATABASE //неважно с какой таблицы, в этой минимум одна запись должна быть

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

Курдль ©  
если это так. то ...  мне тоже нечего с тобой обсуждать ;(.
и кстати такую схему также легко можно и в MSSQL сделать, только зачем? чесать левое ухо правой задней ногой... (ее отрастить сначала надо ;о))


Johnmen   (2006-04-05 18:03:00) [34]


> Курдль ©   (05.04.06 18:00) [10]


Понятно...
Мне обсуждать нечего. И тем более, как я теперь предполагаю, с тобой.


Курдль   (2006-04-05 18:00:00) [35]


> Johnmen ©   (05.04.06 17:56) [8]
>
>
> > Курдль ©
>
>
> Нет, дорогой, ты В КОРНЕ неправ.
> То, что ты привёл, как примеры [3] есть простое наращивание
> значения последовательности или генератора. И не более того.
>


Читайте первоисточники - завтра вернемся к обсуждению :)


Курдль   (2006-04-05 17:59:00) [36]


> можно select IDENT_CURRENT('table_name')


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

Уверяю Вас, что никто из "многопользователей" ни при каких обстоятельствах не получит того же значение последовательности от оракла, идентификатора от сайбэйса или генератора от интербэйса. Их совершенно бесстрашно можно использовать для вставки в новую запись именно целевым значением, как Вы написали insert into table1 (Field1) values ('xxxx')в случае, если одним пакетом заполняются несколько связанных по внешним ключам таблиц с первичным ключом из Вашей table1. Этот метод не только удобен, но еще и рекомендован во многих источниках. И он не имеет ничего общего с select max(id)+1 as NextId from table1.


Johnmen   (2006-04-05 17:56:00) [37]


> Курдль ©


Нет, дорогой, ты В КОРНЕ неправ.
То, что ты привёл, как примеры [3] есть простое наращивание значения последовательности или генератора. И не более того.
Причём, как ты сам понимаешь, полученное значение вовсе не означает того, что оно " будетприсвоено следующейзаписи, перед ее добавление в таблицу".


sniknik   (2006-04-05 17:55:00) [38]

> можно
> select IDENT_CURRENT('table_name')
хотя нет, предположительноследующее будет

select IDENT_CURRENT('table_name')  + IDENT_SEED('table_name')


sniknik   (2006-04-05 17:52:00) [39]

> sniknik! Ну Вы зажгли!!! Сами-то поняли, что написали?!! Поставили себя в неловкое положение, назвав тысячи
> программистов оракла, сайбэйса и интербэйса глупыми?
только тех кто так пишет, закладываеться на фиктивное значение. и мне не неловко, мне комфортно. "правду говорить легко и приятно" (@ не помню чей)

> узнать значение нового идентификатора нельзя до тех пор, пока не вставишь строку. :)
можно
select IDENT_CURRENT('table_name')

> То, что Вы пишете дальше - это уже диагноз! :) Учите албанский!
ну вас тогда надо послать к основам BD


Курдль   (2006-04-05 17:36:00) [40]


> sniknik ©   (05.04.06 17:27) [4]
> > Все более-менее умные СУБД умеют это делать!
> а глупые программисты этим пользуются...
> вообщето приведенные примеры это способ узнать текущеее
> значение счетчика, а не значение которое будет записано.
> .. разница однако.


sniknik! Ну Вы зажгли!!! Сами-то поняли, что написали?!! Поставили себя в неловкое положение, назвав тысячи программистов оракла, сайбэйса и интербэйса глупыми?
Как, по-Вашему, переводится слово после точки и до VAL в этой фразе: select SEQUENCE_NAME.NEXTVAL from DUAL?

Наверное, Вам непосчастливилось учиться работать с БД наоснове MS SQL Server, где и вправду, узнать значение нового идентификатора нельзя до тех пор, пока не вставишь строку. :)

То, что Вы пишете дальше - это уже диагноз! :) Учите албанский!


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

Наверх

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