Склонение ФИО (постановка)

Материал из GedeminWiki
(Различия между версиями)
Перейти к: навигация, поиск
(Ссылки по теме)
(Ссылки по теме)
 
(не показаны 16 промежуточных версий 1 участника)
Строка 1: Строка 1:
Предлагается решить проблемы склонения имен по падежам и хранения имен на разных языках следующим образом:
+
При оформлении различных документов на основании информации из базы данных часто возникает необходимость в склонении имен существительных по падежам. Например, справка выдана ''Петрову'', принять на работу ''Сидорова'' и т.п. Кроме этого, есть необходимость в хранении переводов наименований объектов на различные языки. Предлагается решить две указанные проблемы  следующим образом. Создаем таблицу [[GD_MULTINAME]], каждая запись которой хранит наименование для объекта заданного идентификатором '''refid''' из таблицы '''relationkey'''. Поля '''langid''' и '''caseid'''  содержат языковой тэг и падеж соответственно. Поле '''caseid''' заполняется только в тех случаях, когда это имеет смысл. Для одного объекта таблица [[GD_MULTINAME]] может содержать несколько наименований на разных языках и/или в разных падежах. В запросы, извлекающие наименование объекта мы будем добавлять '''LEFT JOIN''' на таблицу [[GD_MULTINAME]] (или использовать подзапросы в секции SELECT) для извлечения имени в нужном падеже и/или на нужном языке.
  
Создаем таблицу:
+
=== Пример использования ===
  
  CREATE TABLE gd_multiname (
+
Пусть в таблице [[GD_CONTACT]] мы имеем запись:
    refid    dintkey,
+
    langid  CHAR(20) NOT NULL,
+
    caseid  CHAR(1) NOT NULL,
+
    name    dname,
+
+
    PRIMARY KEY gp_pk_multiname (refid, langid, caseid)
+
  )
+
  
Эта таблица будет хранить название объекта с идентификатором refid, на языке langid в падеже caseid.
+
ID          NAME
 +
==========================================
 +
20000001    Иванов Иван Иванович
  
=== Идентификаторы падежей для русского языка ===
+
а в таблице [[GD_GOOD]]:
  
{| cellpadding="3" cellspacing="0" frame="box" width="30%" style="border: 1px solid darkgray;"
+
ID          NAME
|- style="font-weight: bold; background-color: #EEEEEE;"
+
==========================================
|Название
+
20000002    Мыло
|Идентификатор
+
 
|-
+
Тогда, в таблице [[GD_MULTINAME]] могут быть следующие записи:
|Именительный
+
 
|N
+
REFID        LANGID      CASEID      NAME
|-
+
=============================================================
|Родительный
+
20000001    ru          D            Иванову Ивану Ивановичу
|G
+
20000001    ru          G            Иванова Ивана Ивановича
|-
+
20000001    be          N            Іваноў Іван Іванавіч
|Дательный
+
20000002    en          NULL        Soap
|D
+
 
|-
+
Запрос, который извлечет ФИО человека в родительном падеже, будет выглядеть следующим образом:
|Винительный
+
 
|A
+
  SELECT
|-
+
    ...
|Творительный
+
    COALESCE(m.name, c.name),
|B
+
    ...
|-
+
  FROM
|Предложный
+
    ...
|L
+
    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 на существующие базы.
  
 
=== Ссылки по теме ===
 
=== Ссылки по теме ===
Строка 45: Строка 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.

[править] Организация пользовательского интерфейса

Можно предложить три варианта организации пользовательского интерфейса в диалоговых окнах тех объектов, которые подразумевают наличие наименований в разных падежах и/или на разных языках:

  1. Добавить вкладку со списком дополнительных наименований, на которой возможно редактирование непосредственно в таблице.
  2. Справа от поля ввода наименования добавить кнопку "..." по которой на экране открывать окно со списком наименований (форма просмотра TgdcMultiName с настроенными ExraConditions?).
  3. На той же вкладке, где находится поле для ввода наименования, добавить TLabel (TEdit или TMemo, в режиме только для чтения), где отображать дополнительные наименования. Рядом разместить кнопку "..." по которой на экране открывать окно со списком наименований для редактирования.

[править] Модификация базы данных

Необходимо будет добавить процедуру в список modify для добавления таблицы gd_multiline на существующие базы.

[править] Ссылки по теме

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты