В связи с переездом на новый ноутбук на который была поставлена не кошерная Ubuntu взамен кошерного Debian, который продолжает крутиться на старом. Мне пришлось проходить всё круги ада по настройке системы под разработку снова. В связи с этим родилась эта заметка.
понедельник, 18 февраля 2013 г.
воскресенье, 21 октября 2012 г.
Внешние таблицы + препроцессор
Эту заметку пишу в качестве узелка на память.
Дело в ом, что я уже довольно давно знаю о существовании в Oracle внешних таблиц. Очень удобного средства для перекидывания данных из CVS файлов в базу. Но только сегодня я узнал о существовании в Oracle 11.2 препроцессора, который может подготавливать данные для внешней таблицы посредством выполнения каких-либо программ на машине, где работает сервер базы данных.
Ниже даю ссылки на описание работы с внешними таблицами и документ, в котором на основании простых примеров рассказывается как пользоваться препроцессором:
Внешние таблицы
Использование препроцессора с внешними таблицами
Дело в ом, что я уже довольно давно знаю о существовании в Oracle внешних таблиц. Очень удобного средства для перекидывания данных из CVS файлов в базу. Но только сегодня я узнал о существовании в Oracle 11.2 препроцессора, который может подготавливать данные для внешней таблицы посредством выполнения каких-либо программ на машине, где работает сервер базы данных.
Ниже даю ссылки на описание работы с внешними таблицами и документ, в котором на основании простых примеров рассказывается как пользоваться препроцессором:
Внешние таблицы
Использование препроцессора с внешними таблицами
вторник, 11 сентября 2012 г.
Функция LISTAGG
Чтобы "вытянуть" значение нескольких строк одной колонки в одну строку в Oracle 11.2 не обязательно придумывать хитрые иерархические запросы. Достаточно воспользоваться функцией LISTAGG.
Вот её описание в документации Oracle: http://docs.oracle.com/cd/E14072_01/server.112/e10592/functions087.htm
Вот её описание в документации Oracle: http://docs.oracle.com/cd/E14072_01/server.112/e10592/functions087.htm
среда, 15 августа 2012 г.
This is a copy of http://asktom.oracle.com/~tkyte/Misc/RolesAndProcedures.html
If you can do it in plus with no roles you can do it in a procedure. If you can't, you must have the privelege from a role and hence won't be able to do it in a procedure (unless you are using Invokers rights in Oracle8i. See the PLSQL documentation for more information on this feature and make sure you understand the ramifications). To be able to perform that operation in a typical procedure, you need to have that privelege granted directly to you.
Why do I get a "ORA-01031: insufficient privileges" or "PLS-00201: identifier 'x' must be declared" in my stored procedures?
Roles are never enabled during the execution of a procedure except in the special case of Invokers Rights which is a new feature in Oracle8i, release 8.1.This fact is documented application developers guide:Privileges Required to Create Procedures and FunctionsTo create a stand-alone procedure or function, or package specification or</quote>Try this:
body, you must meet the following prerequisites:
• You must have the CREATE PROCEDURE system privilege to create a
procedure or package in your schema, or the CREATE ANY
PROCEDURE system privilege to create a procedure or package in
another user’s schema.
Attention: To create without errors, that is, to compile the procedure
or package successfully, requires the following additional privileges:
The owner of the procedure or package must have been explicitly
granted the necessary object privileges for all objects referenced within
the body of the code; the owner cannot have obtained required
privileges through roles.
If the privileges of a procedure’s or package’s owner change, the procedure
must be reauthenticated before it is executed. If a necessary privilege to a
referenced object is revoked from the owner of the procedure (or package), the
procedure cannot be executed.
SQL> set role none;
SQL> "statement you want to test to see if it'll work in a procedure"
If you can do it in plus with no roles you can do it in a procedure. If you can't, you must have the privelege from a role and hence won't be able to do it in a procedure (unless you are using Invokers rights in Oracle8i. See the PLSQL documentation for more information on this feature and make sure you understand the ramifications). To be able to perform that operation in a typical procedure, you need to have that privelege granted directly to you.
Почему PL/SQL в коде (представлении/процедуре/триггере/пакете) невозможно использовать чужие объекты. Roles and ORA-00942 table or view does not exist
Этот вопрос находится в топе вопросов на SQL.RU по СУБД Oracle.
Краткий ответ такой, потому что грант на эти объекты выдан через роль.
Ответ в документации по Oracle: "Потмучто в именованном PL/SQL блоке все роли отключаются"
Чуть более развёрнутый ответ приведён на самом SQL.RU: Почему в своем pl/sql-коде (представлении/процедуре/триггере/пакете) не удается использовать чужой объект - выдается ошибка ORA-00942 table or view does not exist - хотя в sql-запросе или в анонимном pl/sql/блоке все нормально, обращение к объекту другого пользователя проходит без проблем?
Ответ. Скорее всего на чужой объект есть привилегия, выданная только через роль. Для использования объектов другого пользователя или системных привелегий в своих процедурах/триггерах и т.д., а также в job-ах необходимо дать на них привилегию напрямую, не через роль.
Так же это правило следует учесть для динамического SQL: FAQ: ORA-01031: insufficient privileges при выполнении динамического SQL в процедурах (по этой ссылке приводится ещё более развёрнутый ответ)
Краткий ответ такой, потому что грант на эти объекты выдан через роль.
Ответ в документации по Oracle: "Потмучто в именованном PL/SQL блоке все роли отключаются"
Чуть более развёрнутый ответ приведён на самом SQL.RU: Почему в своем pl/sql-коде (представлении/процедуре/триггере/пакете) не удается использовать чужой объект - выдается ошибка ORA-00942 table or view does not exist - хотя в sql-запросе или в анонимном pl/sql/блоке все нормально, обращение к объекту другого пользователя проходит без проблем?
Ответ. Скорее всего на чужой объект есть привилегия, выданная только через роль. Для использования объектов другого пользователя или системных привелегий в своих процедурах/триггерах и т.д., а также в job-ах необходимо дать на них привилегию напрямую, не через роль.
Так же это правило следует учесть для динамического SQL: FAQ: ORA-01031: insufficient privileges при выполнении динамического SQL в процедурах (по этой ссылке приводится ещё более развёрнутый ответ)
Ну и самый подробный ответ на этот вопрос нам предлагает ASKTOM.ORACLE.COM.
Привожу перепечатку этого ответа, мало ли он исчезнет:
| |||
четверг, 9 августа 2012 г.
Чудесная функция COALESCE
Как всем известно в Oracle SQL есть замечательная функция NVL, которая позволяет вывести результат "по умолчанию", в случае если значение колонки равно NULL.
На протяжении всей своей оракловой жизни я успешно пользовался этой функцией, жил не тужил, хотя нет, иногда мне становилось грустно, когда мне надо было вывести в колонку значение которой надо было взять из других колонок, при этом оно не должно было быть NULL, если все колонки равны NULL, то надо было вывести значение по умолчанию. Обычно эту задачу я решал при помощи CASE, но это требовало много сил и писанины. А вчера произошло чудо, оказывается есть замечательная функция COALESCE, которая замечательно заменяет этот CASE, ниже привожу её синтаксис и пример из документации по Oracle.
На протяжении всей своей оракловой жизни я успешно пользовался этой функцией, жил не тужил, хотя нет, иногда мне становилось грустно, когда мне надо было вывести в колонку значение которой надо было взять из других колонок, при этом оно не должно было быть NULL, если все колонки равны NULL, то надо было вывести значение по умолчанию. Обычно эту задачу я решал при помощи CASE, но это требовало много сил и писанины. А вчера произошло чудо, оказывается есть замечательная функция COALESCE, которая замечательно заменяет этот CASE, ниже привожу её синтаксис и пример из документации по Oracle.
COALESCE (expr1, expr2, ..., exprn), for n>=3
Пример:
SELECT product_id, list_price, min_price, COALESCE(0.9*list_price, min_price, 5) "Sale" FROM product_information WHERE supplier_id = 102050 ORDER BY product_id, list_price, min_price, "Sale"; PRODUCT_ID LIST_PRICE MIN_PRICE Sale ---------- ---------- ---------- ---------- 1769 48 43.2 1770 73 73 2378 305 247 274.5 2382 850 731 765 3355 5Синтаксис и пример взяты документации по SQL СУБД Oracle
пятница, 27 апреля 2012 г.
Как поместить в одну ячейку значение нескольких столбцов
Это скорее небольшая заметка, чем справочная информация.
Столкнулся я с такой проблемой, что надо было мне результат табличной функции представить в в одной ячейке и отделить каждое значение запятой. Самый здравый способ сделать это - функция на PL/SQL, но мы не ищем лёгких путей. Поэтому получилось вот такое:
select text
from (select ltrim(sys_connect_by_path(col, ', '), ', ') as text, CONNECT_BY_ISLEAF is_leaf
from (select <имя колонки, для вытягивания в строку> as col,
rownum as up_rnum,
rownum+1 as rnum
from table(<сюда помещаем нашу табличную функцию>)
)
start with up_rnum = 1
connect by prior rnum = up_rnum)
where is_leaf = 1
UPD:
Оказывается всё уже придумано до нас :)))
На просторах интернета нашёл статью, в которой приведено достаточно способов для вытягивания значения нескольких строк в одну ячейку. Исходник статьи здесь: http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php
Самый "огонь", аналитическая функция, которая появилась в 11gR2 - LISTAGG
Пример её использования:
Столкнулся я с такой проблемой, что надо было мне результат табличной функции представить в в одной ячейке и отделить каждое значение запятой. Самый здравый способ сделать это - функция на PL/SQL, но мы не ищем лёгких путей. Поэтому получилось вот такое:
select text
from (select ltrim(sys_connect_by_path(col, ', '), ', ') as text, CONNECT_BY_ISLEAF is_leaf
from (select <имя колонки, для вытягивания в строку> as col,
rownum as up_rnum,
rownum+1 as rnum
from table(<сюда помещаем нашу табличную функцию>)
)
start with up_rnum = 1
connect by prior rnum = up_rnum)
where is_leaf = 1
UPD:
Оказывается всё уже придумано до нас :)))
На просторах интернета нашёл статью, в которой приведено достаточно способов для вытягивания значения нескольких строк в одну ячейку. Исходник статьи здесь: http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php
Самый "огонь", аналитическая функция, которая появилась в 11gR2 - LISTAGG
Пример её использования:
Base Data:
DEPTNO ENAME
---------- ----------
20 SMITH
30 ALLEN
30 WARD
20 JONES
30 MARTIN
30 BLAKE
10 CLARK
20 SCOTT
10 KING
30 TURNER
20 ADAMS
30 JAMES
20 FORD
10 MILLER
Desired Output:
DEPTNO EMPLOYEES
---------- --------------------------------------------------
10 CLARK,KING,MILLER
20 SMITH,FORD,ADAMS,SCOTT,JONES
30 ALLEN,BLAKE,MARTIN,TURNER,JAMES,WARD
COLUMN employees FORMAT A50
SELECT deptno, LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS employees
FROM emp
GROUP BY deptno;
DEPTNO EMPLOYEES
---------- --------------------------------------------------
10 CLARK,KING,MILLER
20 ADAMS,FORD,JONES,SCOTT,SMITH
30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD
3 rows selected.
Подписаться на:
Сообщения (Atom)