Приветствую форумчан!
На работе у меня в стационарном компьютере была установлена MS SQL Server Express Edition, а Access служил как интерфейс для пользователей. Но по мере роста данных (ежедневно получал несколько сот тысяч записей из БД в ORACLE, а по отдельным отчётам почти млн. записей) компьютер стал страшно тормозить, да и юзеры начали жаловаться, что база работает страшно медленно. Было решено, от MS SQL Server отказаться и перейти на ORACLE, да и базу перенести в серверную машину. Начал потихоньку переносить вручную базу (не стал использовать программки для автоматического переноса, хотел научиться сам).
Приходилось решать по ходу множества проблем. Вот некоторые из них.
1. Как создать хранимую процедуру, которая возвращает набор записей, в ORACLE и получить данные в MS Access
В MS SQL Server создать хранимую процедуру, возвращающую набор записей, проще простого:
CREATE PROCEDURE Test(@A Int) AS
SELECT * FROM Table1 WHERE ID = @A;
А вызвать ХП в запросе к серверу ещё проще.
EXEC Test 1
А вот в ORACLE после многочисленных проб и ошибок и после чтения многочисленных, отрывочных статьей наконец-то нашёл вот такой способ (наверняка не единственный, а 1 из многочисленных способов). Итак создаём ХП так.
CREATE OR REPLACE PROCEDURE FindTable(TableName IN Varchar2, Data OUT sys_refcursor) AS
BEGIN
OPEN Data For
SELECT * FROM all_tables WHERE TABLE_NAME LIKE TableName;
END;
А вот в запросе к серверу после многочисленных проб и ошибок смог наконец-то получить набор записей.
{CALL FindTable('VIEW%')}
Причём в конце не стоит ставить
;Здесь "VIEW%" значение для параметра (аргумента) "TableName". А для "Data" разумеется ничего не передаём, т.к. он только для "выхода" данных (OUT).
Можно конечно написать и функцию, но это отдельная песня (как-нибудь напишу здесь).
2. Грабли с "CASE WHEN ... END" в ORACLE.
Когда Вы пишите обычный запрос "SELECT ... FROM ..." и при этом используете "CASE WHEN ... END" для какого-либо столбца, где для текстового значения используете апостроф, то вот примерно такой запрос к серверу возвращает ошибку:
SELECT
CASE WHEN OWNER IN ('SYS', 'SYSTEM') THEN 'system object'
ELSE 'User''s object'
END SSS
FROM ALL_TABLES;
Как Вы видите, я использовал апостроф внутри "CASE WHEN ... END". Когда запускаете запрос ORACLE ругается. Вроде бы простейший запрос. Когда этот же запрос запускаю в программе "PL/SQL Developer", то там не ругается. Оказывается причина в пробеле после "END" (я отметил красным). Здесь в этом запросе "SSS" это псевдоним столбца. Вот если убрать пробел и псевдоним спустить хотя бы на 1 строчку вниз, вуаля! ORACLE не ругается.
SELECT
CASE WHEN OWNER IN ('SYS', 'SYSTEM') THEN 'system object'
ELSE 'User''s object'
END
SSS
FROM ALL_TABLES;
Думал это косяк Access, который при передаче на сервер что-то там видать мудрит сильно. Но к моему удивлению в другой программе WinSQL та же картина. Скорее всего проблема в ODBC драйвере, а быть может и ОС Windows тоже как-то причастен к косяку. (На всякий случай пишу здесь: у меня 64-битный Win 7, а офис 32-битный. ODBC драйвер "Oracle in XE", устанавливается совместно с ORACLE Express Edition). Если у Вас "нормальный" драйвер, то возможно такой проблемы не возникает.
3. Разные типы данных между ORACLE и Access.
Само собой разумеется, что это абсолютно разные программы разных разработчиков и поэтому совместимость отдельных типов данных скорее случайность чем закономерность. :)
Взять хотя бы целые числа. Если ключевое поле - целое число, то на стороне ORACLE не стоит использовать INETEGER, ибо в этом случае Access будет принимать его как строка, после чего начнётся веселая жизнь в случае обновления или удаления данных. Лучше использовать что-то вроде NUMBER(n). Также следует учесть, что в ORACLE нет пустой строки '', если строка пустая, то там она автоматически NULL.
http://www.sql.ru/forum/1219464/ms-access-oracle