« Назад
Команда
SET RELATION TO [eExpression1 INTO nWorkArea1 | cTableAlias1 [, eExpression2 INTO nWorkArea2 | cTableAlias2 ...] [IN nWorkArea | cTableAlias] [ADDITIVE]]
устанавливает связь между двумя открытыми таблицами: родительской и дочерней. Число дочерних таблиц произвольно. Тип связи – "один к одному" (1:1).
Опции и параметры:
eExpression1 – выражение, связывающее родительскую и дочернюю таблицы. Обычно это индексное выражение управляющего индекса (тега) дочерней таблицы. Установка управляющего индекса или тега может быть выполнена командой SET ORDER.
Дочерняя таблица может, впрочем, не иметь управляющего индекса, если только eExpression1 – это числовое выражение. В противном случае VFP генерирует ошибку.
Если eExpression1 – это числовое выражение и дочерняя таблица не имеет управляющего индекса, то eExpression1 вычисляется, когда файловый указатель перемещается в родительской таблице. Файловый указатель дочерней таблицы перемещается на запись с номером eExpression1.
INTO nWorkArea1 | cTableAlias1 – рабочая область или псевдоним дочерней таблицы.
eExpression2 INTO nWorkArea2 | cTableAlias2 ... – задает выражение связи (eExpression2) и еще одну дочернюю таблицу (посредством параметра nWorkArea2 | cTableAlias2), связывая ее с родительской таблицей. После запятой можно задать и другие дочерние таблицы.
IN nWorkArea | cTableAlias – рабочая область или псевдоним родительской таблицы. Если опция опущена, то в качестве родительской берется текущая таблица.
ADDITIVE – сохраняет существующие связи родительской таблицы. При отсутствии опции существующие связи будут разрушены, а новые созданы.
Связываемые таблицы обычно имеют общее поле, тогда SET RELATION связывает таблицы по этому полю. Причем дочерняя таблица должна быть по этому полю проиндексирована и этот индекс должен быть управляющим.
После установления связи любое изменение позиции файлового указателя родительской таблицы влечет перемещение позиции файлового указателя дочерней таблицы на первую соответствующую запись, то есть на запись, отвечающую выражению eExpression1. Кроме того, в Browse-окне дочерней таблицы отображаются только те ее записи, которые отвечают выражению eExpression1.
Если подходящая запись не может быть найдена, то дочерняя таблица позиционируется в конце файла.
Выполнение команды
SET RELATION TO
разрывает все связи текущей таблицы (она должна быть родительской).
Пример 1. Устанавливается связь между родительской (Books) и дочерней таблицами (BooksContent) по полю BookId.
close databases
open database 'd:\HomeLibrary\HomeLibrary'
use Books in 0
use BooksContent order tag BookId in 0
&&
&& Связываем таблицы
set relation to BookId into BooksContent in Books
&&
&& Выбираем и просматриваем таблицы
&& Если в родительской таблице выбрана запись с BookId = 1,
&& то Browse-окне дочерней таблицы отобразятся только записи,
&& имеющие BookId = 1 (рис. 15.12)
select BooksContent
browse last nowait
select Books
browse last
&& Разрываем связи в текущей рабочей области
set relation to
Рис. 15.12. Отображение связи между таблицами в Browse-окнах
Установленная связь отобразится также и в окне Data session (рис. 15.13).
Рис. 15.13. Отображение связи между таблицами в окне Data session
Пример 2. Устанавливаются связи между родительской таблицей BooksAuthors и дочерними таблицами Authors и Books.
close databases
open database 'd:\HomeLibrary\HomeLibrary'
use Authors order tag AuthorId in 0
use Books order tag BookId in 0
use BooksAuthors in 0
&&
&& Связываем таблицы
set relation to AuthorId into Authors, ;
BookId into Books in BooksAuthors
&&
&& Выбираем и просматриваем таблицы
&& Выбор записи в родительской таблице BooksAuthors приведет
&& к появлению в Browse-окнах дочерних таблиц по одной записи (рис. 15.14)
select Authors
browse last nowait
select Books
browse last nowait
select BooksAuthors
browse last
&& Разрываем все связи в текущей рабочей области
set relation to
Рис. 15.14. Родительская и две дочерние таблицы
Пример 3. Устанавливается связь с таблицей, не имеющей управляющего индекса.
close databases
open database d:\HomeLibrary\HomeLibrary
use Authors in 0
use Books in 0
&&
&& Связываем таблицы
set relation to recno('Books') into Authors in Books
&&
&& Выбираем и просматриваем таблицы
select Authors
browse last nowait
select Books
browse last
&& Разрываем связь между таблицами
set relation off into Authors
Команда
SET RELATION OFF INTO nWorkArea | cTableAlias
разрывает связь родительской таблицы, открытой в текущей рабочей области, с дочерней, задаваемой параметром nWorkArea | cTableAlias.
Команда
SET SKIP TO [TableAlias1 [, TableAlias2] ...]
создает связь "один ко многим" (1:М) между таблицами.
Опция:
TO TableAlias1 [, TableAlias2] ... – содержит псевдонимы дочерних таблиц.
Если в текущей рабочей области открыта родительская таблица, тогда вызов
SET SKIP TO
разрывает ее связь 1:М.
Чтобы установить связь 1:М, первоначально нужно, используя SET RELATION, установить связь 1:1, а затем уже употребить SET SKIP.
Нередко дочерняя таблица содержит несколько записей, отвечающих одной записи родительской таблицы. Команда SET SKIP позволяет установить связь одной записи родительской таблицы с несколькими записями дочерней. Связь проявляется следующим образом: чтобы выполнить перемещение на соседнюю запись родительской таблицы, команду SKIP потребуется употребить столько раз, сколько записей дочерней таблицы соответствует текущей записи родительской. Иными словами, файловый указатель родительской таблицы будет находиться на одной ее записи до тех пор, пока не будут выполнены перемещения по всем отвечающим ей записям дочерней таблицы.
Пусть дочерняя таблица TableAlias1 в свою очередь связана с другой таблицей TableAlias2, то есть является по отношению к ней родительской, а старшая родительская таблица связана посредством SET SKIP с таблицами TableAlias1 и TableAlias2. Тогда для перемещения с текущей записи старшей родительской таблицы на соседнюю запись команду SKIP потребуется выполнить m1 * m2 раз, где m1 и m2 – это соответственно число записей таблиц TableAlias1 и TableAlias2, отвечающих текущей записи родительской таблицы.
Пример:
close databases
&&
&& Создаем таблицу d:\Parent и заносим в нее 2 записи
create table d:\Parent free (Name C(1), Val C(10))
insert into Parent values ('a', 'Pa')
insert into Parent values ('b', 'Pb')
&&
&& Создаем таблицу d:\Child1 и заносим в нее 4 записи
select 0
create table d:\Child1 free (Name1 C(1), Val C(10))
insert into Child1 values ('a', 'Ch1a1')
insert into Child1 values ('a', 'Ch1a2')
insert into Child1 values ('b', 'Chlb1')
insert into Child1 values ('b', 'Chlb2')
&& Создаем структурный индексный CDX-файл. Имя тега любое
index on Name1 tag SomeTag
&&
&& Создаем таблицу d:\Child2 и заносим в нее 6 записей
select 0
create table d:\Child2 free (Name2 C(1), Val C(10))
insert into Child2 values ('a', 'Ch2a1')
insert into Child2 values ('a', 'Ch2a2')
insert into Child2 values ('a', 'Ch2a3')
insert into Child2 values ('b', 'Ch2b1')
insert into Child2 values ('b', 'Ch2.b2')
insert into Child2 values ('b', 'Ch2.b3')
&& Создаем структурный индексный CDX-файл. Имя тега любое
index on Name2 tag SomeTag
&& Устанавливаем связь 1:1 между Child1 и Child2,
&& беря в качестве родительской таблицу Child1
set relation to Name1 into Child2 in Child1
&& Устанавливаем связь 1:1 между Parent и Child1,
&& беря в качестве родительской таблицу Parent
select Parent
set relation to Name into Child1
&& Устанавливаем связь 1:М между Parent и Child1 и Child2
set skip to Child1, Child2
&& Перемещаемся по записям родительской таблицы
scan
? Parent.Val, Child1.Val, Child2.Val
endScan
&& Browse-окно родительской таблицы см. на рис. 15.15
browse last
Печать цикла SCAN:
Pa
|
Ch1a1
|
Ch2a1
|
Pa
|
Ch1a1
|
Ch2a2
|
Pa
|
Ch1a1
|
Ch2a3
|
Pa
|
Ch1a2
|
Ch2a1
|
Pa
|
Ch1a2
|
Ch2a2
|
Pa
|
Ch1a2
|
Ch2a3
|
Pb
|
Ch1b1
|
Ch2b1
|
Pb
|
Ch1b1
|
Ch2b2
|
Pb
|
Ch1b1
|
Ch2b3
|
Pb
|
Ch1b2
|
Ch2b1
|
Pb
|
Ch1b2
|
Ch2b2
|
Pb
|
Ch1b2
|
Ch2b3
|
Рис. 15.15. Таблица Parent
Функция
RELATION(nRelationNumber [, nWorkArea | cTableAlias])
возвращает строку, содержащую выражение связи для текущей или заданной параметром nWorkArea | cTableAlias таблицы. Выбранная таблица должна быть родительской.
Параметр:
nRelationNumber – номер выражения. Определяется местом выражения в команде SET RELATION; при этом последнее выражение имеет номер 1.
Пример:
close databases
open database 'd:\HomeLibrary\HomeLibrary'
use Authors order tag AuthorId in 0
use Books order tag BookId in 0
use BooksAuthors in 0
&&
&& Связываем таблицы
set relation to AuthorId into Authors, BookId into Books in BooksAuthors
&&
&& Печатаем выражения связи и псевдонимы дочерних таблиц
? Relation(1, "BooksAuthors") && Напечатает: BookId
? Relation(2, "BooksAuthors") && Напечатает: AuthorId
? Target(1, "BooksAuthors") && Напечатает: Books
? Target(2, "BooksAuthors") && Напечатает: Authors
set relation to
Замечание. Выражения связи также печатает команда DISPLAY | LIST STATUS.
Функция
TARGET(nRelationNumber [, nWorkArea | cTableAlias])
возвращает строку, содержащую псевдоним дочерней таблицы, для родительской таблицы. Последняя является либо текущей, либо задается параметром nWorkArea | cTableAlias.
|