Динамически настраиваемые запросы из приложения
Задача: имеется некий запрос с динамически настраиваемым условием
Подход я придумала сама, давно уже. А выношу этот вопрос на публику сейчас, потому что сегодня наткнулась на статью приснопамятного Тома Кайта как раз на эту тему. Мой личный подход концептуально не отличается, но кажется более сложным, у Кайта как-то полегче. Но переделывать, наверное, уже не буду — слишком много в приложении на него завязано. Хотя кое-что можно попробовать поковырять с целью повышения производительности.
( Подробности и много кода )
where
. Параметры передаются с веб-интерфейса, при этом если параметр пуст, т.е. is null
, то он не должен включаться в условие where
. Дополнительное условие — постраничный вывод данных, но это мы уже проходили.Подход я придумала сама, давно уже. А выношу этот вопрос на публику сейчас, потому что сегодня наткнулась на статью приснопамятного Тома Кайта как раз на эту тему. Мой личный подход концептуально не отличается, но кажется более сложным, у Кайта как-то полегче. Но переделывать, наверное, уже не буду — слишком много в приложении на него завязано. Хотя кое-что можно попробовать поковырять с целью повышения производительности.
( Подробности и много кода )
Прикольно попала, благодаря собственному стилю программирования
Особенность проекта — доступ к БД только через хранимые процедуры. Все процедуры возвращают output cursor. Поэтому для тех, которые возвращают заведомо одно значение, работает мелкий пакет
( Текст )
Т.е. вернуть фиксированное значение с возможностью задать имя столбца. По умолчанию возвращается 'SUCCESS'.
Сегодня процедура
returns
. В т.ч. returns.ReturnTextSuccess
.( Текст )
Т.е. вернуть фиксированное значение с возможностью задать имя столбца. По умолчанию возвращается 'SUCCESS'.
Сегодня процедура
GetEmailDefaultAttr
начала возвращать этот самый 'SUCCESS'. Понятное дело, потому что значение атрибута было null. Но как-то я оказалась к такому выверту не готова :)Emailing в Oracle 11g
Для того, чтобы стало возможным использование пакетов UTL_TCP, UTL_SMTP, UTL_MAIL, UTL_HTTP, UTL_INADDR необходимо некоторое количество танцев с бубном. В частности, настроить т.н. Access Control Lists (это примочка XML DB).
Полностью процесс описан в документации: Oracle® Database Security Guide -> 4 Configuring Privilege and Role Authorization.
Вкратце же, вся бодяга выглядит следующим образом.
Полностью процесс описан в документации: Oracle® Database Security Guide -> 4 Configuring Privilege and Role Authorization.
Вкратце же, вся бодяга выглядит следующим образом.
- Создаётся access list (в дальнейшем - список контроля доступа)
причём параметр privilege чувствителен к регистру.DBMS_NETWORK_ACL_ADMIN.CREATE_ACL ( acl => 'file_name.xml', description => 'file description', principal => 'user_or_role', is_grant => TRUE|FALSE, privilege => 'connect|resolve', start_date => null|timestamp_with_time_zone, end_date => null|timestamp_with_time_zone);
- Списку присваивается один или несколько адресов.
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL ( acl => 'file_name.xml', host => 'network_host', lower_port => null|port_number, upper_port => null|port_number);
- Привилегия на использование списка предоставляется пользователю или роли.
DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE ( acl => 'file_name.xml', principal => 'user_or_role', is_grant => TRUE|FALSE, privilege => 'connect|resolve', position => null|value, start_date => null|timestamp_with_time_zone, end_date => null|timestamp_with_time_zone);
Ref cursor
What is the difference between cursor and ref cursor, and when would you appropriately use each of these.
Technically, under the covers, at the most "basic level", they are the same. A "normal" plsql cursor is static in defintion. Ref cursors may be dynamically opened or opened based on logic.
Given that block of code — you see perhaps the most "salient" difference — no matter how many times you run that block — cursor C will always be select * from dual. The ref cursor can be anything.
Another difference is a ref cursor can be returned to a client. A plsql "cursor cursor" cannot be returned to a client.
Another difference is a cursor can be global — a ref cursor cannot (you cannot define them OUTSIDE of a procedure / function)
Another difference is a ref cursor can be passed from subroutine to subroutine — a cursor cannot be.
Another difference is that static sql (not using a ref cursor) is much more efficient then using ref cursors and that use of ref cursors should be limited to
— returning result sets to clients
— when there is NO other efficient/effective means of achieving the goal.
That is, you want to use static SQL (with implicit cursors really) first and use a ref cursor only when you absolutely have to.
Difference between cursor and a ref cursor
Technically, under the covers, at the most "basic level", they are the same. A "normal" plsql cursor is static in defintion. Ref cursors may be dynamically opened or opened based on logic.
Declare type rc is ref cursor; cursor c is select * from dual; l_cursor rc; begin if ( to_char(sysdate,'dd') = 30 ) then open l_cursor for 'select * from emp'; elsif ( to_char(sysdate,'dd') = 29 ) then open l_cursor for select * from dept; else open l_cursor for select * from dual; end if; open c; end; /
Given that block of code — you see perhaps the most "salient" difference — no matter how many times you run that block — cursor C will always be select * from dual. The ref cursor can be anything.
Another difference is a ref cursor can be returned to a client. A plsql "cursor cursor" cannot be returned to a client.
Another difference is a cursor can be global — a ref cursor cannot (you cannot define them OUTSIDE of a procedure / function)
Another difference is a ref cursor can be passed from subroutine to subroutine — a cursor cannot be.
Another difference is that static sql (not using a ref cursor) is much more efficient then using ref cursors and that use of ref cursors should be limited to
— returning result sets to clients
— when there is NO other efficient/effective means of achieving the goal.
That is, you want to use static SQL (with implicit cursors really) first and use a ref cursor only when you absolutely have to.
Difference between cursor and a ref cursor