Quantcast
Channel: Oracle Blog : apex
Viewing all 142 articles
Browse latest View live

Usando los esquema de colores del Tema Universal 42 en nuestros componentes personalizados

$
0
0

El Tema Universal utiliza un conjunto de colores (esquemas) entre los diferentes componentes. Estos colores se pueden agrupar en dos paletas: colores generales y colores con estado.

Colores generales

Los colores generales se utilizan para agregar color a varios componentes de la aplicación como gráficos, cards, carousel y más.

Hay 15 colores primarios que se modifican para convertirse en más claros o más oscuros para crear un total de 45 opciones de color. Podemos personalizar estos colores modificando la paleta de colores dentro de Theme Roller.

Colores Primarios

Colores Primarios - Más Claros

Colores Primarios - Más Oscuros

Colores con Estado

Los colores con estado se utilizan para transmitir significado adicional para un componente de interfaz de usuario dado. Por ejemplo, podemos elegir colorear una alerta de advertencia con un tinte amarillo.

Hay 6 colores con estado: normal, hot, informativo, peligro, advertencia y éxito. Podemos personalizar estos colores modificando los colores de estado dentro de Theme Roller.

Colores con Estado

Utilidades de Colores Generales

Mientras que muchos componentes del Tema Universal hacen uso de estos colores automáticamente, también podemos usarlos en varios componentes personalizados. El Tema Universal proporciona una serie de clases CSS que se pueden utilizar para aplicar esta paleta de colores a cualquier etiqueta HTML.

Reglas CSS del Tema Universal 42:

  • Block: u-color-1                  
  • Text: u-color-1-text
  • Background: u-color-1-bg
  • Border: u-color-1-border

La clase u-Color permite definir el esquema del color, hay definidas en el Tema Universal 42 una cantidad de 45 colores diferentes, el cual se definen del 1 al 45.

Por ejemplo, vamos a crear una región de contenido estático, con la plantilla “Blank with Atributes” y en el origen colocamos el siguiente contenido HTML:

<div>

<h1>ORACLE APPLICATION EXPRESS 5.1</h1>

 <h3>Desarrolla</h3>

 <p> Utiliza nuestro moderno, intuitivo y poderoso entorno de desarrollo para construir e implantar aplicaciones rápidamente facilitando el desarrollo iterativo.</p>

</div>

 Agregamos un Identificador estático llamado “miregiondemo” a la región para darle estilos CSS a la misma.

 En propiedades de la página, ingresamos en el sector de “CSS En Línea” las siguientes reglas CSS:

 #miregiondemo

div {height:200px;}

h1 {font-size: 2.5em;text-align:center; }

h3 {font-size: 1.5em;text-align:center; }

p {font-size: 1.2em;text-align:center; padding:5px 50px 5px 50px; }

Ingresamos a la Región Demo en propiedades de la región, nos ubicamos en la sección Diseño y colocamos el siguiente CSS en “Clases CSS de Columna”:

dm-ColorBlock u-Color-8-BG--bg u-Color-8-FG--txt

 

Al ejecutar la página podremos ver que la región toma el color del esquema asociado según el Tema Universal.


Como podemos ver en la imagen de colores primarios el 8 representa el color naranja.

Si por ejemplo usamos este CSS:

dm-ColorBlock u-Color-10-BG--bg u-color-7-text

Donde el color de fondo es 10 (rosado) y el color del texto es 7 (amarillo).

Utilidades de Colores con Estado

El Tema Universal ofrece 6 colores con estado: normal, hot, informativo, peligro, advertencia y éxito. Estas son las clases CSS que podemos usar para aplicar estos estados a nuestros propios controles de interfaz de usuario.

Status

Block

Text

Background

Border

Normal

u-normal

u-normal-text

u-normal-bg

u-normal-border

Hot

u-hot

u-hot-text

u-hot-bg

u-hot-border

Warning

u-warning

u-warning-text

u-warning-bg

u-warning-border

Danger

u-danger

u-danger-text

u-danger-bg

u-danger-border

Info

u-info

u-info-text

u-info-bg

u-info-border

Success

u-success

u-success-text

u-success-bg

u-success-border


Para conocer más sobre el Tema Universal les dejo una aplicación de referencia:

https://apex.oracle.com/pls/apex/f?p=42:6000:::NO:::


 

Gracias a los esquemas de colores predefinidos del Tema Universal podemos hacer eso de ellos en nuestos componentes personalizados.


Conoce el Tema Material APEX una alternativa al Tema Universal 42

$
0
0

Hola a todos, hoy quiero compartir con ustedes que se han cumplido 2 años del proyecto que ha iniciado Vincent Morneau del Tema Material APEX.

Vincent nos cuenta que hace 2 años empezó este proyecto con el objetivo de proporcionar una alternativa adecuada al Tema Universal. Lo ha estado publicando de forma gratuita desde entonces y hoy ha llegado a su 12ª versión.

Aqui les dejo el enlace de Material APEX: http://www.materialapex.com

Material APEX es un tema completo basado en las directrices de diseño de Google. Algunos puntos destacados:

  • Tiene más de 50 tipos de componentes (regiones, elementos, etc.)
  • Tiene más de 30 plantillas diferentes
  • Tiene más de 150 opciones de plantillas
  • Tiene soporte para el tema Roller

El proyecto es completamente de código abierto en https://github.com/vincentmorneau/material-apex

Es mantenido activamente y son bienvenidas las solicitudes de funciones y contribuciones de código.

Material APEX esta creado y diseñado por Google, Material Design es un lenguaje de diseño que combina los principios clásicos de diseño exitoso junto con la innovación y la tecnología. El objetivo de Google es desarrollar un sistema de diseño que permita una experiencia de usuario unificada en todos sus productos en cualquier plataforma.

Material Apex se puede descargar en diferentes formas:

  • Demo App: Descargar la app demo es la forma más fácil de aprender todas las funcionalidades que tiene este tema, estudiando la app como ha sido construida. (demo-app.sql aquí)
  • App Vacía: Descargar la app completamente vacía es recomendado para nuevos proyectos. (empty-app.sql here)
  • Github: Aquí se encuentra el código fuente. Esto te da tanto poder como sea posible. Desde allí puedes hacer lo que quieras para mejorar Material APEX. (código fuente aquí)

Cuando instalas la app demo en tu espacio de trabajo tienes la oportunidad de ver todos los componentes que ofrece:

  • Badges
  • Breadcrums
  • Buttons
  • Calendar
  • Cards
  • Carousel
  • Chips
  • Collasible
  • Collections
  • Dialogs
  • Dropdown
  • Feature Discovery
  • Forms
  • Icons
  • Images & Videos
  • Parallax
  • Spinners
  • Slider
  • ScrollFire
  • Tables
  • Tabs
  • Timeline
  • Transitions
  • Waves
  • Wizard

También nos muestra la sección de Diseño:

  • Colors
  • Grid
  • Helpers
  • Modals
  • Region Display Selector
  • Shadows
  • Typography

Y finalmente disponemos de los patrones que usa:

  • Interactive Gris
  • Interactive Reports
  • Login page
  • Error page
  • APEX_ITEM_API
  • Data Loading
  • Plugins
  • Button Positions

Veamos algunas capturas de pantalla de los componentes, cada componente tiene varias opciones de presentación según como está configurado y en la app nos muestra la información de su configuración según lo que se muestra.

Componente Cards

Componente Botones

Componente Chips

Componente Imagenes y Video

Componente Parallax

Componente Timeline

Si llegaste hasta aquí, podrás ver cuán interesante es este Tema Material APEX, por ello, te invito a que lo descargues y empieces a ver toda su gran potencia con un diseño elegante y moderno para tus aplicaciones en Oracle APEX.

Desde ya muchas gracias a su autor Vincent Morneau que desde hace tantos años está trabajando arduamente en su mantenimiento junto a todos los que colaboran para que este proyecto siga con vida!

Estamos a 37 días del inicio del Oracle Developer Tour 2017!

$
0
0

Hola mis amigos!

He estado un poquito ausente en este último mes pues he estado trabajando en la actulización del sitio web del ODT y en la organización del evento que desde ya hace 5 años que venimos trabajando los distintos Grupos de Usuarios Oracle de Latinoamérica que se suman año a año a este gran evento!

Recuerdo cuando iniciamos este desafío con los Grupos de Usuarios Oracle de Argentina, Uruguay y Brasil, allá por el año 2112, habiendo creado el evento llamado “Oracle APEX Tour Latinoamérica”, solo para los fanáticos de Oracle Application Express, no habíamos imaginado que 5 años después estaríamos frente a un evento el cual no solo participa APEX sino todas las tecnologías de desarrollo para bases de Datos Oracle!

Es un gran orgullo y una gran satisfacción anunciar que este año son 9 los países que participan del Oracle Developer Tour! Con el apoyo de los Grupos de Usuarios de Argentina, Brasil, Chile, Colombia, Costa Rica, Ecuador, México, Panamá y Paraguay esto no podría haber sido logrado!

He desarrollado una aplicación en APEX con la información del evento que poco a poco la iremos actualizando con el envío de la información de los diferentes grupos de usuarios.

Acceso a la Aplicación:

https://apex.oracle.com/pls/apex/f?p=111937:1::::::

Tenemos nuestro sitio web del evento en español y portugués el cual estaremos publicando los enlaces de registración de cada país como así también toda la información del evento.

Sitio Web en español: http://odtlatam.com/

Sitio web en portugués: http://odtlatam.com/pt/

Si necesitas contactarte con el comité organizativo del evento ya sea para ser sponsor del evento en tu respectivo país o para ser voluntario en el día del evento puedes hacerlo escribiendo al siguiente email: info@odtlatam.com

A todos los que tienen pasión por el desarrollo en tecnologías Oracle, te esperamos en este mega evento latinoamericano con Oradores Internacionales, regionales y locales que nos brindaran todo su experiencia y conocimiento y lo mejor de todo que el evento es gratuito para la mayoría de los países!

Podemos monitorear la base de datos desde APEX?

$
0
0

Para monitorear la base de datos disponemos de una utilidad dentro del módulo del Taller de SQL llamada “Control de Base de Datos” que nos muestra información de DBA.

Para poder tener acceso a dicha utilidad necesitamos primero configurarla en el espacio de trabajo INTERNAL.

Ingresamos y seleccionamos Gestionar Instancia --> Valores de Instancia --> Configuración de Función:

Activamos el control de base de datos en el Taller de SQL, colocando .

Seleccionamos cómo se registra la actividad para todas las aplicaciones de esta instancia, en nuestro caso: siempre.

Las opciones incluyen:

  • Usar Configuración de Aplicación (por defecto): utilice el atributo Registro de cada aplicación para determinar si se registra la actividad.
  • Nunca: desactiva el registro para todas las aplicaciones de la instancia.
  • Siempre: activa el registro para todas las aplicaciones de la instancia.
  • Desactivado Inicialmente para Nuevas Aplicaciones y Aplicaciones Empaquetadas: el registro de actividades de las aplicaciones nuevas y de las empaquetadas estará inicialmente desactivado.

Activamos el rastreo de la aplicación en . Cuando se activa, los desarrolladores pueden generar un archivo de seguimiento de base de datos para la ejecución completa de un evento de página.

Aplicamos los cambios.

Nos conectamos a nuestro espacio de trabajo, hacemos clic en el Taller de SQL y luego en Utilidades y finalmente seleccionamos “Control de Base de Datos”.

Se presentará una pantalla en la cual nos pedirá las credenciales del usuario con permisos de DBA.

Una vez ingresada las credenciales, podemos ver las 4 áreas en el cual podemos monitorear la base de datos:

  • Sesiones
  • Estadísticas del Sistema
  • SQL Principal (Top SQL)
  • Operaciones Largas

Sesiones: Vemos información sobre las sesiones, los bloqueos, esperas, E/S, SQL y los cursores abiertos:

En la siguiente imagen vemos un ejemplo de visualización:

Estadísticas del Sistema: nos muestra un resumen de las estadísticas de E/S Física, E/S Lógica, Memoria, Tiempos, Cursores, Transacciones.

Top SQL o SQL Principal: tenemos diferentes filtros para mostrar las consultas SQL en el reporte. Este reporte nos muestra las SQL que más se ejecutan y los recursos que se consumen para ayudarnos a identificar las consultas SQL que bajan el rendimiento de la base de datos.

Operaciones Largas: Aquí se muestran las operaciones que tardan más de 6 segundos. Estas operaciones son consideradas largas para la base de datos.

Cómo distribuir información en múltiples tabs en Oracle APEX 5.1

$
0
0

En este pequeño post quiero mostrar como usar el tab container para distribuir información en múltiples tabs.

Para este ejemplo vamos a crear una página en blanco y realizar los siguientes pasos:

1) Creamos una región de contenido estático, la llamaremos TAB
2) En la sección apariencia indicamos que la plantilla sea “Tabs Container”
3) Dentro de esa región creamos una subregión, por ejemplo puede ser una región de informe clásico con la siguiente consulta de origen: select * from emp 
4) En la sección Diseño indicamos que la Región principal es: “TAB” que quiere decir que esta subregión es hija de la región TAB
5) Creamos otra subregión, puede ser de informe clásico o cualquier otro tipo de región, según lo que necesitemos, por ejemplo yo he creado otra subregión de tipo informe clásico con la siguiente consulta sql: select * from emp where deptno = 20 
6) Volvemos a indicar que la Región principal es: “TAB”, para que en los informes clásicos no se vean el título podemos usar para cada uno en plantilla que sea “Blank with Attributes”.
7) Creamos otra subregión, puede ser de contenido estático e indicamos que su región padre es “TAB”


Aquí abajo muestro una imagen del diseñador de páginas:

Resultado:

En las subregiones podemos colocar el contenido que nosotros necesitamos mostrar en nuestra página ya sea informes, contenido estático y dinámico, imágenes, etc.

Cómo manejar el ancho de columnas en los Informes en Oracle APEX 5.1

$
0
0

Deben existir diferentes formas de manejar el ancho de columnas en los informes en Oracle APEX 5.1.

En este artículo voy a mostrar dos de ellas. Por ejemplo, tenemos un informe interactivo de la tabla Empleados (EMP):

Y queremos modificar el ancho de la columna Job.
Desde el diseñador de páginas:
·       Seleccionamos la columna JOB
·    En la sección Column Formatting, escribimos el siguiente código HTML en el recuadro de HTML expression:
<span style='width:500px;display:inline-block;'>#JOB#</span>
 
Consideración: las columnas de tipo link no tienen esa sección en el panel de propiedades, sin embargo, podemos colocar en atributos del link el ancho de la columna que necesitamos:
style='width:300px;display:inline-block;'
La otra forma de controlar el ancho de las columnas es usando un identificador estático de la región del informe interactivo y un identificador estático de columna.
Por ejemplo, coloquemos el identificador estático COLENAME en la columna ENAME:
Lo mismo hacemos en el informe interactivo, seleccionamos Empleados e ingresamos el Static ID como EMP.
Luego hacemos clic en el título de la página e ingresamos en CSS inline la siguiente regla:
#EMP th#COLENAME, #EMP td[headers=COLENAME]{min-width:250px}
 
Ejecutamos la página y podemos ver que la columna de ename se ha modificado por el ancho que le pusimos, además de ver la columna JOB modificada, al punto que ahora se visualiza la barra horizontal de desplazamiento porque las columnas superan el ancho de la región.
Hasta la próxima!

Cómo definir las preferencias del espacio de trabajo actual en Oracle APEX 5.1

$
0
0

Vamos a aprender en este artículo a conocer cómo definir y controlar las preferencias para el espacio de trabajo.

Para definir las preferencias del espacio de trabajo debemos iniciar sesión con el usuario Administrador; es importante destacar que todas estas configuraciones afectarán todas las aplicaciones que se encuentren alojadas dentro del Espacio de Trabajo.

1. Hacemos clic en el Menú de Administración > Gestionar Servicio > Definir Preferencias de Espacio de Trabajo

2. Se abre la página de las Preferencias del Espacio de Trabajo

3. En la sección Control de Conexión de Cuenta: Disponemos de dos opciones en Vencimiento y Bloqueo de Cuenta:

- Activar

- Desactivar

Esta función proporciona seguridad de autenticación adicional para las aplicaciones. Si seleccionamos Activar, las contraseñas de la cuenta de usuario vencerán después de un período de tiempo configurable, las cuentas se bloquearán después de un número configurable de fallos de autenticación y las contraseñas de la cuenta se pueden definir para que venzan después del primer uso.

Si el administrador de Application Express para esta instalación ha definido el valor de entorno Requerir Bloqueo y Vencimiento de Cuenta de Usuario en , esto significa que la función se debe activar para todos los espacios de trabajo y el elemento mostrará Activar y el administrador del espacio de trabajo no lo puede cambiar.

4. En la sección Creador de Aplicaciones:

  • Activar Creador de Aplicaciones: Sí / No

Aquí especificamos si deseamos activar el uso y desarrollo del Creador de aplicaciones para el espacio de trabajo actual. Podemos seleccionar Sí o No.

Este valor también controla la disponibilidad de las aplicaciones empaquetadas para el espacio de trabajo actual.

5. En la sección del Taller de SQL:

  • Activar Taller de SQL: Sí
  • Edición de PL/SQL: Permitir Edición de Unidad de Programa PL/SQL

Esta función está diseñada para evitar que los programadores cambien código PL/SQL directamente desde el diccionario de datos. Si seleccionamos No Permitir Edición de Unidad de Programa PL/SQL, los desarrolladores podrán crear y sustituir las unidades de programa PL/SQL mediante los archivos de comandos o el procesador de comandos SQL.

  • Activar Servicios RESTful: Sí / No

Especificamos si deseamos activar los servicios RESTful en el espacio de trabajo actual.

  • Prefijo de Ruta de Acceso: <NOMBRE_ESPACIO_DE_TRABAJO>

 Aquí especificamos el prefijo de la ruta de acceso URI que se va a utilizar para acceder a los servicios RESTful en el espacio de trabajo actual. El valor del prefijo de la ruta de acceso por defecto es el nombre del espacio de trabajo.

6. En la sección Desarrollo de Equipos:

  • Activar Desarrollo de Equipos: Sí/ No
  • Activar Repositorio de Archivos: Sí / No

Este atributo solo se puede modificar si la configuración de función "Activar Repositorio de Archivos de Desarrollo de Equipos" en la administración interna de Application Express se ha definido en "Sí".

  • Tamaño Máximo de Archivos (en MB): 15 (este es el valor por defecto)

Al activar la carga de archivos en Desarrollo de Equipos, se creará una tabla de APEX$.

De esta forma muy sencilla podemos definir las preferencias del espacio de trabajo actual, que afectarán a todas las aplicaciones del mismo. 

Webinar: Globalización, Aplicaciones Multilenguaje en Oracle APEX 5.1 - Parte I de II

$
0
0

En esta sesión, Clarisa Maman Orfali nos presentará el tema: Globalización: Creación de Aplicaciones Multilenguaje. Veremos cómo crear una aplicación multilenguaje, además veremos cómo APEX maneja el proceso de traducción y cómo implementar una aplicación traducida en Application Express. Veremos cómo el usuario puede seleccionar su idioma deseado y cómo cambiar entre los idiomas disponibles. Adicionalmente,

Jorge Rimblas nos presentará: Trabajando con traducciones en el modelo de datos. Por medio de un plugin de APEX y ajustes al modelo de datos usando JSON podemos de manera sencilla trabajar con multiples traducciones.

Ver Presentación

Descargar APP Demo

(Please visit the site to view this video)


Webinar: Globalización, Aplicaciones Multilenguaje en Oracle APEX 5.1 - Parte II de II

$
0
0

En esta sesión, Clarisa Maman Orfali nos presentará el tema: Globalización: Creación de Aplicaciones Multilenguaje. Veremos cómo crear una aplicación multilenguaje, además veremos cómo APEX maneja el proceso de traducción y cómo implementar una aplicación traducida en Application Express. Veremos cómo el usuario puede seleccionar su idioma deseado y cómo cambiar entre los idiomas disponibles.

Adicionalmente, Jorge Rimblas nos presentará: Trabajando con traducciones en el modelo de datos. Por medio de un plugin de APEX y ajustes al modelo de datos usando JSON podemos de manera sencilla trabajar con multiples traducciones. 

Ver Presentación

Descargar APP Demo

(Please visit the site to view this video)

Feliz Año 2018 para todos!

$
0
0

¡Que éste inicio del nuevo año sea un año lleno de éxitos personales y profesionales para cada uno!

Este año 2017 fue un año en el cual he podido cumplir muchas metas personales y profesionales,  entre ellas, lanzar mi tercer libro sobre Oracle APEX 5.1 en versión Kindle y Paperback.


He creado dos cursos online:


He sido Sponsor y parte del comité organizativo del Oracle Developer Tour 2017. Visitar sitio web AQUI

He logrado certificarme como Coach de Vida:

Sigo entrenándome y estudiando Programación Neurolingüística (PNL) meta que pieno cumplir en el año 2018.
 
Más de 50 articulos de blog escritos!
Muchos logros personales y famiiares logrados, viajes realizados, y mucho más por hacer en el 2018!
Balance del año 2017 muy positivo y con muchas ganas de hacer muchas cosas mas en el 2018!
Quiero agradecer a todos mis seguidores y los que continuamente me estan apoyando a seguir adelante!
Muy Feliz Año Nuevo para todos!!!
Con todo mi cariño, nunca dejes de aprender y creer en tus habiliades para ser feliz!
Clarisa

Every VARCHAR2(N) Declaration a Bug!

$
0
0

This is something I say in my best practice trainings:

Consider every VARCHAR2(N) declaration to be a bug– unless it's a SPOD.

What, you might ask, is a SPOD? It's the single point of definition - the one place in your code where the thing you are working with (datatype, formula, magic value, etc.) is defined or, to put it another way, hard-coded.

You don't want to repeat magic values in your application and you don't want to repeat formulas...but all too many of us are happy to write code like this:

PROCEDURE process_employee (department_id IN NUMBER)
IS
l_id employees.employee_id%TYPE;
l_fullname VARCHAR2 (100);
CURSOR emps_in_dept_cur
IS
SELECT employee_id, last_name || ',' || first_name lname
FROM employees
WHERE department_id = department_id;

Notice in particular that VARCHAR2(100) declaration. Now, sure, I know that I should use %TYPE to anchor to a database column, as I did with l_id. But I cannot; the "full name" is derived from the first and last names. So what should I do?

Well, what I will most likely do is be lazy: look up the structure of the employees table, note that the maximum length of first name is 20, last name is 25, so that's 46 with the comma. Hey, I'll double that, round up to 100 - the full name will never get that big!

Yeah, well, unless the DBA expands the maximum length of those columns.

Seems fairly hypothetical, right? Sadly, I ran into just such a scenario yesterday in the Application Express application for the PL/SQL Challenge (www.plsqlchallenge.com).

A user complained of the classic " ORA-06502: PL/SQL: numeric or value error: character string buffer too small" error when trying to view a quiz from April 20, 2010 - way back at the beginning of the PL/SQL Challenge. So immediately I wondered how things had changed since then, since players are not reporting similar errors for newer quizzes. Ah, the bad assumptions we make!

Well, fortunately, I could reproduce the error without difficulty. And APEX 4.1 gives us a lot of error information so I saw this:

So I opened up the page in Application Express and found this code in the Region Source:

DECLARE
CV SYS_REFCURSOR;
r qdb_news%ROWTYPE;
l_after_first BOOLEAN := FALSE;
BEGIN
CV :=
qdb_competition_mgr.news_for_quiz (
quiz_id_in => :p651_quiz_id);
LOOP
FETCH CV INTO r;
EXIT WHEN CV%NOTFOUND;
HTP.bold ('<h4>' || r.title || '</h4>');
HTP.p (r.full_text);
IF r.discussion_url IS NOT NULL
THEN
HTP.p (
'Click <a href="'
|| r.discussion_url
|| '" onClick="window.open('''
|| r.discussion_url
|| '''); return false; var x__ = parseInt'
|| '">here</a> for more information and discussion on this point.');
HTP.p ('<br/>');
END IF;
END LOOP;
CLOSE CV;
END;

I couldn't see any reason in my code to cause a VALUE_ERROR exception - but maybe there was a problem passing a large string to the HTP subprograms? So I pasted it into Toad and ran it - and got a VALUE_ERROR exception. I added some trace statement, ran it again - and again - but no longer got the VALUE_ERROR exception. I did notice, however, that the full_text string was about 1200 characters long.

Very frustrating! I still do not know why I got such an error the first time I ran it. A mystery without a resolution. Ever have any of those?

Eventually, I gave up on this code - it really didn't seem to have a problem. And I looked further down on the page, to the Condition code. And what do I find there, but the following:

DECLARE
l_news_title VARCHAR2(1000);
l_news_text VARCHAR2(1000);
BEGIN
qdb_competition_mgr.get_news_for_quiz (
quiz_id_in =>:p651_quiz_id
, news_title_out => l_news_title
, news_text_out => l_news_text);
IF l_news_title ISNOTNULL
AND:p651_hide_answers ='show'
THEN
RETURNTRUE;
ELSE
RETURNFALSE;
ENDIF;
END;

Oh my. Someone (can't imagine who J No seriously I don't think it was me!) took a "short cut" and decided that the title and text of the news item couldn't ever possibly exceed 1000 characters.

Oh, no, of course not.

But for this particular quiz, way back on April 20, 2010, it did.

Well, the fix was then quite straightforward. I changed the declaration section to:

DECLARE
l_news_title qdb_news.title%TYPE;
l_news_text qdb_news.full_text%TYPE;
and the problem disappeared.

An excellent reminder to me, and now to all my readers, that you should:

Consider every VARCHAR2(N) declaration to be a bug– unless it's a SPOD.

You are probably wondering, like me, why the error wasn't reported sooner - like on April 21, when players would be reading the news. The only explanation I have for that is this problematic code wasn't introduced until much later, as we revised the way we displayed the news.

Like I say: the mysteries of programming!

My First APEX Application For A Swedish Logistics Company Is In Production Now !!

$
0
0
After a long time went back writing SQL's and PL/SQL blocks, triggers, procedures & functions again.....140 Hrs of learning apex and working after my regular work has paid, Memories of my initial developer days, My first Oracle APEX 4.1 application is out in production for a Swedish logistics company.

Anybody interested in developing quick applications for yourself, Please start learning APEX, Its quick and smart and easy...

Below are the few screen shots of the application.

Oracle APEX 4.1
Oracle 11g R1 database
Oracle BI Publisher For Reports






Happy Learning!

Oracle OpenWorld Submissions - The Full Monty

$
0
0
Here one day before deadline, I have entered almost my entire current catalog of presentations for consideration in the Oracle OpenWorld 2013 agenda . One new for this year: “Worst Oracle ADF Project Ever” If you would like me to speak at one of your events, the following are the presentations I currently have prepared - feel free to email me at sten@vesterli.com . If you don’t have budget for speaker travel and accommodation and plan to ask the Oracle ACE Program for support...(read more)

I am sailing…

$
0
0
Next week, I’m off for the OUGN Spring Conference that the Norwegian Oracle User Group arranges on board a cruise ship sailing from Oslo to Kiel and back. This event gathers the Oracle A-List, including Tom Kyte, Cary Millsap, Bryn Llewellyn, Mark Rittman, Markus Eisele and many others - it’s an honor to be part of such a lineup. My presentations are: Ten Secrets of Successful ADF Projects APEX or ADF? From Requirements to Tool Choice I’ve heard that there are still...(read more)

An APEX Database Monitoring App for XE – Guilty GUI pleasures

$
0
0
Guilty pleasures. For some, it’s a “diet” burger with “diet” fries, washed down with a “diet” shake. Others have a penchant for Kurt Geiger shoes. “I’m Welsh and I’m worth it”, they may well say. It may even be that Def Leppard track nestled in your playlist between Coldplay and Oasis. In programming terms, APEX seems to fall into this category for me. On the one hand, it’s a declarative development environment. This means...(read more)

Coding Therapy comes to Montreal!

$
0
0

On September 10-11, ODTUG will hold its latest APEXposed conference in Montreal. I am honored to be a keynote speaker on the 11th, and I will reprise my world-famous "Coding Therapy for Software Developers" presentation. Here's a description:

We can't write software without our brains, and our brains come with a full load of "issues." The way our brain remembers the past and projects into the future has a big impact on how we write code. Moving beyond physiology, human psychology also plays its role, making it difficult for us to acknowledge ignorance and ask for help. Steven will in this session address offer an intensive coding therapy session (including couples therapy, dream therapy, game theory, and shock therapy) to help all attendees come to grips with their innate, unavoidable "issues", making it easier to write better code -- and help others on their team write better code.

And if you cannot attend the conference, you can check out the therapy sessions that Dell (then Quest) recorded back in 2012:

I am looking forward to returning to Montreal. Years and years ago, I brought Eli with me (then perhaps 10 or 11, now 26) while I did a full day training for the user group. He stayed in the hotel room, I went to the ballroom to present. Two hours later, the fire alarm goes off in the hotel. OMG, where is Eli? Is he OK? Everyone milled around in the lobby....and I found him, hanging out and playing Magic cards with an attendee of the training. Whew.

Turning off Password expiration on Oracle XE and Apex

$
0
0
It is a strange time in the UK. I’m not referring to England being 2-0 up after 2 tests in the Ashes (something that happens about as often as a Briton winnng the Men’s Singles at Wimbledon), nor the fact that a Briton has won the Tour de France for the second year running. Stranger even than that is the bright yellow ball in the sky which has replaced the traditional warm rain of the British Summer. This phenomenon has had a strange effect on the cat. Her animal instincts obviously...(read more)

Re-structuring data for Hierarchical Queries – or (Tree) Walking With Big Macs

$
0
0
Steve McNulty. Even the name sounds a bit hard. This is not the hero in Jason Statham’s latest celluloid exploit. Neither is it the central character in a hard-bitten cop drama. Steve McNulty is, in fact the current Luton Town captain and a member of an endangered species – the stopper Centre-Half. When you first set eyes on him, he looks, well, a bit chunky. You might imagine his nickname to be “Big Mac” because of his penchant for a certain fast-food chain. This is something...(read more)

APEX and Privileges Granted through Roles

$
0
0

The mystery has finally been solved. England’s surrendering of the Ashes last winter was nothing to do with Australia being a much better cricket team. Thanks to Kevin Pietersen’s recently published Autobiography, we now know that the problem was that there were rather too many silly points in the England dressing room.
Moving swiftly on from that weak pun, the subject at hand can also be rather mystifying at first glance.

In a “traditional” Oracle Forms application, you would have one database user per application users.
Connections via the Application to the database would be done as the individual users.
It’s quite likely that database roles would be used to grant the appropriate privileges.

For applications using other web technologies, the application may interact with the database via a single account, often that of the Application Owner. Whether or not this is a good idea is probably a discussion for another time.

For now though, the question we’re asking is, how an APEX application connect to the database ?
On the face of it, it would seem that it’s pretty similar to the second of the two approaches above. APEX connects as the Parsing Schema (usually the application owner).
As Kevin will tell you, appearances can be deceiving…

The Environment

For the purposes of this post, I’ll be using a simple APEX application that’s been created in it’s own workspace.
The application is called NEW_HR and uses the default APEX Authentication Scheme.
The parsing schema is defined as HR.
At this point the application consists of a login screen and a blank Home Page.
I’ve also created a Workspace Admin user called…well…let’s call it Kevin.
The database version is Oracle 11g Express Edition and the APEX version is 4.2.
This environment uses the embedded PL/SQL Gateway to manage database connections from APEX. This is the default setup on Oracle 11g XE.

Who am I ? No, really

Now, I know that there is no user called KEVIN in my database….

select count(*) 
from dba_users 
where username = 'KEVIN'
/
  COUNT(*)
----------
         0

SQL> 

…so I’d like to know who the database thinks I am when I login through my APEX app. I’d also like to check who the APEX itself thinks I am.

The first step then, is to add a couple of fields to the application Home Page…

First of all, I’ve add an HTML Region called whoami. Apart from the name I’ve just accepted the defaults.

Now to add a field to display the Application User – i.e. who APEX thinks I am.

This is a Display Only Item called P1_APEX_USER in the whoami region.
The source settings for this item are the defaults except for :

Source Used : Always, replacing any existing value in session state
Source value or expression : APP_USER

apex_user_source

Next up is to add a field to display the database user.

The field is defined in the same way as P1_APEX_USER, except for :

Source Type : SQL Query (return single value)

and the source itself which is the following query :

select user from dual

db_user_source

Now, if we connect as Kevin….

login

…we can start to resolve our identity crisis….

whoami

So, as expected, APEX knows that Kevin is the Application user. However, the database user is not HR, rather it’s something called ANONYMOUS.

NOTE– If you’re using the Embedded PL/SQL Gateway ( the default setup for Express Edition) then you’ll be connected as ANONYMOUS. If you have the APEX Listener setup then, unless you’ve changed the default, you’ll be connected as APEX_PUBLIC_USER.
For our current purposes we can treat these accounts as synonymous from a database standpoint.
I’ll continue to refer to ANONYMOUS from here on because (a) I’m running this on XE and (b) the name has slightly more comedic potential.

Let’s find out a bit more about this user whilst trying not to worry that our application has been visited by hacktivists.
Hmmm, maybe not so much comedic potential.

The ANONYMOUS User

Looking in the database, we can confirm that ANONYMOUS is indeed a database user :

select account_status, profile, authentication_type
from dba_users
where username = 'ANONYMOUS'
/

ACCOUNT_STATUS                   PROFILE                        AUTHENTI
-------------------------------- ------------------------------ --------
OPEN                             DEFAULT                        PASSWORD

Doesn’t seem to be anything out of the ordinary there.
Now let’s see what ANONYMOUS has granted to it. For good measure, we can see what objects it owns ( if any).
The query looks like this :

select 'SYSTEM PRIVILEGE' as priv_type,
    null as db_object,
    privilege
from dba_sys_privs
where grantee = 'ANONYMOUS'
union
select 'ROLE GRANTED' as priv_type,
    granted_role as db_object,
    null as privilege
from dba_role_privs
where grantee = 'ANONYMOUS'
union
select 'OBJECT PRIVILEGE' as priv_type,
    owner||'.'||table_name as db_object,
    privilege
from dba_tab_privs
where grantee = 'ANONYMOUS'
union
select 'OWNED OBJECT' as priv_type,
    object_name as db_object,
    null as privilege
from dba_objects
where owner = 'ANONYMOUS'
order by 1,2
/ 

When we run it we get variations on the theme of :

PRIV_TYPE            DB_OBJECT                                                    PRIVILEGE
-------------------- ------------------------------------------------------------ ------------------------------
OBJECT PRIVILEGE     APEX_040000.WWV_FLOW_EPG_INCLUDE_MODULES                     EXECUTE
OBJECT PRIVILEGE     APEX_040200.WWV_FLOW_EPG_INCLUDE_MODULES                     EXECUTE
OBJECT PRIVILEGE     FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$                           ALTER
OBJECT PRIVILEGE     FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$                           DELETE
OBJECT PRIVILEGE     FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$                           FLASHBACK
OBJECT PRIVILEGE     FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$                           INDEX
OBJECT PRIVILEGE     FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$                           INSERT
OBJECT PRIVILEGE     FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$                           ON COMMIT REFRESH
OBJECT PRIVILEGE     FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$                           QUERY REWRITE
OBJECT PRIVILEGE     FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$                           REFERENCES
OBJECT PRIVILEGE     FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$                           SELECT
OBJECT PRIVILEGE     FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$                           UPDATE
SYSTEM PRIVILEGE                                                                  CREATE SESSION

Now, the Object Privileges listed here are probable the result of some of the sample APEX applications I’ve installed.
By default, the only thing granted to ANONYMOUS is the CREATE SESSION privilege.

More pertinent here though is that it has no permissions at all on any objects owned by HR. This begs the question as to how our APEX application will work. Remember, our parsing schema ‎( essentially the Application Owner) is HR. Therefore, it’s reasonable to assume that we’ll want to interact with the tables in that schema.

NOTE– at this point I should add that, of course, ANONYMOUS does have additional privileges – i.e. everything granted to PUBLIC in the database. Whilst th‎is is not strictly relevant to the matter at hand, it’s probably worth bearing in mind when you look at how you implement security around this user.

Anyway, let’s put it to the test…

The Regions Report

In our application we’re going to create a new page – a Report on the HR.REGIONS table so…

In the Application Builder, click on Create Page :

create_page

Select Report and click Next

Select Interactive Report and click Next

Accept the defaults for Page Region Attribute and click Next

In Tab Options choose Use an existing tab set and create a new tab within the existing set
New Tab Label is Regions :

tab_options

Click Next

For the SQL Query :

select region_id, region_name
from regions

Note– we’re not specifying the table owner in this query, even though ANONYMOUS does not have a synonym on the HR.REGIONS table ( let alone any privileges)

query

Click Next

…and click Create

create

When we now connect to the application as Kevin and click on the Regions tab….

regions

So, the report has worked without error, despite the lack of privileges and synonyms. So what’s happening ?

Session Privileges in APEX

To answer this, we’ll need to tweak our earlier privileges query. This time, we’ll use the USER_ version of the views.
We can then it to the Application Home Page in a new reports region to see what ANONYMOUS can actually do when connected via APEX.

First, the new query, using USER_ versions of the views and without the order by clause.

select 'SYSTEM PRIVILEGE' as priv_type,
    null as db_object,
    privilege
from user_sys_privs
union
select 'ROLE GRANTED' as priv_type,
    granted_role as db_object,
    null as privilege
from user_role_privs
union
select 'OBJECT PRIVILEGE' as priv_type,
    owner||'.'||table_name as db_object,
    privilege
from user_tab_privs
union
select 'OWNED OBJECT' as priv_type,
    object_name as db_object,
    null as privilege
from user_objects
where object_type != 'INDEX'
/

Spoiler Alert– the reason I’m not using the SESSION_PRIVS view here is because it will list privileges granted via roles. The distinction between these and directly granted privileges will shortly become apparent.

We now simply create a new interactive reports region called User Privileges on the Home Page, using the above query.
If we now filter on PRIV_TYPE = ‘OWNED OBJECT’, we can see that we’ve magically acquired ownership of all the HR objects…

owned_objects

If we filter on PRIV_TYPE = ‘SYSTEM PRIVILEGE’, we can see that we also seem to have inherited HR’s System Privileges…

sys_privs

So, we can infer from this that, although the database connection from APEX is as the ANONYMOUS user, the session will inherit all of the objects and privileges of the parsing schema.
A reasonable assumption, given the evidence, and a correct one…mostly.

Objects not owned by the parsing schema

I’ve created a simple function in my own schema :

create or replace function name_scandal_fn( i_basename varchar2)
    return varchar2
as
begin
    return i_basename||'gate';
end;
/

Next we’re going to create a role and then grant execute on this function to that role. Finally, we’re going to grant the role to hr :

create role hr_role
/

grant execute on name_scandal_fn to hr_role
/

grant hr_role to hr
/

First off, we’ll test this in SQL*Plus. Connect as HR and …

select mike.name_scandal_fn('Twitter') from dual
/

MIKE.NAME_SCANDAL_FN('TWITTER')
--------------------------------------------------------------------------------
Twittergate

SQL> 

So, we should have no problem invoking this function from our application then.

Let’s create a page with a Display Only field that is populated by a call to this function :

Blank Page :

fn_page1

Called Scandal

fn_page2

…With an HTML Region…

fn_page3

…on a new tab…

fn_page4

…and confirm…

fn_page5

Now, add the Item…

fn_item1

…called P3_SCANDAL_NAME…

fn_item2

Accept the defaults for the Item Attributes settings, and Settings…

… and change the Source settings to :

Source Used : Always, replacing any existing value in session state
Source Type : SQL Query (return single value)
Item Source Value – here we put in our call to the function :

select mike.name_scandal_fn('Twitter') from dual

fn_item3

Finally, hit the create button.

No problems so far. Now, let’s try running the page…

fn_err

Hmmm, not quite what we were expecting.

Looking at the error stack, a possible source of the problem emerges.
In the background, it looks as if APEX is calling a package called WWV_FLOW_FORMS, which in turn calls WWV_FLOW_DYNAMIC_EXEC.
Whilst the source for both of these packages is wrapped, there are some notes availble on the next package in the call stack, WWV_DBMS_SQL here.

Putting all together and looking at the package headers, it would seem reasonable to assume that, rather than running the SQL statement directly, APEX does this via a series of package calls which then run the statement as dynamic SQL.
The effect of calling a (presumably) Definer’s Rights package is that any privileges granted via roles are ignored.

In order to test this theory, we can revoke the role from HR and instead, grant execute on the function directly.
So, connected to SQL*Plus as the function owner ( in my case MIKE) :

revoke hr_role from hr
/

grant execute on name_scandal_fn to hr
/

Now a quick sanity check to make sure that HR can see the function.
Connect as HR and :

SQL> select mike.name_scandal_fn('Twitter') from dual
  2  /

MIKE.NAME_SCANDAL_FN('TWITTER')
--------------------------------------------------------------------------------
Twittergate

SQL> 

Now let’s see what APEX makes of this.
Re-run the page and we can see…

itworks

There you have it. APEX, like Kevin, is just a little bit different.


Filed under: APEX, Oracle, SQL Tagged: apex anonymous user, apex_public_user, granting privileges via roles, parsing schema

APEX 503 – Service Unavailable – And you don’t know the APEX_PUBLIC_USER Password

$
0
0

It’s probably Monday morning. The caffeine from your first cup of coffee has not quite worked it’s way into your system.
The cold sweat running down the back of your neck provides an unpleasant contrast to the warm blast of panicked users as they call up to inform you that the Application is down.
APEX, which has been behaving impeccibly all this time, has suddenly decided to respond to all requests with :

503 – Service Unavailable.

The database is up. The APEX Listener is up. But something else is up. APEX just doesn’t want to play.
Better still, the person who set up the APEX in the first place has long-departed the company. You have no idea how the Apex Listener was configured.

Out of sympathy with your current predicament, what follows is :

  • How to confirm that this problem is related to the APEX_PUBLIC_USER (the most likely cause)
  • A quick and fairly dirty way of getting things back up and running again
  • How to stop this happening again

Note: These steps were tested Oracle Developer Day VM with a 12c database running on Oracle Linux 6.5. In this environment, APEX is configured to run with the APEX Listener.

Confirming the APEX User name

First of all, we want to make sure that APEX is connecting to the database as APEX_PUBLIC_USER. To do this, we need to check the default.xml file.
Assuming you’re on a Linux box :

cd /u01/oracle/apexListener/apex
cat default.xml

If you don’t see an entry for db.username then APEX_PUBLIC_USER is the one that’s being used.
If there is an entry for db.username then that is the name of the database user you need to check in the following steps.
For now, I’ll assume that it’s set to the default.

Incidentally, there will also be an entry for db.password. This will almost certainly be encrypted so is unlikely to be of use to you here.

Confirming the status of the APEX_PUBLIC_USER

The most likely reason for your current troubles is that the APEX_PUBLIC_USER’s database password has expired.
To verify this – and get the information we’ll need to fix it, connect to the database and run the query :

select account_status, profile
from dba_users
where username = 'APEX_PUBLIC_USER'
/

If the account_status is EXPIRED, then the issue you are facing is that the APEX_PUBLIC_USER is expired and therefore APEX can’t connect to the database.

The other item of interest here is the PROFILE assigned to the user.
We need to check this to make sure that there is no PASSWORD_VERIFY_FUNCTION assigned to the profile. If there is then you need to supply the existing password in order to change it, which is a bit of a problem if you don’t know what it is.
Whilst we’re at it, we need to check whether there is any restriction in place as to the length of time or number of password changes that must take place before a password can be reused.
In my case, APEX_PUBLIC_USER has been assigned the DEFAULT profile.

select resource_name, limit
from dba_profiles
where profile = 'DEFAULT'
and resource_name in 
('PASSWORD_REUSE_TIME', 'PASSWORD_REUSE_MAX', 'PASSWORD_VERIFY_FUNCTION'
)
/

When I ran this, I was lucky and got :

RESOURCE_NAME                  LIMIT              
------------------------------ --------------------
PASSWORD_REUSE_TIME            UNLIMITED            
PASSWORD_REUSE_MAX             UNLIMITED            
PASSWORD_VERIFY_FUNCTION       NULL     

So, there are no restrictions on password reuse for this profile. Neither is there any verify function.

If your APEX_PUBLIC_USER is attached to a profile that has these restrictions, then you’ll want to change this before re-setting the password.
As we’re going to have to assign this user to another profile anyway, we may as well get it out of the way now.

The New Profile for the APEX_PUBLIC_USER

Oracle’s advice for the APEX_PUBLIC_USER is to set the PASSWORD_LIFE_TIME to UNLIMITED.

Whilst it’s only these four parameters we need to set in the profile for us to get out of our current predicament, it’s worth also including a limitation on the maxiumum number of failed login attempts, if only to provide some limited protection against brute-forcing.
In fact, I’ve just decided to use the settings from the DEFAULT profile for the attributes that I don’t need to change :

create profile apex_public limit
    failed_login_attempts 10
    password_life_time unlimited
    password_reuse_time unlimited
    password_reuse_max unlimited
    password_lock_time 1 
    composite_limit unlimited
    sessions_per_user unlimited
    cpu_per_session unlimited
    cpu_per_call unlimited
    logical_reads_per_session unlimited
    logical_reads_per_call unlimited
    idle_time unlimited
    connect_time unlimited
    private_sga unlimited
/

As we don’t specify a PASSWORD_VERIFY_FUNCTION, none is assigned to the new profile.

NOTE – it’s best to check the settings in your own default profile as they may well differ from those listed here.

Next, we assign this profile to APEX_PUBLIC_USER…

alter user apex_public_user profile apex_public
/

The next step is to reset the APEX_PUBLIC_USER password, which is the only way to unexpire the user.

No password, no problem

Remember, in this scenario, we don’t know the current password for APEX_PUBLIC_USER. We don’t want to reset the password to just anything because we’re not sure how to set the password in the DAD used by the Apex Listener.

First of all, we need to get the password hash for the current password. To do this :

select password
from sys.user$
where name = 'APEX_PUBLIC_USER'
/

You’ll get back a hex string – let’s say something like ‘DF37145AF23CCA4′.

Next step is to re-set the APEX_PUBLIC_USER password :

alter user apex_public_user identified by sometemporarypassword
/

We now immediately set it back to it’s original value using IDENTIFIED BY VALUES :

alter user apex_public_user identified by values 'DF37145AF23CCA4' 
/

At this point, APEX should be back up and running.

Once the dust settles…

Whilst your APEX installation may now be back up and running, you now have a database user for which the password never changes.
Although the APEX_PUBLIC_USER has only limited system and table privilges, it also has access to any database objects that are available to PUBLIC.
Whilst this is in-line with Oracle’s currently documented recommendations, you may consider that this is a situation that you want to address from a security perspective.
If there is a sensible way of changing the APEX_PUBLIC_USER password without breaking anything, then you may consider it preferable to simply setup some kind of reminder mechanism so that you know when the password is due to expire and can change it ahead of time.
You would then be able to set the password to expire as normal.
If you’re wondering why I’m being a bit vague here, it’s simply because I don’t currently know of a sensible way of doing this.
If you do, it would be really helpful if you could let me know :)


Filed under: APEX, Oracle, SQL Tagged: APEX 503 Unavailable, create profile, dba_profiles, dba_users.account_status, failed_login_attempts, identified by values, password_reuse_max, password_reuse_time, password_verify_function
Viewing all 142 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>