Программирование на Microsoft Access с нуля
|
|
Перекрестный запрос представляет данные в более компактном виде, чем обычный, позволяя указать имя поля или выражение, используемое в качестве заголовков столбцов. TRANSFORM не обязательно, но если указано, должно быть первым в строке запроса. Оно предшествует оператору SELECT, указывающему поля, используемые в качестве названий строк, и выражению GROUP BY, указывающему способ группировки строк. Можно включать другие выражения, например WHERE, для указания критериев отбора и сортировки. Можно также использовать подзапросы в выражении WHERE. Значения, возвращаемые в pivotfield, используются как заголовки столбцов в результирующем запросе. Например, использование названия месяца в качестве pivotfield приведет к запросу с двенадцатью столбцами. Можно ограничить число столбцов, создав заголовки из набора констант, перечисленных в выражении IN (значения, не входящие в набор, будут отфильтрованы).
Следующий пример можно ввести в SQL-окне конструктора запросов:
1. Помесячный объем продаж. Месяцы – названия столбцов, товары – названия строк
PARAMETERS [Sales for which year?] LONG;
TRANSFORM Sum([Order Details].Quantity *
([Order Details].UnitPrice - ([Order Details].Discount / 100) *
[Order Details].UnitPrice)) AS Sales
SELECT ProductName FROM Orders INNER JOIN
Products INNER JOIN [Order Details]
ON Products.ProductID = [Order Details].ProductID)
ON Orders.OrderID = [Order Details].OrderID
WHERE DatePart("yyyy", OrderDate) = [Sales for which year?]
GROUP BY ProductName ORDER BY ProductName
PIVOT DatePart("m", OrderDate);
Выражение PROCEDURE
Определяет имя и, при необходимости, параметры запроса. Формат:
PROCEDURE name [param1 datatype[, param2 datatype[, ...]]
Оператор PROCEDURE имеет следующие части:
|
Процудура SQL состоит из выражения PROCEDURE, определяющего имя процедуры, не обязательного списка определения параметров и одного оператора SQL. Если выражение включает несколько определений полей (пары param-datatype), они разделяются запятыми. За выражением должен следовать оператор SQL (SELECT, UPDATE и т.п.). Введенное в SQL-режиме конструктора запросов выражение PROCEDURE, удаляется при переключении в другой режим, при этом результат запроса не меняется. Если были определены параметры, то выражение PROCEDURE заменяется выражением PARAMETERS.
В следующем примере вводится имя запроса CategoryList (используется функция SQLTRANSFORMOutput):
Sub ProcedureX()
Dim dbs As Database, rst As Recordset
Dim qdf As QueryDef, strSql As String
' Modify this line to include the path to Northwind on your computer.
Set dbs = OpenDatabase("Northwind.mdb")
strSql = "PROCEDURE CategoryList; " _
& "SELECT DISTINCTROW CategoryName, " _
& "CategoryID FROM Categories ORDER BY CategoryName;"
' Create a named QueryDef based on the SQL statement.
Set qdf = dbs.CreateQueryDef("NewQry", strSql)
' Create a temporary snapshot-type Recordset.
Set rst = qdf.OpenRecordset(dbOpenSnapshot)
rst.MoveLast ' Populate the Recordset.
' Call EnumFields to print the contents of the Recordset.
' Pass the Recordset object and desired field width.
EnumFields rst, 15
' Delete the QueryDef because this is a demonstration.
dbs.QueryDefs.Delete "NewQry"
dbs.Close
End Sub
Объявление PARAMETERS
Объявляет имя и тип параметра в параметрическом запросе. Формат:
PARAMETERS name datatype [, name datatype [, ...]]
Объявление PARAMETERS имеет следующие части:
|
Обявление параметров позволяет менять условия запроса, т.к. они запрашиваются при его выполнении. Объявление не обязательно, но если есть, должно предшествовать другим операторам. Если оно включает более одного параметра, они разделяются запятыми. Следующее объявление включает два параметра
PARAMETERS [Low price] Currency, [Beginning date] DateTime;
Объявленные имена можно использовать в выражениях WHERE и HAVING:
PARAMETERS [Low price] Currency, [Beginning date] DateTime;
SELECT OrderID, OrderAmount FROM Orders WHERE OrderAmount > [Low price] AND OrderDate > = [Beginning date];
Параметры запрашиваются при каждом выполнении запроса, что позволяет пользователю ввести нужные значения. Объявление PARAMETERS эквивалентно определению параметров в ячейках Criteria конструктора запросов.
Для выполнения следующего примера нужно создать новый запрос в базе Northwind и ввести в режиме SQL:
PARAMETERS [Enter a Last Name:] Text;
SELECT * FROM Employees WHERE LastName =[Enter a Last Name:];
Запрос будет запрашивать у пользователя Last Name. Аналогично, запрос
PARAMETERS [Enter a Category ID:] Value;
SELECT CategoryID, ProductName, Count([Order Details].OrderID) AS Tally FROM Products
INNER JOIN [Order Details] ON Products.ProductID = [Order Details].ProductID
GROUP BY CategoryID, ProductName HAVING CategoryID = [Enter a Category ID:];
будет запрашивать Category ID.
Оператор UPDATE
Создает запрос на обновление, изменяющий значения полей в указанной таблице согласно указанному критерию. Формат:
UPDATE table SET newvalue WHERE criteria;
Оператор UPDATE имеет следующие части:
|
UPDATE особенно полезен при изменении большого числа записей или записей в нескольких таблицах. Позволяет изменять сразу несколько полей:
UPDATE Orders SET OrderAmount = OrderAmount * 1.1,
Freight = Freight * 1.03 WHERE ShipCountry = 'UK';
– увеличивает в таблице Order все значения Amount на 10% и Freight на 3% для заказов, доставляемых в United Kingdom.
- Операцию UPDATE нельзя отменить; если нужно предварительно узнать, какие записи будут изменены, используется оператор SELECT с тем же критерием отбора.
- Полезно иметь страховочную копию – при неправильном изменении можно восстановить старые значения.
Поскольку UPDATE не формирует результат как набор записей, в Microsoft Access нельзя непосредственно вывести результат оператора. Если нужно подтверждать каждое изменение, можно использовать команду Replace меню Edit в форме.
Следующие запросы меняют таблицы в базе Northwind (если изменения нежелательны, нужно предварительно сделать копию, отменить нельзя)
UPDATE Employees SET ReportsTo = 5 WHERE ReportsTo = 2;
– полю ReportsTo присваивается значение 5 во всех записях таблицы Employees, в которых ReportsTo было равно 2
UPDATE Products SET UnitPrice = UnitPrice * 1.1
WHERE SupplierID = 8 AND Discontinued = No;
– цена UnitPrice в таблице Products увеличивается на 10% для всех товаров поставщика №8, у которых нет скидки.
UPDATE Suppliers INNER JOIN Products ON Suppliers.SupplierID = Products.SupplierID
SET UnitPrice = UnitPrice * .95
WHERE CompanyName = 'Tokyo Traders' AND Discontinued = No;
– цена UnitPrice уменьшается на 5% для всех товаров без скидки, поставляемых Tokyo Traders. Таблицы Products и Suppliers имеют отношение n:1.
Оператор INSERT INTO
Добавляет одну или несколько записей в таблицу. Формат добавления нескольких записей:
INSERT INTO target [IN externaldatabase] [(field1[, field2[, ...]])]
SELECT [source.]field1[, field2[, ...] FROM tableexpression
Формат добавления одной записи:
INSERT INTO target [(field1[, field2[, ...]])] VALUES (value1[, value2[, ...])
Оператор INSERT INTO имеет следующие части:
|
Для добавления одной записи в таблицу в указывается имя и значение каждого поля. Если какое-либо поле не указано, ему присваивается значение Null, запись добавляется в конец таблицы. Если список полей не указан, значения в выражении VALUES должны ссответствовать каждому полю таблицы, иначе произойдет ошибка. В окне конструктора Microsoft Access преобразует выражение VALUES в SELECT. Рузультат тот же. При добавлении сразу нескольких записей они берутся из другой таблицы или запроса. В этом случае выражение SELECT определяет поля, которые нужно добавить. INSERT INTO должно предшествовать выражению SELECT. Чтобы посмотреть, что добавляется, нужно составить запрос на выборку с теми же условиями.
source и target могут быть запросами. Если в качестве target указан запрос, данные добавляются во все таблицы, входящие а запрос. Если target имеет первичный ключ, то в него должно обязательно вводиться уникальное значение, иначе запись не добавится и произойдет ошибка. Если target содержит поле типа AutoNumber и надо продолжать нумерацию, его не нужно включать в список полей. Оно включается только, если нужно сохранить его исходное (из source) значение. Для добавления записей в другую базу используется выражение IN.
Для создания новой таблицы вместо запроса на создание лучше использовать SELECT...INTO. INSERT INTO не влияет на таблицы источники. Использование оператора INSERT INTO эквивалентно установке свойства DestinationTable в окне свойств запроса на добавление в конструкторе запросов
Следующие запросы меняют таблицы в базе Northwind (если изменения нежелательны, нужно предварительно сделать копию).
В следующем примере запрос добавляет все записи из таблицы NewCustomers в Customers (NewCustomers нужно сделать как копию Customers):
INSERT INTO Customers SELECT * FROM NewCustomers;
Добавление записи в таблицу Employees
INSERT INTO Employees (FirstName,LastName, Title)
VALUES ('Harry', 'Washington', 'Trainee');
Оператор DELETE
Удаляет записи из таблицы/таблиц, указанных в выражении FROM, удовлетворяющие условию WHERE. Формат:
DELETE [table.*] FROM table WHERE criteria
Оператор DELETE имеет следующие части:
|
Для удаления таблицы используется оператор DROP, но при этом удаляется и ее структура. DELETE удаляет только данные. Запись удаляется целиком, если нужно удалить только значение поля/полей, используется запрос на обновление и в поле заносится Null. Оператор DELETE особенно полезен, если нужно удалить сразу много записей. Оператор DELETE не создает набора записей. Чтобы узнать, какие записи удаляются, нужно предварительно сделать запрос на выборку с тем же criteria. Операцию нельзя отменить, неправильно удаленные записи можно восстановить только из резервной копии.
Если удаляется запись из таблицы, входяшей в отношение 1:n со стороны 1 и разрешено каскадное удаление, то записи, относящиеся к ней со стороны n, тоже будут удалены. Например, если такое отношение установлено для таблиц Customers и Orders (1:n), то удаление записи о клиенте автоматически вызовет удаление записей о его заказах.
В следующем примере удаляются все служащие Trainee ():
DELETE * FROM Employees WHERE Title = 'Trainee';
Изменение структуры
Прежде чем работать с данными непосредственно нужно подготовить структуру таблиц для их хранения и указать некоторые свойства этих данных. Прежде всего нужно создать таблицу либо на основе существующей (SELECT...INTO), либо новую (CREATE TABLE). В последнем случае нужно также указать свойства полей – тип, размер, уникальность и т.п.. Последнее выполняется выражением CONSTRAINT. Существующую таблицу можно изменить (ALTER TABLE) или удалить (DROP). Для ускорения поиска в таблице строятся индексы (CREATE INDEX),
которые также можно удалять (DROP). С помощью индекса можно также обуспечить уникальность значений поля
Следует иметь в виду, что создание и последующее удаление таблиц приводит к «распуханию» базы, поэтому в ряде случает выгоднее иметь пустую таблицу для работы, нежели создавать каждый раз по мере необходимости.
Оператор SELECT...INTO
Создает запрос, формирующий таблицу. Формат
SELECT field1[, field2[, ...]] INTO newtable [IN externaldatabase]
FROM source
Оператор SELECT...INTO имеет следующие части:
|
С помощью этого запроса можно сделать архивную копию таблицы, копию для экспорка в другую базу или источник записей для отчета (например, отчет о месячных продажах по регионам можно сделать на основе одного и того же запроса). Чтобы узнать, какие записи будут скопированы, можно сперва выбрать их с помощью оператора SELECT и использовать тот же критерий отбора.
При создании новой таблицы ее поля наследуют только тип и размер источника, другие свойства (индекс, первичный ключ) нужно создавать специально. Для добавления данных к существующей таблице можно использовать оператор INSERT INTO вместо запроса на добавление.
Следующий пример копирует все записи из таблицы Employees в новую таблицу Emp Backup:
SELECT * INTO [Employees Backup] FROM Employees;
Следующий запрос создает таблицу Sales Representatives, содержающую только со служащих Sales Representative:
SELECT Employees.FirstName, LastName INTO [Sales Representatives]
FROM Employees WHERE Title = 'Sales Representative';
Оператор CREATE TABLE
Создает новую таблицу. Формат:
CREATE TABLE table (field1 type [(size)] [NOT NULL] [index1] [, field2 type [(size)] [NOT NULL] [index2] [, ...]] [, CONSTRAINT multifieldindex [, ...]])
Оператор CREATE TABLE имеет следующие части:
|
Оператор CREATE TABLE создает новую таблицу и устанавливает свойства ее полей. Если для поля указано NOT NULL, оно требует обязательного ввода. Свойство NOT NULL можно указывать для отдельного поля или в именованом выражении CONSTRAINT. Соответственно, оно будет применяться к одному полю или ко всем перечисленным. Его можно устанавливать для поля только один раз, иначе происходит ошибка.
Выражение CONSTRAINT устанавливает ограничения для отдельного поля и может использоваться для создания первичного ключа. Для создания ключей (в т.ч. первичного) в существующей таблице используется оператор CREATE INDEX.
Следующие запросы меняют таблицы в базе Northwind (если изменения нежелательны, нужно предварительно сделать копию). Запросы вводятся в SQL окне конструктора запросов, затем нужно выполнить запрос.
Создается таблица с двумя текстовыми полями:
CREATE TABLE FirstTable (FirstName TEXT, LastName TEXT);
Создается таблица с двумя текстовыми и Date/Time полем, создается уникальный составной индекс на основе всех трех полей:
CREATE TABLE SecondTable (FirstName TEXT, LastName TEXT, DateOfBirth DATETIME,
CONSTRAINT MyTableConstraint UNIQUE (FirstName, LastName, DateOfBirth));
Выражение CONSTRAINT
Используется в операторах ALTER TABLE и CREATE TABLE для установки свойств полей – наложения или удаления ограничений. Позволяет также устанавливать связь с другой таблицей. Имеются две формы – для одного поля и для нескольких.
Ограничения для одного поля:
CONSTRAINT name {PRIMARY KEY | UNIQUE | NOT NULL |
REFERENCES foreigntable [(foreignfield1, foreignfield2)]}
Ограничения для нескольких полей
CONSTRAINT name
{PRIMARY KEY (primary1[, primary2 [, ...]]) |
UNIQUE (unique1[, unique2 [, ...]]) |
NOT NULL (notnull1[, notnull2 [, ...]]) |
FOREIGN KEY (ref1[, ref2 [, ...]])
REFERENCES foreigntable [(foreignfield1 [, foreignfield2 [, ...]])]}
Выражение CONSTRAINT имеет следующие части:
|
Синтаксис для единичного поля можно использовать в операторах ALTER TABLE и CREATE TABLE в определении поля сразу после указания типа, синтаксис для нескольких полей можно использовать в тех же операторах вне определений полей со служебным словом CONSTRAINT.
Выражение CONSTRAINT может устанавливать следующие ограничения:
- UNIQUE – определяет поле с уникальными значениями, т.е. две записи не могут содержать в этом поле одинаковые значения. Если полей несколько, в двух записях невозможны одинаковые сочетания их значений.
- PRIMARY KEY – поле/поля образуют первичный ключ. Все значения должны быть разными и не Null. Т.к. в таблице только один первичный ключ, при попытке создать второй происходит ошибка.
- NOT NULL – поле/поля не могут содержать Null, т.е. обязательны для заполнения.
- FOREIGN KEY – поле/поля образуют внешний ключ. Если первичный ключ внешней таблицы состоит из нескольких полей, нужно использовать форму CONSTRAINT для нескольких полей, содержащую перечень ссылающихся полей, имя внешней таблицы и имена полей во внешней таблицы, на которые ссылаются перечисленные, указанные в том же порядке. Если ссылка идет не поля первичного ключа внешней таблицы, их указывать не нужно, т.к. эти поля подразумеваются по умолчанию.
Следующие запросы меняют таблицы в базе Northwind (если изменения нежелательны, нужно предварительно сделать копию). Запросы вводятся в SQL окне конструктора запросов, затем нужно выполнить запрос.
Создается таблица с двумя текстовыми и Date/Time полем, создается уникальный составной индекс на основе всех трех полей:
CREATE TABLE SecondTable (FirstName TEXT, LastName TEXT, DateOfBirth DATETIME,
CONSTRAINT MyTableConstraint UNIQUE (FirstName, LastName, DateOfBirth));
Создается таблица с двумя текстовыми и Integer полем, поле SSN является первичным ключом:
CREATE TABLE ThirdTable (FirstName TEXT, LastName TEXT, SSN INTEGER
CONSTRAINT MyFieldConstraint PRIMARY KEY);
Оператор ALTER TABLE
Меняет структуру таблицы после ее создания оператором CREATE TABLE. Формат:
ALTER TABLE table {ADD {COLUMN field type[(size)] [NOT NULL][CONSTRAINT index] | CONSTRAINT multifieldindex} |DROP
{COLUMN field I CONSTRAINT indexname} }
Оператор ALTER TABLE имеет следующие части:
|
С помощью ALTER TABLE в существующей таблице можно сделать различные изменения:
- ADD COLUMN добавляет поле в таблицу. Нужно указать имя и тип поля, а для типов Text и Binary – размер. Например, следующий оператор добавляет 25-символьное текстовое поле Notes в таблицу Employees:
ALTER TABLE Employees ADD COLUMN Notes TEXT(25)
Можно также добавить индекс для этого поля (см. CONSTRAINT). Если для поля указано NOT NULL, то в новые записи необходито будет вводит допустимые данные. - ADD CONSTRAINT добавляет составной индекс (см. CONSTRAINT).
- DROP COLUMN удаляет поле. Указывается только имя поля.
- DROP CONSTRAINT удаляет составной индекс. Указывается только имя индекса.
За один раз нельзя добавить или удалить более одного поля или индекса. Для добавления индекса можно также использовать CREATE INDEX., а для удаления – DROP. Можно указывать NOT NULL для одного поля или внутри именованного выражения для нескольких полей (?). При повторном применении к тому же полю NOT NULL вызывает ошибку выполнения.
Следующие запросы меняют таблицы в базе Northwind (если изменения нежелательны, нужно предварительно сделать копию). Запросы вводятся в SQL окне конструктора запросов, затем нужно выполнить запрос.
Ввести в таблицу Employees поле Salary типа Currency:
ALTER TABLE Employees ADD COLUMN Salary CURRENCY;
Удалить поле Salary из таблицы Employees:
ALTER TABLE Employees DROP COLUMN Salary;
Следующий пример добавляет внешний ключ к таблице Orders. Внешний ключ основан на поле EmployeeID и ссылается на поле EmployeeID таблицы Employees. В данном случае не обязательно указывать поле EmployeeID после таблицы Employees в выражении REFERENCES, т.к. EmployeeID является ее первичным ключом.
Sub AlterTableX3()
Dim dbs As Database
' Modify this line to include the path to Northwind on your computer.
Set dbs = OpenDatabase("Northwind.mdb")
' Add a foreign key to the Orders table.
dbs.Execute "ALTER TABLE Orders ADD CONSTRAINT OrdersRelationship " _
& "FOREIGN KEY (EmployeeID) REFERENCES Employees (EmployeeID);"
dbs.Close
End Sub
Оператор CREATE INDEX
Создает новый индекс в существующей таблице. Формат:
CREATE [ UNIQUE ] INDEX index ON table (field [ASC|DESC][, field [ASC|DESC], ...])
[WITH { PRIMARY | DISALLOW NULL | IGNORE NULL }]
Оператор CREATE INDEX имеет следующие части:
|
Если значения поля/полей должны быть уникальны, используется служебное слово UNIQUE. В не обязательном выражении WITH указываются ограничения:
- DISALLOW NULL – запретить значения Null в индексируемом поле/полях (обязательны для заполнения)
- IGNORE NULL – исключить незаполненные поля из индексации
- PRIMARY – использовать индекс как первичный ключ (индекс подразумевается уникальным, UNIQUE можно не указывать). При попытке создать в таблице второй первичный ключ происходит ошибка.
Можно использовать CREATE INDEX для создания псевдоиндекса в присоединенной таблице из ODBC-источника (например, SQL Server). Для этого не нужно разрешения или доступа к удаленному серверу, он не реагирует на создание псевдоиндекса. Формат оператора тот же. Это особенно полезно для таблиц, которые были бы «только для чтения» из-за отсутствия индекса.
Можно использовать ALTER TABLE для добавления индекса и ALTER TABLE или DROP для удаления индекса, созданного ALTER TABLE или CREATE INDEX.
Следующие запросы меняют таблицы в базе Northwind (если изменения нежелательны, нужно предварительно сделать копию). Запросы вводятся в SQL окне конструктора запросов, затем нужно выполнить запрос.
В таблице Employees создается индекс на основании полей Home Phone и Extension:
CREATE INDEX NewIndex ON Employees (HomePhone, Extension);
В таблице Customers создается уникальный индекс на основе поля CustomerID, поле обязательно для заполнения:
CREATE UNIQUE INDEX CustID ON Customers (CustomerID) WITH DISALLOW NULL;
Удалить созданный индекс можно оператором
DROP INDEX CustID ON Customers;
Его нельзя удалить в окне конструктора, пока не удалены связи таблицы Customers.
В следующем примере создается псевдоиндекс в присоединенной таблице OrderDetailsODBC
CREATE UNIQUE INDEX OrderID ON OrderDetailsODBC (OrderID);
Оператор DROP
Удаляет существующий индекс из таблицы или существующую таблицу из базы. Формат:
DROP {TABLE table | INDEX index ON table}
Оператор DROP имеет следующие части:
|
Прежде чем удалять индекс или саму таблицу, ее нужно запрыть. Удалить индекс можно оператором ALTER TABLE.
В следующих примерах предполагается наличие индекса NewIndex в таблице Employees базы Northwind. Запросы меняют таблицы в базе Northwind (если изменения нежелательны, нужно предварительно сделать копию).
Удалить индекс NewIndex из таблицы Employees:
DROP INDEX MyIndex ON Employees;
Удалить таблицу Employees из базы:
DROP TABLE Trainees;
Автор статьи: Leonid Maximov (AKA Leon).
В следующем выпуске мы рассмотрим некоторые агрегатные функции.
Вопросы в рассылку |
№5 Есть приложение, которое работает в нескольких филиалах одной фирмы, оно разбито на два mdb файла:
1. В первом файле находятся таблицы с данными, назовем его base.mdb
2. Во втором файле запросы, формы, отчеты, назовем его prog.mdb. Кроме того в нем находятся связанные таблизы из первого файла.
Так было сделано, чтобы при добавлении каких либо функций можно было разослать новый файл prog.mdb при этом данные в филиалах сохраняются.
Но неожиданно возникла необходимость изменить структуру самой таблицы данных. Попытался создать в файле prog.mdb кнопку по которой запросом изменяется структура присоединнной таблице, но не смог.
Пришлось посылать отдельный mdb файл, где была только форма с одной кнопкой выполняющей запрос:
Private Sub Eiiiea0_Click()
Dim appAccess As New Access.Application
Set appAccess = CreateObject("Access.Application.8")
appAccess.OpenCurrentDatabase "s:\spip\257r\base.mdb"
appAccess.DoCmd.RunSQL "ALTER TABLE main ADD COLUMN Mria DOUBLE;"
appAccess.DoCmd.RunSQL "UPDATE main SET main.Mria = 0;"
appAccess.CloseCurrentDatabase
Application.Quit
End Sub
Всё получилось, но хотелось бы узнать существует ли способ изменить структуру присоединной таблицы из самого приложения?
Прислал: Дмитрий [Ответить ]
№6
Есть основная ФОРМА - "ЦЕХА" и подчинённая "ЗАМЕРЫ". В основной форме создано поле со списком - "АДРЕСА".
ВОПРОС - Как сделать, чтобы выбирая из поле со списком - "АДРЕСА" определённый адрес - изменялись бы и соответствующие значения в подчинённой форме - "ЗАМЕРЫ".
Прислал: Viktor [Ответить ]
P.S. Если у кого-то есть интересные статьи и ссылки на тему программирования на Microsoft Access, присылайте! Давайте вместе делать рассылку интересной и полезной.
© 2006 Виктория Колдбер E-mail: Victoria_koldber@mail.ru Сайт: MyAccess.BOOM.ru
В избранное | ||