[ELMA3] Особенности разработки для Oracle
Программы и настройки
- Oracle SQL Developer.
- Для ELMA в папке bin сервера должны лежать библиотеки из Libs\Oracle.
- Правильно настроенная конфигурация. Для сохранения и загрузки настроек используется класс OracleSettingsSection, соответсвено, в конфиге нужно его указать вместо базового.
1 | <section name= "main" type= "EleWise.ELMA.Extensions.Oracle.OracleSettingsSection, EleWise.ELMA.Extensions.Oracle" /> |
5. В настройке провайдера добавилось 2 новых свойства: sysUser и sysPassword. Это логин и пароль глобального администратора на Oracle сервере.
1 | < main connectionStringName = "MainDB" type = "EleWise.ELMA.Extensions.Oracle.OracleProvider, EleWise.ELMA.Extensions.Oracle" backupEnabled = "false" sysUser = "login" sysPassword = "password" /> |
1 2 3 4 | create user c##login identified by password ; grant all PRIVILEGES to c##login ; GRANT SELECT ON "SYS" . "GV_$RESERVED_WORDS" TO c##login; GRANT SELECT ON "SYS" . "V_$RESERVED_WORDS" TO c##login; |
1 | drop user elma3 cascade ; |
SQL-запросы
При разработке нужно всегда помнить, что в Oracle около 1200 ключевых слов. Каждое ключевое слово в запросах должно быть взято в кавычки. При этом нужно помнить, что такие названия в кавычках становятся регистрозависимыми. К примеру, UID и "Uid" это две разные колонки для Oracle. Список ключевых слов хранится прямо в базе, можно получить их запросом:
1 | select keyword from sys.v_$reserved_words |
Хранимые процедуры
Так просто в Oracle табличку из функции не вернуть. Лучше всего это делать через кастомные типы. Для того, чтобы вернуть табличку, нужно создать тип для строки и тип для таблички:
1 2 3 4 5 6 7 8 | CREATE TYPE NOMENCLATURETREE_row as object ( "Id" integer , "Name" nvarchar2(2000) , PARENTGROUP integer , LinkId integer , nodetypeuid raw(16)); CREATE TYPE NOMENCLATURETREE_tbl as table of NOMENCLATURETREE_row; |
После этого можно писать процедуру, которая возвращает результат типа таблица:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | create or replace function NOMENCLATURETREE (p_YEARNOMEN integer ) RETURN NOMENCLATURETREE_tbl PIPELINED is temp NOMENCLATURETREE_row; begin temp := NOMENCLATURETREE_row( null , null , null , null , null ); FOR i IN ( select dg. "Id" as "Id" , case when (rpi. "Id" is not null ) then rp. "Name" when (dl. "Id" is not null ) then dr2. "Name" else dg. "Name" end as "Name" , dg.parentgroup, case when (dl. "Id" is not null ) then dl.DEPOSITORY else dg. "Id" end as LinkId, dg.typeuid as nodetypeuid from depositorygroup dg left join depositorygroup dr on dr. "Id" = dg. "Id" left join registrationplaceitem rpi on rpi. "Id" = dr. "Id" left join REGISTRATIONPLACE rp on rp. "Id" = rpi.registrationplace left join depositorylink dl on dl. "Id" = dr. "Id" left join depositorygroup dr2 on dl.depository = dr2. "Id" start with 1=1 and dg.parentgroup is null and exists ( select 1 from registrationplaceitem regpli, accountingyear ay where 1=1 and dg. "Id" = regpli. "Id" and ay. "Id" = regpli.ACCOUNTINGYEAR and ay. "Year" = p_YEARNOMEN) connect by nocycle prior dg. "Id" = dg.parentgroup ) LOOP temp . "Id" := i. "Id" ; temp . "Name" := i. "Name" ; temp .PARENTGROUP := i.PARENTGROUP; temp .LinkId := i.LinkId; temp .nodetypeuid := i.nodetypeuid; PIPE ROW ( temp ); END LOOP; RETURN ; end NOMENCLATURETREE; |
Рекурсивные процедуры
Oracle поддерживает стандарт по рекурсивным запросам только с 11-ой версии. У нас должно еще работать и на 10-ой. До 11 версии в Oracle существовал только свой синтаксис (через CONNECT BY). Подробнее написано здесь (глава про Oracle).