Распечатать страницу

Связывание таблиц в Visual FoxPro

« Назад

Команда

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

229.1.-Отображение-связи-между-таблицами-в-Browse-окнах

Рис. 15.12. Отображение связи между таблицами в Browse-окнах

Установленная связь отобразится также и в окне Data session (рис. 15.13).

229.2.-Отображение-связи-между-таблицами-в-окне-Data-session

Рис. 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

229.3.-Родительская-и-две-дочерние-таблицы

Рис. 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

229.4.-Таблица-Parent

Рис. 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.