Rambler's Top100

(c)2009-2017 openinfotech.ru

СУБД HyTech

Документация
Функция htFilterTables - Фильтрация группы связанных таблиц

htFilterTables - Фильтрация группы связанных таблиц

Назначение:

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

В результате выполнения операции устанавливается соответствие запись-запись-..-запись заданного числа исходных таблиц. Порядок расположения составляющих таблиц в результате определятся порядком перечисления таблиц во втором параметре.

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

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

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

  • дерево связей может иметь только одну вершину;
  • сыновья должны быть описаны ниже родителей.

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

Пусть таблицы связаны следующим образом:

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

и описать связи: 1-2, 1-3, 1-4

Алгоритм связывания таблиц работает следующим образом:

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

Прототип:

 LPSAB pascal htFilterTables(
	LPSAB   	fpDst,    	/* Для приема результатов */
	LPPSAB  	fppSABs,  	/* Группа таблиц и подмножества записей в них */
	int     	nTabCnt,  	/* Число таблиц */
	int far 	*fpnField,	/* Номера полей таблиц для анализа */
	int     	nFieldCnt,	/* Число полей */
	LPTLINK 	fpLinks,  	/* Описатели связей таблиц */
	int     	nLinkCnt, 	/* Число связей */
	LPSFUNC 	fpfFilter,	/* Пользовательская функция фильтрации */
	void far	*fpUser,  	/* Параметр пользователя */
	int     	nMode     	/* Режимы связывания таблиц */
 );

Параметры

fpDst
определяет адрес БДС, предназначенного для хранения результата слияния таблиц
fppSABs
задает массив адресов БДС. Каждый БДС содержит некоторое (м.б.полное) множество записей очередной таблицы из группы и определяет "снимок" этой таблицы
nTabCnt
задает число таблиц, входящих в связку
fpnField
задает номера полей, которые нужно "вырезать" из "композитной" записи для того, чтобы принять решение о пригодности записи. Предполагается сквозная нумерация всех полей "композитной" записи, включая физический номер для каждой составляющей записи. Если поля отбора не заданы (NULL) - отбирается вся поля всех записей целиком
nFieldCnt
задает число отбираемых полей или 0, если поля отбора не заданы
fpLinks
задает адрес массива описателей связей таблиц. Каждый элемент массива описывает одну связь пары таблиц. Число связей таблиц ограничено ресурсами машины. Структура описателя связи имеет тип TLINK. Под порядковым номером таблицы понимается ее индекс в массиве БДС'ов (параметр fppSABs).
nLinkCnt
задает число описателей связей
fpfFilter
должен содержать адрес пользовательской функции фильтрации. Если он не задан все кандидаты попадут в результат. Функция имеет прототип SFUNC
fpUser
можно использовать для передачи дополнительных параметров в пользовательскую функцию фильтрации. Значение параметра будет передано в функцию фильтрации
nMode
задает режим связывания таблиц. Возможное управление связыванием таблиц определяется константами FLT_???

Результат:

адрес БДС, заданный в качестве первого параметра В случае успешного завершения
NULL Ошибка, Код ошибки будет занесен в поле fpDst->nRetCode

Пример

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

 typedef struct tagREPUBLIC { /* Структура записи таблицы республик */
     char code; /* Поле-связка с таблицей CLIENT */
     char rep[30];
 } REPUBLIC;
 typedef struct tagROOM { /* Структура записи таблицы кабинетов */
     int room; /* Поле-связка с таблицей CLIENT */
     int floor;
 } ROOM;
 typedef struct tagCLIENT { /* Структура записи таблицы больных */
     char name[15];
     char address[50];
     char sex;
     char code; 	 /* Поле-связка с таблицей REPUBLIC */
     int room; 	 /* Поле-связка с таблицей ROOM */
 } CLIENT;
 SAB asTabs[3];
 SAB sRes;
 TLINK asLinks = {
	{ 0, 4, 1, 1 },	/* Связь CLIENT.code - REPUBLIC.code */
	{ 0, 5, 2, 1 },	/* Связь CLIENT.room - ROOM.room */
 };
 int anFld[] = { 1,2,3,8,10 }; /* Закажем отбор полей: */
 /* CLIENT.name, CLIENT.address, CLIENT.sex, REPUBLIC.rep и ROOM.room*/
 /* Функция фильтрации, которая пропускает все */
 static SFUNC Filter
 {
	return 1;
 }
 THANDLE hClient;
 THANDLE hRepub;
 THANDLE hRoom;
 . . .
 /* Мужчины-больные */
 htSearch( NULL, asTabs+0, hClient, 3, EQUAL, "M", NULL );
 . . .
 /* Код республики по названию */
 htSearch( NULL, asTabs+1, hRepub, 2, EQUAL, "КАЗАХСТАН", NULL );
 . . .
 /* Кабинеты второго этажа */
 htSearch( NULL, asTabs+2, hRoom, 2, EQUAL, "\2", NULL );
 . . .
 /* Больные мужчины из Казахстана, посещающие кабинеты второго этажа */
 htFilterTables( &sRes, asTabs, 3, NULL, 0, asLinks, 2, Filter, NULL );
 . . .
 printf( "Найдено %ld больных\n", sRes.gFoundCnt );