martes, 19 de septiembre de 2023

Oracle 7 - Nuevo enfoque (4).Preparando el sistema de archvos docker para hacer backups de Oracle.

 0. Introducción

Créditos 

https://www.tutorialspoint.com/how-to-copy-files-from-host-to-docker-container

https://www.baeldung.com/linux/docker-mount-host-filesystem#:~:text=To%20mount%20a%20filesystem%20within,container%20target%20directory%20path

https://www.baeldung.com/linux/docker-container-add-volume

http://www.rebellionrider.com/?s=expdp

http://www.rebellionrider.com/?s=impdp

http://www.rebellionrider.com/?s=rman

1. Eligiendo un destino de las copias de seguridad

Se pueden hacer copias de seguridad dentro del sistema de ficheros propios del contenedor o también el el propio servidor físico.

2. Backups dentro  del sistema de ficheros docker

Se pueden hacer copias de seguridad dentro del sistema de ficheros propios del contenedor o también el el propio servidor físico.

En el primer caso utilizaremos el comando docker cp para copiar los ficheros entre el servidor físico y el contenedor docker tal como vimos en la entrada anterior:

#1. Listar los contenedores activos para ver su nombre
docker ps

#2. Copiar un fichero del servidor al contenedor
docker cp <src-path> <container-name>:<dest-path> 

#3. Copiar un fichero desde el contenedor al servidor
docker cp <container>:<src-path> <local-dest-path> 

3. Backups en carpetas compartidas con el servidor

OJO: No se debe compartir directamente una carpeta con un contenedor existente. Se puede hacer de forma no recomendable segun Baeldung  modificando el fichero de configuración JSON de docker situado en /var/lib/docker en Ubuntu

Se puede compartir una carpeta entre el servidor y un NUEVO contenedor a crear mediante mapeo directo de una carpeta del servidor o mapeando un VOLUMEN previamente creado con docker.

4. Dos formas de compartir carpetas en el servidor: Montaje directo y volúmenes

Veamos como se pueden crear los dos tipos de contenedores y como arrancarlos. En este caso para simplificar las cosas usaremos la imagen del linux Alpine


# OJO: puede que se pida ejecutar docker con "sudo"!
#-------------------------------------------------------------
#1. Contenedor que comparte la carpeta
#   del servidor/home/ximo/prueba y mapeándola a /tmp_prueba
#   en dicho contenedor            
#--------------------------------------------------------------
#1.1 Crear el contenedor (alpine) 
#                             <nombre contenedor>       <carpeta server>  <carpeta container> <nombre imagen> <programa a ejecutar>
docker container create --name my-alpine-share   -it -v /home/ximo/prueba:/tmp_prueba         alpine:latest   /bin/sh

#1.2 Arrancar el contenedor (alpine) 
docker container start -i my-alpine-share

#--------------------------------------------------------------
#2. Proceso de crear un contendedor que comparta un volumen
#--------------------------------------------------------------
#2.1 Manejo de un volumen 
#2.1.1 Crear un volumen
docker volume create my-volume

#2.1.1 Ver los volumenes creados
docker volumen ls

#2.1.2 Mostrar informacion del volumen
docker volume inspect my-volume

# Y obtenemos la ruta de montaje
#[
#    {
#        "CreatedAt": "2023-09-20T09:12:31+02:00",
#        "Driver": "local",
#       "Labels": null,
#        "Mountpoint": "/var/lib/docker/volumes/my-volume/_data",
#        "Name": "my-volume",
#        "Options": null,
#        "Scope": "local"
#    }
#]

#2.2 Manejo del contendor
#2.2.1 Crear un contenedor (alpine) compartiendo el volumen
#      del servidor/home/ximo/prueba y mapeándola a /tmp_prueba
#      en dicho contenedor                        

#                            <nombre contenedor>            <volumen>        <carpeta container>   <nombre imagen> <programa a ejecutar>
docker container create --name my-alpine-volume -it --mount source=my-volume,target=/opt/my-volume alpine:latest   /bin/sh

#2.2.2 Arrancar el contenedor (alpine) 
docker container start -i my-alpine-volume

Se recomienda crear un volumen pues es mas eficiente (la segunda opción)

5. Proceso de asignación de carpetas compartidas a un contenedor existente

En el apartado anterior hemos visto como crear contenedores nuevos a partir de imágenes y montando las carpetas compartidas o volumenes a compartir. Pero lo mas normal es que nos encontremos con contenedores previamente existentes que no se les ha montado una carpeta o volumen compartido.

Como no debemos asignar carpetas compartidas a un contenedor existente, lo mas cómodo es:

  1. Crear una nueva imagen a partir de un contenedor existente
  2. Crear un contenedor a partir de esta imagen al cual le añadiremos un VOLUMEN previamente creado o el mapeo de la carpeta del servidor (visto en el punto anterior
Para crear una imagen de un contenedor existente se puede hacer de dos maneras:
  1. docker container export y docker container import
  2. docker container commit
Vemos un ejemplo de cada uno de ellos

# OJO: puede que se pida ejecutar docker con "sudo"!
#-------------------------------------------------------------
#1. Contenedor que comparte la carpeta
#   del servidor/home/ximo/prueba y mapeándola a /tmp_prueba
#   en dicho contenedor            
#------------------------------------------------------------------
#1. Exportar el contenedor como imagen en un fichero "tar" (export)
#------------------------------------------------------------------
#1.1 Comando a utilizar para exportar
#                          <fichero.tar>    <nombre-contenedor>
docker container export -o my-alpine.tar     my-alpine

#1.2. Ver el contenido del fichero "tar"
tar -tvf myalpine-vol.tar

#

#1.3. Crear una imagen a partir de este fichero "tar"
#                   <fichero tar> <-nombre nueva imagen>
docker image import my-alpine.tar my-alpine-imported
#------------------------------------------------------------- #2. Exportar el contenedor como imagen directamente (commit) #------------------------------------------------------------- # <nombre-contenedor> <nombre nueva imagen> docker container commit my-alpine my-alpine-committed
#----------------------------------------------------------------------- #3. Ahora solo falta crear los contenedores a partir de las imagenes #----------------------------------------------------------------------- #3.1 Listamos imagenes docker images

6. Proceso completo de asignación de  volumen al contenedor docker existente de Oracle

Vamos a :
  1. Crear una imagen del contenedor de la BD Oracle con un commit
  2. Crear un volumen
  3. Crear un contenedor a partir de la imagen montando el volumen. Hay que advertir que al crear el contenedor SI hace falta dar puertos ni contraseñas.
<
#-------------------------------------------------------------
#1. Exportar el contenedor como imagen directamente (commit)
#    y listamos las imagenes para comprobar
#-------------------------------------------------------------
#                       <nombre-contenedor>  <nombre nueva imagen>
docker container commit ximo-oracle-db       oracle-db-image-committed

docker images

#REPOSITORY                                       TAG             IMAGE ID       CREATED         SIZE
#oracle-db-image-committed                        latest          036d3ff6a2cf   9 minutes ago   16.5GB
#container-registry.oracle.com/database/express   latest          8da8cedb7fbf   6 weeks ago     11.4GB


#-----------------------------------------------
#3. Creamos un volumen y listamos para combrobar
#-----------------------------------------------
docker volume create ximo-oracle-volume

docker volume ls

#DRIVER    VOLUME NAME
#local     ximo-oracle-volume


#------------------------------------------------------------
#4. Creamos un nuevo contenedor a partir de la imagen y 
#   le montamos el volumen
#   OJO: SI hace falta dar pawssword y puertos 
#------------------------------------------------------------
#                             <nombre-contenedor>      <mapeo puerto1> <mapeo puerto2>                                         <volumen a montar>        <punto montaje>  <nombre imagen>
docker container create --name ximo-oracle-db-new -it -p 1111:1521 -p 2222:5500 -e ORACLE_PWD=myPassword --mount source=ximo-oracle-volume,target=/opt/ximo-volume oracle-db-image-committed #-------------------------------- 5. Arrancamos el contenedor #--------------------------------
#                         <nombre-contenedor>
docker container start -i ximo-oracle-db-new


Y vemos que podemos conectar mediante DBeaver.







lunes, 18 de septiembre de 2023

Oracle 6 - Nuevo enfoque (3).Entender Oracle Express con Docker. Copias de seguridad de un esquema de Oracle. Crear y restaurar

0. Introducción

Ahora que tenemos instalado Oracle con docker, vamos a ver si somos capaces de ver el sistema de ficheros  y entender como funciona el sistema. A continuación, con sqlplus intentaremos hacer la copia de seguridad, y finalmente copiaremos los ficheros de copia de seguridad desde docker a una ubicación fuera de docker.

Créditos:

https://www.ajpdsoft.com/modules.php?name=News&file=print&sid=560#copiaseguridadlogicaoracle

https://www.baeldung.com/ops/docker-container-filesystem

http://www.rebellionrider.com/data-pump-expdp-how-to-export-schema-oracle/

https://arvindasdba.blogspot.com/2016/05/restore-database-schema-from-full-expdp.html

1. Entender Docker

1.0. Ver los contenedores docker en marcha (NO los contenedores internos  de Oracle)

docker ps

Y nos sale: (Tomar nota del ID del contenedor y del nombre que está al final)

CONTAINER ID   IMAGE                                            COMMAND                  CREATED      STATUS                PORTS                                                                                  NAMES
34a5f979d3de   container-registry.oracle.com/database/express   "/bin/bash -c $ORACL…"   4 days ago   Up 4 days (healthy)   0.0.0.0:1111->1521/tcp, :::1111->1521/tcp, 0.0.0.0:2222->5500/tcp, :::2222->5500/tcp   ximo-oracle-db

1.1 Copiar ficheros entre un contenedor docker y el servidor físico

Para copiar ficheros desde el servidor físico a un contenedor docker:

docker cp <src-path> <container-name>:<dest-path>    por ejemplo:
docker cp /home/ximo/myFile.txt ximo-oracle-db:/home/oracle

Y para copiar desde el contenedor al servidor

docker cp <container>:<src-path> <local-dest-path>    por ejemplo:
docker cp ximo-oracle-db:/home/oracle/myFile.txt /home/ximo


1.2. Abrir una consola de comandos en dicho contenedor y crear una carpeta donde guardar las copias de seguridad

docker exec -it 34a5f979d3de /bin/bash

Y nos sale una consola de comandos

bash-4.2$

Si ejecutamos pwd para ver donde estmos nos sale /home/oracle  

Podemos crear la carpeta /home/oracle/BACKUP_XIMO para descargar las copias de seguridad ahí (es evidente que estamos en el servidor) y por si acaso le damos permiso a 777

mkdir BACKUP_XIMO

chmod 777 BACKUP_XIMO

2. Introducción a las copias de seguridad en Oracle

2.1. Entrar en sqlplus como sys y mapear el directorio físico a uno de la BD

Tenemos 3 opciones para entrar en sqlplus como sysdba.

La primera opción es desde la consola de comandos ejecutar:

sqlplus / as sysdba

Y la segunda es salirse de la consola de comandos con el comando 

exit

y entramos en sqlplus con docker  

docker exec -it ximo-oracle-db  sqlplus / as sysdba

La tercera opción es hace click derecho sobre la BD XEPDB1 de la pestaña Database Navigator de DBeaver ->SQL Editor -> New SQL Script

Una vez dentro de sqlplus nos vamos al contenedor XEPDB1, (no hace falta en DBeaver pues ya estamos en dicho contenedor)

OJO: Seleccionar el contenedor XEPDB1 interno de Oracle (solo en sqlplus)  en 1ª y 2ª opciones):

SQL> ALTER SESSION SET CONTAINER = XEPDB1;

Ahora mapeamos el directorio creado, y le asignamos el nombre exp_schema_ximo. No nos olvidemos de colocar un ";" al final de las sentencias SQL sinó NO SE EJECUTARÁN !!

SQL> CREATE DIRECTORY exp_schema_ximo as '/home/oracle/BACKUP_XIMO';

y nos dice "Directory created"

Si queremos listar todos directorios, o solo el que nos interesa:

SQL> SELECT * FROM ALL_DIRECTORIES;

SQL> SELECT * FROM ALL_DIRECTORIES WHERE DIRECTORY_PATH LIKE '%XIMO%';

 Y nos devuelve:


OWNER|DIRECTORY_NAME |DIRECTORY_PATH          |ORIGIN_CON_ID|
-----+---------------+------------------------+-------------+
SYS  |EXP_SCHEMA_XIMO|/home/oracle/BACKUP_XIMO|            3|

2.2. Otorgar permisios de lectura y escritura del directorio mapeado al usuario

Sabemos que cuando se crea un SCHEMA también se crea un USUARIO con el mismo nombre asociado a dicho SCHEMA. Ahora hay que asignar permisos a dicho usuario al directorio.

SQL> GRANT read, write ON DIRECTORY EXP_SCHEMA_XIMO TO SCHM01_XIMO;

2.3. Otorgar el rol DATAPUMP_EXP_FULL_DATABASE al usuario

El rol DATAPUMP_EXP_FULL_DATABASE permite:

  1. Especificar un esquema cualquiera que no sea el tuyo o una lista de esquemas
  2. Exportar objetos de información adicional de cada esquema especificado, tales como contraseñs etc de manera que se pueden volver a crear los esquemas en la importación a otra BD.
Por tanto los usuarios que no tengan ese rol solo pueden exportar su esquema.

Para asignar dicho rol :

SQL> GRANT DATAPUMP_EXP_FULL_DATABASE TO SCHM01_XIMO;

2.4. BACKUP: Ejecutar el comando expdp (fuera de sqlplus) en una shell.


expdp es una sentnecia que se ejecuta en una ventana de comandos y no dentro sqlplus, por taqnto si estamos dentro de sqlplus hay que salir. Si estamos en docker ejecutamos

SQL> exit 

Si después de ejecutar este comando todavía estamos en docker entonces perfecto, pero si se hemos salido de docker hay que ejecutar el contenedor docker de  oracle en modo shell

docker exec -it 34a5f979d3de /bin/bash

siendo 34a5f979d3de el id del contenedor tal como vimos en el primer punto

Y nos sale una consola de comandos

bash-4.2$


Ahora ejecutamos el comando


expdp SCHM01_XIMO/myPassword@XEPDB1  DIRECTORY = EXP_SCHEMA_XIMO DUMPFILE =exp_schm_ximo.dmp LOGFILE=ximo_lg.log SCHEMAS = SCHM01_XIMO

Siendo
  • SCHM01_XIMO/myPassword@XEPDB1 : nombre esquema/contraseña esquema@contenedor interno de la base de datos
  • DIRECTORY = EXP_SCHEMA_XIMO : el directorio creado con CREATE DIRECTORY de sqlplus
  • DUMPFILE y LOGFILE son los nombres de los ficheros a generar y pueden ser cualquiera que queramos y a ser posible sin cambiar las extensiones
  • SCHEMAS = SCHM01_XIMO es el esquema a guardar. Si se quisiese guardar mas esquemas, se seararían por comas (ejemplo SCHEMAS= SCHM01_XIMO, miesquema1, otro_esquema )
y tras ejecutar el comando sale:

Export: Release 21.0.0.0.0 - Production on Tue Sep 19 12:50:50 2023
Version 21.3.0.0.0

Copyright (c) 1982, 2021, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Starting "SCHM01_XIMO"."SYS_EXPORT_SCHEMA_01":  SCHM01_XIMO/********@XEPDB1 DIRECTORY=EXP_SCHEMA_XIMO DUMPFILE=exp_schm_ximo.dmp LOGFILE=ximo_lg.log SCHEMAS=SCHM01_XIMO 
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/ROLE_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/IDENTITY_COLUMN
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
. . exported "SCHM01_XIMO"."INVENTORIES"                 21.41 KB    1112 rows
. . exported "SCHM01_XIMO"."REGIONS"                     5.562 KB       4 rows
. . exported "SCHM01_XIMO"."CONTACTS"                    28.72 KB     319 rows
. . exported "SCHM01_XIMO"."COUNTRIES"                   6.382 KB      25 rows
. . exported "SCHM01_XIMO"."CUSTOMERS"                   32.28 KB     319 rows
. . exported "SCHM01_XIMO"."EMPLOYEES"                   17.35 KB     107 rows
. . exported "SCHM01_XIMO"."LOCATIONS"                   8.390 KB      23 rows
. . exported "SCHM01_XIMO"."ORDERS"                      9.781 KB     105 rows
. . exported "SCHM01_XIMO"."ORDER_ITEMS"                 21.21 KB     665 rows
. . exported "SCHM01_XIMO"."PRODUCTS"                    33.68 KB     288 rows
. . exported "SCHM01_XIMO"."PRODUCT_CATEGORIES"          5.585 KB       5 rows
. . exported "SCHM01_XIMO"."WAREHOUSES"                  6.171 KB       9 rows
Master table "SCHM01_XIMO"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SCHM01_XIMO.SYS_EXPORT_SCHEMA_01 is:
  /home/oracle/BACKUP_XIMO/exp_schm_ximo.dmp
Job "SCHM01_XIMO"."SYS_EXPORT_SCHEMA_01" successfully completed at Tue Sep 19 12:51:48 2023 elapsed 0 00:00:56

Y si vamos al directorio /home/oracle/BACKUP_XIMO y hacemos "ls -al" sale

total 956
drwxrwxrwx 2 oracle oinstall   4096 Sep 19 12:50 .
drwxr-xr-x 1 oracle oinstall   4096 Sep 19 06:04 ..
-rw-r----- 1 oracle oinstall 962560 Sep 19 12:51 exp_schm_ximo.dmp
-rw-r--r-- 1 oracle oinstall   2603 Sep 19 12:51 ximo_lg.log

2.5. RESTORE Ejecutar el comando impdp (fuera de sqlplus) en una shell.


impdp es una sentnecia que se ejecuta en una ventana de comandos y no dentro sqlplus, por taqnto si estamos dentro de sqlplus hay que salir. 

Si queremos restaurar el  backup anterior en un nuevo SCHEMA por ejemplo SCHM01_XIMO_COP añadiremos  REMAP_SCHEMA=SCHM01_XIMO:SCHM01_XIMO_COP

La senterncia ejecutar es:

impdp SCHM01_XIMO/myPassword@XEPDB1 DIRECTORY = EXP_SCHEMA_XIMO DUMPFILE =exp_schm_ximo.dmp LOGFILE=ximo_lg.log SCHEMAS = SCHM01_XIMO REMAP_SCHEMA=SCHM01_XIMO:SCHM01_XIMO_COP


Y si observamos, se ha creado el nuevo esquema.






Oracle 5 - Nuevo enfoque (2).Utilizar DBeaver para manejar Oracle Express

 0. Introducción

En Oracle tenemos estos conceptos:

SCHEMA: Un conjunto de tablas y otros elementos (funciones, procedimientos almacenados, tipos indices, vistas...)que tienen ciertas caracteristicas comunes. Por ejemplo podemos tener un esquema pora territorio,  para personas, para contabilidad etc. 

TABLESPACE: Sistema físico donde almacenar las tablas, el concepto es similar al de un directorio que puede guardar ficheros. Fijare que las tablas de un mismos SCHEMA pueden estar en distintos TABLESPACES.

Para crear una tabla, DBeaver nos ofrece la opción de seleccionar un SCHEMA y un TABLESPACE. Por omisión si no se los indicamos los crea en un esquema

IMPORTANTE: Tener cuidado con el contenedor (Base de datos) que estamos usando, como ya se vió:

Para listar los contenedores (siempre que no hayamos entrado en algún contenedor específico) hacemos

SQL> select con_id, name from v$containers;

Y para utilizar un contenedor debemos hacer 

SQL> ALTER SESSION SET CONTAINER = XEPDB1;


1. Creación de un SCHEMA.

Hacemos click derecho sobre Schemas y seleccionamos Create new Schema. Le damos nombre y contraseña




También se hubiera podido hacer ejecutando un script dentro de DBeaver (este escript dentro de DBeaver, se ejecuta en el contenedor XEPDB1).

CREATE USER SCHM01_XIMO IDENTIFIED BY myPassword;

OJO: Oracle considera un esquema como un usuario. 

Según el tutorial de Oracle hay que darle permisos y todo como un usuario.

GRANT CONNECT, RESOURCE, DBA TO SCHM01_XIMO;

2. Creación de un TABLESPACE.

Parece ser que en DBeaver not enomos la opción de crear TABLESPACES. Para ello hacemos click derecho sobre la conexion (en mi caso XEPDB1), Seleccionamos SQL Editor y New SQL Script  

Y ejecutamos el script


CREATE TABLESPACE TABSPC01_XIMO DATAFILE '/opt/oracle/oradata/XE/XEPDB1/TABSPC01_XIMO.dbf' size 50M;

y refrescando DBeaver vemos dicho TABLESPACE


3. Creación de una TABLA. 

Vamos Schemas - SCHM01_XIMO - Tables y con click derecho seleccionamos Create New Table   

y nos pide el nombre de la tabla ,TABLESACE y mas información.


Podemos utilizar un script SQL y crear una tabla. Para ello, este escipt sirva de ejemplo que se ha tomado de la base de datos ejemplo del tutorial de Oracle que se ha modificado para añadir el SCHEMA y el TABLESPACE

CREATE TABLE SCHM01_XIMO.REGIONS 
     (
        REGION_ID       NUMBER          GENERATED BY DEFAULT AS IDENTITY START WITH 5 PRIMARY KEY, 
        REGION_NAME     VARCHAR2(50)    NOT NULL --, 
     )
     TABLESPACE TABSPC01_XIMO;

4. Modificar script de creación de tablas

Vamos a modificar el script de creación de tablas del tutorial de Oracle, para ello tenemos que añadir el SCHEMA y el TABLESPACE, basta con buscar y sustituir 
  1. "TABLE " por "TABLE SCHM01_XIMO." para añadir el SCHEMA y
  2. ");" por  ") TABLESPACE TABSPC01_XIMO;"
y quedaría:

--------------------------------------------------------------------------------------
-- Name	       : OT (Oracle Tutorial) Sample Database
-- Link	       : http://www.oracletutorial.com/oracle-sample-database/
-- Version     : 1.0
-- Last Updated: July-28-2017
-- Copyright   : Copyright © 2017 by www.oracletutorial.com. All Rights Reserved.
-- Notice      : Use this sample database for the educational purpose only.
--               Credit the site oracletutorial.com explitly in your materials that
--               use this sample database.
--------------------------------------------------------------------------------------


---------------------------------------------------------------------------
-- execute the following statements to create tables
---------------------------------------------------------------------------
-- regions
CREATE TABLE SCHM01_XIMO.regions
  (
    region_id NUMBER GENERATED BY DEFAULT AS IDENTITY
    START WITH 5 PRIMARY KEY,
    region_name VARCHAR2( 50 ) NOT NULL
  ) 
  TABLESPACE TABSPC01_XIMO;
-- countries table
CREATE TABLE SCHM01_XIMO.countries
  (
    country_id   CHAR( 2 ) PRIMARY KEY  ,
    country_name VARCHAR2( 40 ) NOT NULL,
    region_id    NUMBER                 , -- fk
    CONSTRAINT fk_countries_regions FOREIGN KEY( region_id )
      REFERENCES  SCHM01_XIMO.regions( region_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;

-- location
CREATE TABLE SCHM01_XIMO.locations
  (
    location_id NUMBER GENERATED BY DEFAULT AS IDENTITY START WITH 24 
                PRIMARY KEY       ,
    address     VARCHAR2( 255 ) NOT NULL,
    postal_code VARCHAR2( 20 )          ,
    city        VARCHAR2( 50 )          ,
    state       VARCHAR2( 50 )          ,
    country_id  CHAR( 2 )               , -- fk
    CONSTRAINT fk_locations_countries 
      FOREIGN KEY( country_id )
      REFERENCES  SCHM01_XIMO.countries( country_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- warehouses
CREATE TABLE SCHM01_XIMO.warehouses
  (
    warehouse_id NUMBER 
                 GENERATED BY DEFAULT AS IDENTITY START WITH 10 
                 PRIMARY KEY,
    warehouse_name VARCHAR( 255 ) ,
    location_id    NUMBER( 12, 0 ), -- fk
    CONSTRAINT fk_warehouses_locations 
      FOREIGN KEY( location_id )
      REFERENCES  SCHM01_XIMO.locations( location_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- employees
CREATE TABLE SCHM01_XIMO.employees
  (
    employee_id NUMBER 
                GENERATED BY DEFAULT AS IDENTITY START WITH 108 
                PRIMARY KEY,
    first_name VARCHAR( 255 ) NOT NULL,
    last_name  VARCHAR( 255 ) NOT NULL,
    email      VARCHAR( 255 ) NOT NULL,
    phone      VARCHAR( 50 ) NOT NULL ,
    hire_date  DATE NOT NULL          ,
    manager_id NUMBER( 12, 0 )        , -- fk
    job_title  VARCHAR( 255 ) NOT NULL,
    CONSTRAINT fk_employees_manager 
        FOREIGN KEY( manager_id )
        REFERENCES  SCHM01_XIMO.employees( employee_id )
        ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- product category
CREATE TABLE SCHM01_XIMO.product_categories
  (
    category_id NUMBER 
                GENERATED BY DEFAULT AS IDENTITY START WITH 6 
                PRIMARY KEY,
    category_name VARCHAR2( 255 ) NOT NULL
  ) 
  TABLESPACE TABSPC01_XIMO;

-- products table
CREATE TABLE SCHM01_XIMO.products
  (
    product_id NUMBER 
               GENERATED BY DEFAULT AS IDENTITY START WITH 289 
               PRIMARY KEY,
    product_name  VARCHAR2( 255 ) NOT NULL,
    description   VARCHAR2( 2000 )        ,
    standard_cost NUMBER( 9, 2 )          ,
    list_price    NUMBER( 9, 2 )          ,
    category_id   NUMBER NOT NULL         ,
    CONSTRAINT fk_products_categories 
      FOREIGN KEY( category_id )
      REFERENCES  SCHM01_XIMO.product_categories( category_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- customers
CREATE TABLE SCHM01_XIMO.customers
  (
    customer_id NUMBER 
                GENERATED BY DEFAULT AS IDENTITY START WITH 320 
                PRIMARY KEY,
    name         VARCHAR2( 255 ) NOT NULL,
    address      VARCHAR2( 255 )         ,
    website      VARCHAR2( 255 )         ,
    credit_limit NUMBER( 8, 2 )
  ) 
  TABLESPACE TABSPC01_XIMO;
-- contacts
CREATE TABLE SCHM01_XIMO.contacts
  (
    contact_id NUMBER 
               GENERATED BY DEFAULT AS IDENTITY START WITH 320 
               PRIMARY KEY,
    first_name  VARCHAR2( 255 ) NOT NULL,
    last_name   VARCHAR2( 255 ) NOT NULL,
    email       VARCHAR2( 255 ) NOT NULL,
    phone       VARCHAR2( 20 )          ,
    customer_id NUMBER                  ,
    CONSTRAINT fk_contacts_customers 
      FOREIGN KEY( customer_id )
      REFERENCES  SCHM01_XIMO.customers( customer_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- orders table
CREATE TABLE SCHM01_XIMO.orders
  (
    order_id NUMBER 
             GENERATED BY DEFAULT AS IDENTITY START WITH 106 
             PRIMARY KEY,
    customer_id NUMBER( 6, 0 ) NOT NULL, -- fk
    status      VARCHAR( 20 ) NOT NULL ,
    salesman_id NUMBER( 6, 0 )         , -- fk
    order_date  DATE NOT NULL          ,
    CONSTRAINT fk_orders_customers 
      FOREIGN KEY( customer_id )
      REFERENCES  SCHM01_XIMO.customers( customer_id )
      ON DELETE CASCADE,
    CONSTRAINT fk_orders_employees 
      FOREIGN KEY( salesman_id )
      REFERENCES  SCHM01_XIMO.employees( employee_id ) 
      ON DELETE SET NULL
  ) 
  TABLESPACE TABSPC01_XIMO;
-- order items
CREATE TABLE SCHM01_XIMO.order_items
  (
    order_id   NUMBER( 12, 0 )                                , -- fk
    item_id    NUMBER( 12, 0 )                                ,
    product_id NUMBER( 12, 0 ) NOT NULL                       , -- fk
    quantity   NUMBER( 8, 2 ) NOT NULL                        ,
    unit_price NUMBER( 8, 2 ) NOT NULL                        ,
    CONSTRAINT pk_order_items 
      PRIMARY KEY( order_id, item_id ),
    CONSTRAINT fk_order_items_products 
      FOREIGN KEY( product_id )
      REFERENCES  SCHM01_XIMO.products( product_id ) 
      ON DELETE CASCADE,
    CONSTRAINT fk_order_items_orders 
      FOREIGN KEY( order_id )
      REFERENCES  SCHM01_XIMO.orders( order_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;
-- inventories
CREATE TABLE SCHM01_XIMO.inventories
  (
    product_id   NUMBER( 12, 0 )        , -- fk
    warehouse_id NUMBER( 12, 0 )        , -- fk
    quantity     NUMBER( 8, 0 ) NOT NULL,
    CONSTRAINT pk_inventories 
      PRIMARY KEY( product_id, warehouse_id ),
    CONSTRAINT fk_inventories_products 
      FOREIGN KEY( product_id )
      REFERENCES  SCHM01_XIMO.products( product_id ) 
      ON DELETE CASCADE,
    CONSTRAINT fk_inventories_warehouses 
      FOREIGN KEY( warehouse_id )
      REFERENCES  SCHM01_XIMO.warehouses( warehouse_id ) 
      ON DELETE CASCADE
  ) 
  TABLESPACE TABSPC01_XIMO;

Y se a da a ejecutar dicho escript y si acaso fallara, se puede seleccionar el código de creación de una tabla y crearla una por una.

Para ejecutar el script se seleccionan las sentencias a ejecturar y se le da al símbolo




Y al final tedríamos:


5. Modificar el script de carga de datos

Procediendo igual que antes, sobre elscript ot_data.sql cambiando  :
  1. "TABLE " por "TABLE SCHM01_XIMO." para añadir el SCHEMA,
  2. "Insert into " por "Insert into SCHM01_XIMO."
  3. "REM INSERTING" por "--REM INSERTING." (Comentando)
  4. "SET DEFINE" por "--SET DEFINE(Comentando)
Ahora se tienen problemas para cargar la fecha y para ello da un error ORA1843 en la sentencia TO_DATE que dice que el més esta mal. Según stackoverflow podemos ejecutar una consulta como esta para ver como se lamna los meses del año en nuestro idioma

SELECT TO_CHAR(TO_DATE(1, 'MM'), 'MON'), 
TO_CHAR(TO_DATE(2, 'MM'), 'MON'),
TO_CHAR(TO_DATE(3, 'MM'), 'MON'),
TO_CHAR(TO_DATE(4, 'MM'), 'MON'),
TO_CHAR(TO_DATE(5, 'MM'), 'MON'),
TO_CHAR(TO_DATE(6, 'MM'), 'MON'),
TO_CHAR(TO_DATE(7, 'MM'), 'MON'),
TO_CHAR(TO_DATE(8, 'MM'), 'MON'),
TO_CHAR(TO_DATE(9, 'MM'), 'MON'),
TO_CHAR(TO_DATE(10, 'MM'), 'MON'),
TO_CHAR(TO_DATE(11, 'MM'), 'MON'),
TO_CHAR(TO_DATE(12, 'MM'), 'MON')
FROM DUAL;

Y se obtiene en mi caso:

GEN. FEBR. MARÇ ABR. ABR. MAIG JUNY JUL. AG. SET. OCT. NOV. DES.

Ahora debemos cambiar los meses en ingles (JAN FEB MAR APR JUN JUL AUG OCT NOV DEC) por los anteriores y ejecutar, y en teopría se deberían cargar

Analogamente se ejecutarían las sentenciasdel script  de carga de datos.










jueves, 14 de septiembre de 2023

Oracle 4 - Nuevo enfoque (1). Instalar Oracle Express en Docker.Ojo al seleccionar la BD de Oracle!

 0. Introducción

Ha pasado mucho tiempo desde que se hicieron las entradas previas de Oracle.

Pero ahora vamos a iniciar de nuevo el tema pero con el contenedor docker.

Suponemos que tenemos docker perfectamente instalado.



1. Instalación de Oracle Database XE Release 21c (21.3.0.0) Docker Image

1. Descargar la imagen

docker pull container-registry.oracle.com/database/express:latest

2. Listar las imágenes para ver si se ha descargado

docker images

y aparecen

REPOSITORY                                       TAG             IMAGE ID       CREATED         SIZE
container-registry.oracle.com/database/express   latest          8da8cedb7fbf   6 weeks ago     11.4GB
hello-world                                      latest          9c7a54a9a43c   4 months ago    13.3kB
ximo-app                                         latest          597718d0ba1e   10 months ago   537MB
tomcat                                           jdk17-temurin   6dd589e60602   10 months ago   474MB

la que nos interesa es la primera.

3. Arrancar la imagen

docker run --name ximo-oracle-db -p 1111:1521 -p 2222:5500 -e ORACLE_PWD=myPassword container-registry.oracle.com/database/express

siendo ximo-oracle-db el nombre que le hemos dado al contenedor y                                       container-registry.oracle.com/database/express el nombre del repositorio que nos interesaba. También hemos reasignado los puertos 1521 y 5500 a 1111 y 2222 respectivamente y lr hemos dado de contraseña myPassword

4. Conectarse con el servidor

https://localhost:2222/em/

y nos sale esta pantalla





Hay que tener en cuenta que para listar los contenedores (de la BD y no de docker!!) se hace

docker exec -it ximo-oracle-db  sqlplus / as sysdba

y le damos a la consulta

SQL> select con_id, name from v$containers;

que nos devuelve 3 contenedores y debemos elegir el primero

CDB$ROOT

2 PDB$SEED

3 XEPDB1

OJO: Ahora hemos seleccionado CDB$ROOT pero al conectarnos con DBEaver lo hemos hecho con el contenedor XEPDB1 por tanto, si queremos estar en sintonia con DBeaver, tendríamos que seleccionar XEPDB1     

Y al aceptar las credenciales sale esta pantalla



2. Conectase con DBEAVER

2. Entrar en DBeaver y en el menu Database Seleccionar Driver Manager 


Copiamos el driver de Oracle


Cambiamos el puerto a 1111 y hay que tener en cuenta que el default DB es XEPDB1 en vez de ORCL aunque aquí no hace falta cambiarla


Vamos a la pestaña de libraries y le damos a Add File y buscamos el driver JDBC descargado


Y cuando le damos al boton  Find Class nos abre una pantalla de descarga que eleccionamos el último elemento


Ahora en la pantalla anterior indicamos Crivers class oracle.jdbc.OraclweDriver y le dmos a OK y cerramos

Ahora en el Menu Database -> New Database Connection buscamos una BD SQL y elegimos Oracle Copy y le damos al boton Next


Ahora le indicamos los parametros marcados y le damos el pasword que le hemos dado "myPassword")


Debeis tener los parametros indicados en la pantalla.

Importante cambiar la BD a XEPDB1  !!! Y el usuario system !!! y el puerto 1111 (que por omisión es el 1511


Le damos a test Connection y nos conecta



Y vemos que podemos consultar muchas cosas en DBeaver



3. Cuidado con la BD (contenedor) elegida.

Sabemos que Oracle fusiona USER y SCHEMA, pero lo que en otras bases de datos como Postgres o MySQL se conoce como base de datos, en Oracle los llama contenedores

Hermos visto que para listar los contenedores hacemos

SQL> SELECT con_id, name from v$containers;

Y devuelve CDB$ROOT, PDB$SEED y XEPDB1.

OJO: Mientras 

Y para utilizar un contenedor debemos hacer 

SQL> ALTER SESSION SET CONTAINER = XEPDB1;

Pero ahora si lisamos los contenedores con el comado "SELECT * FROM V$CONTAINERS" , solo nos muestra el contenedor XEPDB1 !!!!

Y para ver la BD actual

SQL> SELECT NAME FROM v$database; 

OJO: Si ejecutamos el comando para ver la BD actual en cualquier conenedor nos devuelve el mismo valor "XE", por tanto a priori este comando no 

jueves, 20 de abril de 2023

Ubuntu. Buscar ficheros con contenido de modo recursivo

 Primeramente nos situamos en el direcotrio que queramos buscar

Ejecutamos este script

grep -inr --include \*.java "IRPF" ./ /home/ximo/IRPF_files_java.txt

donde

\*.java indica la extensión de los ficheros, en este caso son los ficheros con extensión ".java"

"IRPF" es el texto a buscar dentro de los ficheros

./ es la ruta donde buscar. Indica la carpta actual

> /home/ximo/IRPF_files_java.txt es el fichero donde se guardaran los resultados.