Склонение ФИО (постановка)
SYSDBA (обсуждение | вклад) |
Morpher (обсуждение | вклад) (→Ссылки по теме) |
||
| (не показаны 12 промежуточных версий 1 участника) | |||
| Строка 1: | Строка 1: | ||
| − | + | При оформлении различных документов на основании информации из базы данных часто возникает необходимость в склонении имен существительных по падежам. Например, справка выдана ''Петрову'', принять на работу ''Сидорова'' и т.п. Кроме этого, есть необходимость в хранении переводов наименований объектов на различные языки. Предлагается решить две указанные проблемы следующим образом. Создаем таблицу [[GD_MULTINAME]], каждая запись которой хранит наименование для объекта заданного идентификатором '''refid''' из таблицы '''relationkey'''. Поля '''langid''' и '''caseid''' содержат языковой тэг и падеж соответственно. Поле '''caseid''' заполняется только в тех случаях, когда это имеет смысл. Для одного объекта таблица [[GD_MULTINAME]] может содержать несколько наименований на разных языках и/или в разных падежах. В запросы, извлекающие наименование объекта мы будем добавлять '''LEFT JOIN''' на таблицу [[GD_MULTINAME]] (или использовать подзапросы в секции SELECT) для извлечения имени в нужном падеже и/или на нужном языке. | |
| − | + | ||
| − | Создаем таблицу | + | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
=== Пример использования === | === Пример использования === | ||
| Строка 58: | Строка 19: | ||
REFID LANGID CASEID NAME | REFID LANGID CASEID NAME | ||
============================================================= | ============================================================= | ||
| − | 20000001 | + | 20000001 ru D Иванову Ивану Ивановичу |
| − | 20000001 | + | 20000001 ru G Иванова Ивана Ивановича |
| − | 20000001 | + | 20000001 be N Іваноў Іван Іванавіч |
| − | 20000002 | + | 20000002 en NULL Soap |
Запрос, который извлечет ФИО человека в родительном падеже, будет выглядеть следующим образом: | Запрос, который извлечет ФИО человека в родительном падеже, будет выглядеть следующим образом: | ||
| Строка 72: | Строка 33: | ||
... | ... | ||
gd_contact c LEFT JOIN gd_multiname m | gd_contact c LEFT JOIN gd_multiname m | ||
| − | ON c.id = m.refid AND m.langid = ' | + | ON c.id = m.refid AND m.langid = 'ru' AND m.caseid = 'G' |
... | ... | ||
| + | |||
| + | Обратите внимание, что если соответствующая запись в таблице gd_multiname будет отсутствовать, то запрос покажет наименование из таблицы gd_contact. | ||
| + | |||
| + | Аналогично, запрос, который пожет наименование товара на английском, если таковое присутствует в базе: | ||
| + | |||
| + | SELECT | ||
| + | ... | ||
| + | COALESCE(m.name, g.name), | ||
| + | ... | ||
| + | FROM | ||
| + | ... | ||
| + | gd_good g LEFT JOIN gd_multiname m | ||
| + | ON g.id = m.refid AND m.langid = 'en' | ||
| + | ... | ||
| + | |||
| + | Вариант с использованием позапроса: | ||
| + | |||
| + | SELECT | ||
| + | ... | ||
| + | c.name, -- имя объекта | ||
| + | (SELECT m.name FROM gd_multiname m WHERE c.id = m.refid AND m.langid = 'ru' AND m.caseid = 'G'), -- имя в нужном падеже | ||
| + | ... | ||
| + | FROM | ||
| + | ... | ||
| + | gd_contact c | ||
| + | ... | ||
| + | |||
| + | === Бизнес-класс TgdcMultiName === | ||
| + | |||
| + | Таблица gd_multiname является главной таблицей для бизнес-класса [[TgdcMultiName]]. Диалоговое окно для бизнес-класса TgdcMultiName должно отображать: | ||
| + | * Идентификатор записи для которой указано наименование (refid); | ||
| + | * Название таблицы; | ||
| + | * Исходное наименование (из таблицы заданной relationkey); | ||
| + | * Наименование; | ||
| + | * Тэг языка (TComboBox с возможностью редактирования. Выпадающий список должен содержать значения "ru", "be" и "en"); | ||
| + | * Падеж (для выбора падежа разместить шесть радио кнопок с наименованиями падежа и падежными вопросами, и седьмую радио-кнопку "Не указан"). | ||
| + | |||
| + | При нажатии на кнопку Новый в диалоговом окне, поля refid и relationkey должны получать значения из предыдущей записи. | ||
| + | |||
| + | === Удаление записей из таблицы gd_multiname === | ||
| + | |||
| + | Поскольку refid не является внешним ключем, то применить автоматическое каскадное удаление невозможно. Для очистки таблицы от ненужных записей придется либо написать хранимую процедуру, которая для каждой записи в gd_multiname будет проверять ее существование в таблице relationkey и удалять в случае отсутствия, либо встроить такой алгоритм непосредственно в TgdcMultiLine. Вызов операции очистки базы необходимо назначить кнопке на панели инструментов окна просмотра класса TgdcMultiLine. | ||
=== Организация пользовательского интерфейса === | === Организация пользовательского интерфейса === | ||
| + | |||
| + | Можно предложить три варианта организации пользовательского интерфейса в диалоговых окнах тех объектов, которые подразумевают наличие наименований в разных падежах и/или на разных языках: | ||
| + | # Добавить вкладку со списком дополнительных наименований, на которой возможно редактирование непосредственно в таблице. | ||
| + | # Справа от поля ввода наименования добавить кнопку "..." по которой на экране открывать окно со списком наименований (форма просмотра TgdcMultiName с настроенными ExraConditions?). | ||
| + | # На той же вкладке, где находится поле для ввода наименования, добавить TLabel (TEdit или TMemo, в режиме только для чтения), где отображать дополнительные наименования. Рядом разместить кнопку "..." по которой на экране открывать окно со списком наименований для редактирования. | ||
| + | |||
| + | === Модификация базы данных === | ||
| + | |||
| + | Необходимо будет добавить процедуру в список modify для добавления таблицы gd_multiline на существующие базы. | ||
=== Ссылки по теме === | === Ссылки по теме === | ||
| Строка 82: | Строка 94: | ||
* [http://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D0%B4%D0%B5%D0%B6 Падеж] | * [http://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D0%B4%D0%B5%D0%B6 Падеж] | ||
* [http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=412 Склонение имен и фамилий по падежам, библиотека функций] | * [http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=412 Склонение имен и фамилий по падежам, библиотека функций] | ||
| + | * [http://morpher.ru «Морфер» – универсальный модуль склонения словосочетаний] | ||
[[Category:Постановка]] | [[Category:Постановка]] | ||
Текущая версия на 19:28, 14 марта 2009
При оформлении различных документов на основании информации из базы данных часто возникает необходимость в склонении имен существительных по падежам. Например, справка выдана Петрову, принять на работу Сидорова и т.п. Кроме этого, есть необходимость в хранении переводов наименований объектов на различные языки. Предлагается решить две указанные проблемы следующим образом. Создаем таблицу GD_MULTINAME, каждая запись которой хранит наименование для объекта заданного идентификатором refid из таблицы relationkey. Поля langid и caseid содержат языковой тэг и падеж соответственно. Поле caseid заполняется только в тех случаях, когда это имеет смысл. Для одного объекта таблица GD_MULTINAME может содержать несколько наименований на разных языках и/или в разных падежах. В запросы, извлекающие наименование объекта мы будем добавлять LEFT JOIN на таблицу GD_MULTINAME (или использовать подзапросы в секции SELECT) для извлечения имени в нужном падеже и/или на нужном языке.
Содержание |
[править] Пример использования
Пусть в таблице GD_CONTACT мы имеем запись:
ID NAME ========================================== 20000001 Иванов Иван Иванович
а в таблице GD_GOOD:
ID NAME ========================================== 20000002 Мыло
Тогда, в таблице GD_MULTINAME могут быть следующие записи:
REFID LANGID CASEID NAME ============================================================= 20000001 ru D Иванову Ивану Ивановичу 20000001 ru G Иванова Ивана Ивановича 20000001 be N Іваноў Іван Іванавіч 20000002 en NULL Soap
Запрос, который извлечет ФИО человека в родительном падеже, будет выглядеть следующим образом:
SELECT
...
COALESCE(m.name, c.name),
...
FROM
...
gd_contact c LEFT JOIN gd_multiname m
ON c.id = m.refid AND m.langid = 'ru' AND m.caseid = 'G'
...
Обратите внимание, что если соответствующая запись в таблице gd_multiname будет отсутствовать, то запрос покажет наименование из таблицы gd_contact.
Аналогично, запрос, который пожет наименование товара на английском, если таковое присутствует в базе:
SELECT
...
COALESCE(m.name, g.name),
...
FROM
...
gd_good g LEFT JOIN gd_multiname m
ON g.id = m.refid AND m.langid = 'en'
...
Вариант с использованием позапроса:
SELECT ... c.name, -- имя объекта (SELECT m.name FROM gd_multiname m WHERE c.id = m.refid AND m.langid = 'ru' AND m.caseid = 'G'), -- имя в нужном падеже ... FROM ... gd_contact c ...
[править] Бизнес-класс TgdcMultiName
Таблица gd_multiname является главной таблицей для бизнес-класса TgdcMultiName. Диалоговое окно для бизнес-класса TgdcMultiName должно отображать:
- Идентификатор записи для которой указано наименование (refid);
- Название таблицы;
- Исходное наименование (из таблицы заданной relationkey);
- Наименование;
- Тэг языка (TComboBox с возможностью редактирования. Выпадающий список должен содержать значения "ru", "be" и "en");
- Падеж (для выбора падежа разместить шесть радио кнопок с наименованиями падежа и падежными вопросами, и седьмую радио-кнопку "Не указан").
При нажатии на кнопку Новый в диалоговом окне, поля refid и relationkey должны получать значения из предыдущей записи.
[править] Удаление записей из таблицы gd_multiname
Поскольку refid не является внешним ключем, то применить автоматическое каскадное удаление невозможно. Для очистки таблицы от ненужных записей придется либо написать хранимую процедуру, которая для каждой записи в gd_multiname будет проверять ее существование в таблице relationkey и удалять в случае отсутствия, либо встроить такой алгоритм непосредственно в TgdcMultiLine. Вызов операции очистки базы необходимо назначить кнопке на панели инструментов окна просмотра класса TgdcMultiLine.
[править] Организация пользовательского интерфейса
Можно предложить три варианта организации пользовательского интерфейса в диалоговых окнах тех объектов, которые подразумевают наличие наименований в разных падежах и/или на разных языках:
- Добавить вкладку со списком дополнительных наименований, на которой возможно редактирование непосредственно в таблице.
- Справа от поля ввода наименования добавить кнопку "..." по которой на экране открывать окно со списком наименований (форма просмотра TgdcMultiName с настроенными ExraConditions?).
- На той же вкладке, где находится поле для ввода наименования, добавить TLabel (TEdit или TMemo, в режиме только для чтения), где отображать дополнительные наименования. Рядом разместить кнопку "..." по которой на экране открывать окно со списком наименований для редактирования.
[править] Модификация базы данных
Необходимо будет добавить процедуру в список modify для добавления таблицы gd_multiline на существующие базы.