7618

Средства обработки БД в СУБД FoxPro

Лекция

Информатика, кибернетика и программирование

Средства обработки БД в СУБД FoxPro. Синтаксис и семантика основных операторов. SELECT 0 Выбрать свободную рабочую область и установить её текущей рабочей областью. Понятие рабочая область в определенном смысле соответствует понятию о...

Русский

2013-01-26

76.5 KB

4 чел.

Средства обработки БД в СУБД FoxPro.

Синтаксис и семантика основных операторов.

  •  SELECT 0

Выбрать свободную рабочую область и  установить её текущей рабочей областью.

Понятие «рабочая область» в определенном смысле соответствует понятию «объект типа TTable» в Delphi.

  •  USE ИмяТаблицы

Открыть таблицу в текущей рабочей области. ИмяТаблицы становится псевдонимом этой рабочей области.

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

  •  USE

Закрыть таблицу в текущей рабочей области. Рабочая область при этом теряет соответствующий псевдоним.

  •  SELECT ПсевдонимРабочейОбласти

Установить текущей рабочую область с указанным псевдонимом. Текущая таблица – открытая в текущей рабочей области. В операторах FoxPro обычно не указано явно, с какой таблицей он работает, всегда имеется в виду – с таблицей, открытой в текущей рабочей области.

  •  USE ИмяТаблицы AGAIN ALIAS Псевдоним

Открыть таблицу в текущей рабочей области. Явно указанный Псевдоним становится псевдонимом этой рабочей области.

Обычно невозможно открыть таблицу еще раз, если она уже открыта в какой-либо рабочей области. Оператором USE в такой форме (с AGAIN) таблицу можно открыть еще раз. При этом надо явно указать псевдоним (ALIAS) для текущей рабочей области, чтобы иметь возможность по псевдонимам различать две рабочие области, в которых открыта одна и та же таблица.

Зачем такое нужно? Например, в задаче «Построить декартово произведение ТхТ», открыв одну таблицу два раза, мы сможем во внешнем цикле перебирать строки этой таблицы в рабочей области с первым псевдонимом, а во внутреннем цикле независимо перебирать строки этой же таблицы в рабочей области со вторым псевдонимом (без сшибания положения маркера текущей строки). Эта возможность соответствует возможности в Delphi использовать два объекта типа TTable для независимого управления работой с одной и той же таблицей.

  •  Уточненное имя поля: Псевдоним.ИмяПоля 

Так можно сослаться на поле таблицы, открытой в другой (не текущей) рабочей области.

  •  GO TOP

Установиться на 1-ю строку текущей таблицы (открытой в текущей рабочей области).

1-я имеется в виду в логическом порядке. Физический порядок строк считается логическим порядком по умолчанию. Для явной установки других логических порядков используются индексы.

  •  SKIP

Переместиться к следующей (в логическом порядке) строке в текущей таблице.

  •  SKIP k

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

  •  SEEK Выражение

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

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

  •  SET RELATION TO ВыражениеКлючаСвязи INTO Псевдоним

Этот оператор устанавливает операционную связь (типа Master -> Detal в Delphi). Ведущая (Master) таблица – текущая таблица, ведомая (Detal) таблица – таблица, открытая в рабочей области с указанным псевдонимом. При перемещении по строкам ведущей таблицы в ведомой таблице будет автоматически устанавливаться текущая строка с ключом – текущим значением ВыражениеКлючаСвязи.

  •  LOCATE ALL FOR Условие

Переместиться в текущей таблице на строку, удовлетворяющую Условие.

Строк, удовлетворяющих условию, может быть несколько, тогда устанавливается первая (в логическом порядке) из таких строк. Остальные можно перебрать (в цикле) оператором «Продолжить поиск строк, удовлетворяющих условию»:

CONTINUE

  •  APPEND BLANK

Добавить (в конец) пустую строку в текущую таблицу.

  •  REPLACE ИмяПоля WITH Выражение, . . .

Заменить в текущей строке текущей таблицы значение поля ИмяПоля на значение выражения Выражение

REPLACE ALL ИмяПоля WITH Выражение, . . .

заменить во всех строках...

  •  
    COPY ALL TO
    ИмяТаблицы FIELDS ИмяПоля, ... FOR Условие

Создается новая таблица ИмяТаблицы. В ней будут поля текущей таблицы, перечисленные в FIELDS. В неё попадут строки текущей таблицы, удовлетворяющие FOR-Условию.

Новая таблица не открывается, для этого надо выбрать рабочую область (SELECT 0) и открыть (USE ...).

  •  Обычные средства процедурного программирования.
  •  Оператор присваивания.

ИмяПеременной = Выражение

Не следует путать понятия «Переменная» и «Поле таблицы», и то и другое можно использовать для построения выражений, но в левой части не может стоять имя поля.

  •  Условный оператор.

IF Условие

...

ELSE

...

ENDIF

Особенности этого синтаксиса - IF ELSE ENDIF пишутся в отдельных строках, а между ними then и else вложенные операторы.

  •  Оператор цикла

DO WHILE Условие

...

ENDDO


ПРИМЕРЫ.

База данных содержит файлы - ПОСТАВЩИКИ, ДЕТАЛИ и ПОСТАВКИ. Файл ПОСТАВЩИКИ (Psts) имеет поля - код поставщика (KPst - уникальный ключ), наименование поставщика (ImPst), адрес поставщика (AdrPst). Файл ПОСТАВКИ (Pst) содержит сведения о том, «кто» - «что» - «в каком количестве» поставил, и имеет поля - код поставщика (KPst), код детали (KDet), количество (Kol).

CREATE TABLE Psts (KPst N(4),ImPst C(20),AdrPst C(30))

CREATE TABLE Pst (KPst N(4),KDet N(6),Kol N(10))

Сформировать список крупных (в количестве > 1000) поставок детали с кодом 1010: наименование поставщика, размер поставки.(*)

Решение 0. Используется SQL-запрос

SELECT Psts.ImPst,Pst.Kol ;

 FROM Pst,Psts INTO TABLE Otvet ;

 WHERE (Psts.KPst=Pst.KPst).AND.;

       (Pst.KDet=1010).AND.(Pst.Kol>1000)

Решение 1. Используются средства работы с файлами на уровне записей (уровень языка Паскаль).

SELECT 0

CREATE TABLE Otvet (ImPst C(20), Kol N(10))

SELECT 0

USE Psts

SELECT 0

USE Pst

GO TOP

DO WHILE NOT EOF()

IF (Pst.KDet=1010) AND (Pst.Kol>1000)

 SELECT Psts

 GO TOP

DO WHILE NOT EOF()

IF Psts.KPst=Pst.KPst

 SELECT Otvet

 APPEND BLANK

 REPLACE ImPst WITH Psts.ImPst,Kol WITH Pst.Kol

 EXIT

ENDIF

 SKIP

ENDDO

ENDIF

 SELECT Pst

 SKIP

ENDDO

Решение 2. Используется LOCATE

SELECT 0

CREATE TABLE Otvet (ImPst C(20), Kol N(10))

SELECT 0

USE Psts

SELECT 0

USE Pst

LOCATE ALL FOR (Pst.KDet=1010) AND (Pst.Kol>1000)

DO WHILE FOUND()

 SELECT Psts

 LOCATE ALL FOR Psts.KPst=Pst.KPst

 SELECT Otvet

 APPEND BLANK

 REPLACE ImPst WITH Psts.ImPst,Kol WITH Pst.Kol

 SELECT Pst

 CONTINUE

ENDDO

Решение 3. Используется SEEK

SELECT 0

CREATE TABLE Otvet (ImPst C(20), Kol N(10))

SELECT 0

USE Psts

INDEX ON KPst TO Psts

SELECT 0

USE Pst

LOCATE ALL FOR (Pst.KDet=1010) AND (Pst.Kol>1000)

DO WHILE FOUND()

 SELECT Psts

 SEEK Pst.KPst

 SELECT Otvet

 APPEND BLANK

 REPLACE ImPst WITH Psts.ImPst,Kol WITH Pst.Kol

 SELECT Pst

 CONTINUE

ENDDO

Решение 4. Используется RELATION

SELECT 0

USE Psts

INDEX ON KPst TO Psts

SELECT 0

USE Pst

SET RELATION TO KPst INTO Psts

GO TOP

COPY ALL TO Otvet FIELDS Psts.ImPst,Pst.Kol ;

FOR (Pst.KDet=1010) AND (Pst.Kol>1000)

Запрос реляционного исчисления кортежей.

НАЙТИ{(r.ImPst)/rPsts} detDet ((det.Cvet#'КРАСНЫЙ')

dogDog ((dog.KDet=det.KDet)(dog.KPst=r.KPst)))

SELECT 0

USE Dog

SELECT 0

USE Det

SELECT 0

USE Psts

GO TOP

DO WHILE NOT EOF()

SELECT Det

GO TOP

detA=.T.

DO WHILE detA AND NOT EOF()

IF Cvet='КРАСНЫЙ'

SELECT Dog

GO TOP

dogE=.F.

DO WHILE NOT dogE AND NOT EOF()

IF (KDet=Det.KDet) AND (KPst=Psts.KPst)

dogE=.T.

ENDIF

SKIP

ENDDO && цикл можно заменить на LOCATE

detA=dogE

SELECT Det

ENDIF && можно заменить на LOCATE и CONTINUE

SKIP

ENDDO

SELECT Psts

IF detA

{вывести, т.к. нашли поставщика, такого что...}

ENDIF

SKIP

ENDDO

Выражение реляционной алгебры.

[ImPst](Psts*(([KPst,KDet]Dog)

  ([KDet]([Cvet='КРАСНЫЙ']Det))))

Схема (в лоб) соответствующей программы:

  •  Сформировать файл W1 кодов красных деталей (делитель).

SELECT Det

COPY ALL TO W1 FOR Cvet='КРАСНЫЙ' FIELDS KDet

  •  Сформировать файл W2 – делимое.

SELECT Dog

COPY ALL TO W2 FIELDS KPst,KDet

  •  Сформировать файл W3=(W2W1).

Деление реализуется довольно громоздко, т.к. оно имеет -определение:

W3=(W2W1) = НАЙТИ{(r.KPst)/rW2}

sW1 tW2 ((t.KDet=s.KDet)(t.KPst=r.KPst))

Согласно этому определению его можно реализовать, как было описано выше. А за одно можно получить и окончательный ответ, т.к.

[ImPst](Psts*W3) = НАЙТИ{(r.ImPst)/rPsts}

sW1 tW2 ((t.KDet=s.KDet)(t.KPst=r.KPst))

SELECT 0

CREATE TABLE Otvet (ImPst C(20))

SELECT Psts

GO TOP

DO WHILE NOT EOF()

AllDet=.T.

SELECT W1

GO TOP

DO WHILE AllDet AND NOT EOF()

SELECT W2

LOCATE ALL FOR (W2.KDet=W1.KDet) AND ;

(W2.KPst=Psts.KPst)

 AllDet=FOUND()

 SELECT W1

 SKIP

ENDDO

IF AllDet

 SELECT Otvet

 APPEND BLANK

 REPLACE ImPst WITH Psts.ImPst

ENDIF

SELECT Psts

SKIP

ENDDO

Реализация того же запроса на SQL (FoxPro)

CLOSE ALL

*!* CREATE DATABASE Dogovora

*!* CREATE TABLE Psts (ImPst C(20),AdrPst C(30), KPst N(4) PRIMARY KEY)

*!* CREATE TABLE Det (ImDet C(25),Cvet C(10), KDet N(6) PRIMARY KEY)

*!* CREATE TABLE Dog (Kol N(10) CHECK Kol>0,;

*!*     KPst N(4) REFERENCES Pst NOT NULL,;

*!*     KDet N(6) REFERENCES Detali NOT NULL)

*!* OPEN DATABASE Dogovora

*!* SELECT 0

*!* USE Psts

*!* SELECT 0

*!* USE Detali

*!* SELECT 0

*!* USE Dog

*!* SELECT 0

SELECT Det.KDet,Psts.KPst FROM Det,Psts INTO CURSOR W2 ;

 WHERE (Det.Cvet=[Красный])

SELECT W2.KDet,W2.KPst FROM W2 INTO CURSOR W1 ;

 WHERE NOT EXISTS (SELECT * FROM Dog ;

   WHERE (Dog.KDet=W2.KDet) AND ;

    (Dog.KPst=W2.KPst))

*!* Тоже не удовлетворяет ограничениям FoxPro

*!* SELECT Det.KDet,Psts.KPst FROM Det,Psts INTO CURSOR W1 ;

*!*   WHERE (Det.Cvet=[Красный]) AND ;

*!*    NOT EXISTS (SELECT * FROM Dog ;

*!*     WHERE (Dog.KDet=Det.KDet) AND ;

*!*      (Dog.KPst=Psts.KPst))

SELECT Psts.ImPst FROM Psts INTO TABLE Result ;

WHERE NOT EXISTS (SELECT * FROM W1 WHERE W1.KPst=Psts.KPst)

*!* Хорошо соответствует запросу исчисления кортежей, но не

*!* удовлетворяет ограничениям FoxPro

*!* SELECT Psts.ImPst FROM Psts INTO TABLE Result ;

*!*  WHERE NOT EXISTS (SELECT * FROM Det ;

*!*   WHERE (Det.Cvet=[Красный]) AND ;

*!*    NOT EXISTS (SELECT * FROM Dog ;

*!*     WHERE (Dog.KDet=Det.KDet) AND ;

*!*      (Dog.KPst=Psts.KPst)))

BROW

Пример из методического материала к курсовому проекту.

Найти наименования покупателей из Казани, которые до 1 января 2003 года покупали каждый товар, имеющий цену выше 100.

Запрос реляционного исчисления кортежей:

НАЙТИ{(p.POKUP)/pPOKUPATELI} (p.GOROD='Казань')  tTOVARY

((t.ZENA <=100)  rRASXOD ((r.DATA_RASH<’01.01.2003’)

(r.KOD_TOVAR =t.KOD_TOVAR)(r.KOD_POKUP =p.KOD_POKUP)))

Рассмотрим схему (лобовой) реализации этого запроса традиционными средствами уровня языка Паскаль.

SELECT 0

USE New2

ZAP

SELECT 0

USE Tovary

SELECT 0

USE Rasxod

SELECT 0

USE Pokupateli

GO TOP

DO WHILE NOT EOF()

IF Gorod=’Казань’

 aT=.T.

 SELECT Tovary

 GO TOP

 DO WHILE aT AND NOT EOF()

   aT=(Zena <=100)

   IF NOT aT

     eR=.F.

     SELECT Rasxod

     GO TOP

     DO WHILE NOT eR AND NOT EOF()

       eR=(Data_Rash<{01.01.2003})AND;

     (Kod_Tovar=Tovary.Kod_Tovar)AND;

(Kod_Pokup=Pokupateli.Kod_Pokup)

       SKIP

     ENDDO

     aT=eR

SELECT Tovary

   ENDIF

   SKIP

 ENDDO

 IF aT

   SELECT New2

   APPEND BLANK

   REPLACE Pokup WITH Pokupateli.Pokup

 ENDIF

 SELECT Pokupateli

ENDIF

 SKIP

ENDDO

Примечание.

Выделенный жирным курсивом фрагмент можно заменить на:

SELECT Rasxod

LOCATE ALL FOR (Data_Rash<{01.01.2003})AND;

     (Kod_Tovar=Tovary.Kod_Tovar)AND;

(Kod_Pokup=Pokupateli.Kod_Pokup)

aT=FOUND()

SELECT Tovary

(*) Hижеприведенные решения эквивалентны только при наличии Psts.KPst для каждого Pst.KPst - хороший повод поговорить о ссылочной целостности БД и влиянии централизованного ее контроля на составление программ.


 

А также другие работы, которые могут Вас заинтересовать

50813. ИЗМЕРЕНИЕ ПЕРЕМЕННОГО ЭЛЕКТРИЧЕСКОГО НАПРЯЖЕНИЯ 248.5 KB
  Получение навыков измерения переменного электрического напряжения; 1. Ознакомление с особенностями влияния формы и частоты измеряемого напряжения на показания средств измерений; 1. Приобретение представления о порядке работы с электроизмерительными приборами при измерении переменного напряжения.
50814. Программирование в Delphi. Разработка интерфейса 1.69 MB
  Цель: Получить первичные навыки работы в визуальной среде программирования Delphi. При этом становится активным окно редактора кода и Delphi автоматически создает ОБРАБОТЧИК СОБЫТИЯ – процедуру выполняющуюся при нажатии кнопки В окне редактора кода ввести соответствующие команды Прежде всего необходимо научиться сохранять свои программы.
50816. Язык гипертекстовой разметки HTML 85.5 KB
  На самом деле содержимое контейнера mrquee не ограничивается строками и позволяет перемещать скролировать любые элементы вебстраницы изображения текст таблицы элементы форм и т. Таблицы Элемент tble служит контейнером для элементов определяющих содержимое таблицы. Параметры lign Определяет выравнивание таблицы. bgcolor Цвет фона таблицы.
50817. Определение теплоёмкости металлов методом охлаждения 154.5 KB
  Металлический образец, имеющий температуру более высокую, чем температура окружающей среды, в этой среде охлаждается. Кол-во теплоты q , теряемой образцом металла за единицу времени t может быть записано в виде...
50818. Каскадные листы стилей CSS 330.5 KB
  Значение 0 соответствует полной прозрачности элемента а 1 наоборот его непрозрачности.2 Oper 9 border позволяет одновременно установить толщину стиль и цвет рамки вокруг элемента.
50819. Построение и экспериментальная проверка статической характеристики замкнутой системы 868 KB
  Освоить методику аналитического построения статической характеристики замкнутой САР по статическим характеристикам отдельных элементов. Под статической характеристикой замкнутой САР понимают функциональную зависимость регулируемой величины от задающего и возмущающих воздействий снятую на установившихся режимах. Если регулируемая величина на установившемся режиме не зависит от возмущающих воздействий то такая система называется астатической а если зависит то статической.