Из этой таблицы мне пригодились всего два параметра – Id и Name. Имя запроса мне известно, а все записи в другой системной таблице, относящиеся к этому запросу я нахожу при помощи поля Id.
2.Внешний вид записей, относящихся к одному запросу в таблице MSysQueries (в ней хранится структура всех запросов и процедур).
Attribute
Expression
Flag
LvExtra
Name1
Name2
ObjectId
Order
0
0
-2147483636
(VARBYTES)
255
-2147483636
(VARBYTES)
5
Staff_list
-2147483636
(VARBYTES)
5
Personal
-2147483636
(VARBYTES)
6
[Staff_list].[P_code]
0
-2147483636
(VARBYTES)
6
[Staff_list].[Name]
0
-2147483636
(VARBYTES)
6
[Staff_list].[Br]
0
-2147483636
(VARBYTES)
6
[Staff_list].[Room]
0
-2147483636
(VARBYTES)
6
[Personal].[Fam]
0
-2147483636
(VARBYTES)
7
[Staff_list].[Room]=[Personal].[Room]
2
Staff_list
Personal
-2147483636
(VARBYTES)
7
[Staff_list].[Br]=[Personal].[Br]
2
Staff_list
Personal
-2147483636
(VARBYTES)
7
[Staff_list].[P_code]=[Personal].[P_code]
2
Staff_list
Personal
-2147483636
(VARBYTES)
Хотя в Access и не делается различие между запросом и процедурой, на самом деле оно есть в ADO. Запросом считается простой запрос SQL без параметров, который называется VIEW. Все запросы на изменение структуры таблиц, запросы с параметрами, запросы на объединение и пр... считаются процедурами и выбираютя из базы данных как views или procedures соответственно. Запросы сохраняются в базу данных соответственно с помощью CREATE VIEW, а процедуры – CREATE PROCEDURE. Если вы добавили в запрос параметры, он преобразовался в процедуру, и обратно сохранять его нужно уже с помощью CREATE PROCEDURE. Да, и перед сохранением измененного запроса не забывайте удалять из базы предыдущий – DROP VIEW или DROP PROCEDURE . Кстати запрос (view) удаляется и инструкцией DROP TABLE, однако я бы не рекомендовал ею пользоваться, потому что ошибка в имени, или невнимательность – и вы удалите вместо запроса таблицу. С помощью DROP VIEW таблицу удалить нельзя. Этот вариант более безопасен. С помощью DROP VIEW можно удалить процедуру, но, опять же лучше пользоваться предназначенной инструкцией – по крайней мере вы будете четко понимать, что делаете.
3. Описание полей и их значений относящихся к запросу (процедуре).
Формат хранения запросов в Access (MsysQueries) Значение ObjectID и имя запроса находится в таблице MsysObjects
Поле
Значение
Описание
СубПоле
Значение
Описание
Attribute
0
Разделитель запросов
ObjectID
[LongInt]
Этот же ID содержится во всех остальных записях, относящихся к этому запросу
255
Пустая запись (я не встречал ее заполненой)
Идет после Attribute 0 всегда
1
Тип запроса, определяется полем Flag. Присутствует не всегда. Если запись отсутствует, то это (скорее всего, да других вариантов и не встречалось) запрос SELECT
Flag
1
SELECT ... FROM
2
INSERT ... INTO
3
UPDATE ... SET
4
UPDATE ... SELECT
5
DELETE
6
TRANSFORM
7
MODIFY, CREATE TABLE, DROP
8
9
UNION
10
11
EXECUTE
Expression
[Text]
Параметры для Execute
[Text]
Текст процедуры для Flag=7
Name1
[Text]
Имя процедуры для Execute
2
Параметры запроса
Flag
1
Bit (boolean по Delphi)
2
Byte (Tinyint)
3
Short (SmallInt)
4
Integer
5
Currency
6
Real
7
Float
8
TdateTime
9
10
String([LvExtra]) (Char..., Text...)
11
Image !!!
12
13
14
15
UNIQUEIDENTIFIER
16
Decimal
LvExtra
[Integer]
Длина параметра для [String] и т. д. где имеет смысл
Запись с аттрибутом 3 я так и не разобрал, это только ход моих размышлений.
3
Предикаты (Скорее всего битовое поле) ?????
Flag
0,1
ALL
2
DISTINCT
3
SELECT DISTINCT *
4
WITH OWNERACCESS OPTION
5
Выборка *
8
DISTINCT ROW ???
16
TOP <N> Поле Name1 - <N>
48
TOP <N> PERCENT Поле Name1 - <N>
4
Внешняя база данных
Name1
[Text]
Путь к внешней базе данных ( IN )
5
Исходные таблицы или текст отдельного блока для UNION
Expression
[Text]
Для UNION содержит в каждой строке текст блока UNION SELECT
Для SELECT
Name1
[Text]
Имя таблицы для выборки
Для SELECT
Name2
[Text]
Алиас таблицы
6
Имя поля секции SELECT
Expression
[Text]
Имя поля
Name1
[Text]
Алиас поля {<Expression> as <Name1>}
7
Конструкция и тип объединения JOIN
Expression
[Text]
<Поле1>{ = | <> | > | < }<Поле2>
Flag
1
INNER JOIN
2
LEFT JOIN
3
RIGHT JOIN
Name1
[Text]
Имя или алиас Таблицы1
Name2
[Text]
Имя или алиас Таблицы2
8
Секция WHERE
[Expression]
[Text]
Условие WHERE полностью
9
Секция GROUP BY
[Expression]
[Text]
Условие GROUP BY полностью
10
Секция HAVING
[Expression]
[Text]
Условие HAVING полностью
11
Секция ORDER BY
[Expression]
[Text]
Условие ORDER BY полностью
Используя эту информацию можно вытащить и собрать текст запроса из базы данных Access. Если кто знает другой способ, всегда рад помощи, да и сам готов помочь или поделиться знаниями. Создание такого парсера – довольно хорошая возможность разобраться с SQL. Напрмер я не прорабатывал варианты, когда в инструкции SQL используются нестандартные функции, и как в Access это все будет сохранено, я не знаю. Эта статья – не техническая документация, а попытка поделиться опытом.
Всем удачи!
Шкут Александр (AlexS.) 25 декабря 2003г. Специально для