Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MySQL > вычисляемое поле


Автор: Cetus 24.11.2004, 16:13
Как описать создание следующей таблицы?
(id, Code, stringname)
id - auto_increment;
stringname - строка;
Code состоит из XX.YY.ZZ, где
XX - числовое значение, при добавлении:
либо указывается в запросе либо равно id.
при редактировании значение поля Code НЕ
изменяется
YY - дата;
ZZ - символ или число.

Автор: Ignat 24.11.2004, 17:46
Cetus, боюсь, в этом варианте невозможно. Более подробно опишите задачу - постараемся придумать.

Дело в том, что для составления поля Code требуется хранимка, а хранимок в стабильных версиях нет.

Автор: GoodBoy 25.11.2004, 11:09
Cetus
Для реализации твоего варианта придётся использовать дополнительный UPDATE после операции INSERT если XX=id... Если же XX!=id, то формируй поля Code сам перед вставкой записи в таблицу...

Автор: Ignat 25.11.2004, 11:25
GoodBoy, в описаном варианте не прокатит:

Цитата(Cetus @ 24.11.2004, 16:13)
при редактировании значение поля Code НЕ
изменяется


Автор: Secandr 25.11.2004, 11:37
Cetus А может лучше разбить поле Code на три?

Автор: Ignat 25.11.2004, 11:39
Имхо, лучше вычислять на выборке, а результат представлять как столбец.

Автор: Secandr 25.11.2004, 11:43
А смысл этого поля, зачем оно?

Автор: Cetus 25.11.2004, 12:14
Впринципе можно поле Code разбить на 3.
Мои поиски по документации привели к такому решению.
на сервере описать функцию OnInsert для данной таблицы.
полятаблицы:
Id - auto_increment,
Code - integer, }
DateIn - Date, } бывшее поле Code
IdTOV - char, }
StringName - char(255);

Смысл поля Code - уникальный код товара.
Дело в том что запись о товаре может кочевать по разным таблицам, и поле Code должно быть постоянно.
При поступлении товара на склад уникальный номер (использую Id-auto_increment) прописывается в поле Code.


Что должна выполнять функция(OnInsert):
при вставке новой записи выполняется проверка:
если Code = 0 то Code := Id
иначе ничего не менять.

!! Хотелось бы увидеть пример функции, если тип поля (!) Code - integer и (!) Code - char(255)

Как залить/описать на сервере данную функцию?
Добавлено @ 12:18
Цитата(GoodBoy @ 25.11.2004, 11:09)
Cetus
Для реализации твоего варианта придётся использовать дополнительный UPDATE после операции INSERT если XX=id... Если же XX!=id, то формируй поля Code сам перед вставкой записи в таблицу...

дело в том, что между Insert Update может вклиниться другой клиент.
Чтобы избежать этого надо блокировать таблицу.
код будет вида

lock table asd;
inesrt ....
update ....
unlock table asd;

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

Автор: Ignat 25.11.2004, 12:25
Цитата(Cetus @ 25.11.2004, 12:14)
дело в том, что между Insert Update может вклиниться другой клиент.

В этом нет ничего страшного. Создай поле sid, запиши туда какой-нибудь ид (например, MD5 хеш - имени товара ) и update делай по этому sid, в момент редактирования обнули sid, чтоб место не занимал.

Автор: GoodBoy 25.11.2004, 13:09
Cetus
Ну могу посоветовать тебе использовать Оракл... :-))))))))))))

Автор: Cetus 25.11.2004, 13:13
Ignat,
в том то и дело что _много_ товаров с _одинаковым имемем_, тут требуется различать между собой все товары с одинаковым именем.
Заказчик - параноик smile

Автор: Secandr 25.11.2004, 13:14
Решение:
1. изменить структуру бд - зранить весь товар в одной таблицн
2. использовать уникальные ключи: uniqid("") генерировать их в пхп.

Автор: Cetus 25.11.2004, 13:16
Как написать серверную функцию вида:
OnInsert
[Code - integer]
Если Code = NULL or Code = 0 то Code := Id;
или
[Code - char(255)]
Если Code = NULL or Code = '' то Code := IntToStr(Id)

Автор: Secandr 25.11.2004, 13:17
Cetus В стабильных венрсиях вроде бы нет хранимых процедур smile
читай предыдущее сообщение.

Автор: Cetus 25.11.2004, 13:18
Как написать серверную функцию вида:
OnInsert
[Code - integer]
Если Code = NULL or Code = 0 то Code := Id;
или
[Code - char(255)]
Если Code = NULL or Code = '' то Code := IntToStr(Id)

у меня MySQL 4.0.2 в документации написано что можно добавлять пользовательские процедуры.

сервер MySQL, клиент на Delphi. так что PHP использовать не могу.
предлагал клиенту использовать GUID:
не понравилось, сказал, что слишком длинный ключ smile))

Автор: Ignat 25.11.2004, 13:35
Цитата(Cetus @ 25.11.2004, 13:18)
у меня MySQL 4.0.2 в документации написано что можно добавлять пользовательские процедуры.

Угу, только для этого Мускуль перекомпилить придется, а процедуру писать на сях.


Цитата(Cetus @ 25.11.2004, 13:13)
в том то и дело что _много_ товаров с _одинаковым имемем_,


Цитата(Ignat @ 25.11.2004, 12:25)
(например, MD5 хеш - имени товара )

Временный ID можно срандомизить в клиенте, не обязательно же использовать имя товара - возьми, например, текущее время в миллисекундах, плюс рандом, плюс артикул товара и направление ветра. Это же нужно только на один запрос - потом сотрешь.

Автор: Cetus 25.11.2004, 14:08
НЕТ! идентификатор товара нужен постоянно!
тем более что:

1. MD5 может совпасть при достаточно большом обьеме информации.
2. MD5 слишком длинное символьное представление
хотелось бы что нибудь покороче.

P.S. т.е. никак не прикрутить функции к серверу?
а если подгружать динамически во время работы сервера, через клиента?

Автор: Ignat 25.11.2004, 14:16
Цитата(Cetus @ 25.11.2004, 14:08)
НЕТ! идентификатор товара нужен постоянно!

А кто говорит, что его не будет. Я тебе предлагаю сделать временный идентификатор. На случай, если во время между insert и update кто-то вставит строку, то ты мог определить какую строку вставил именно твой клиент, а после изменить именно эту строку, вставив постоянный идентификатор.
Хотя по идее, если insert, update следуют друг за другом, то на таблице будет стоять блокировка записи.

Автор: Cetus 25.11.2004, 14:23
требуется чтобы любой клиент не мог прочитать данную запись с еще неустановленным идентификатором.
для этого нужно либо чтобы стояла полная блокировка таблицы (этот вариант отпадает), либо данную запись блокировать по чтению.

P.S. спасибо за идею с MD5, я понял суть smile

Автор: Ignat 25.11.2004, 14:27
Цитата(Cetus @ 25.11.2004, 14:23)
либо данную запись блокировать по чтению.

В таком случае, нужно использовать таблицы InnoDB. В них есть блокировка строк. В соседнем топике есть ссылка.

Автор: Cetus 25.11.2004, 14:32
Ignat, Secandr, GoodBoy
Спасибо !

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)