Oracle Application Express (APEX) has been hosted by Oracle Academy and used for many years to facilitate the delivery of curriculum for database design and programming, SQL, PL/SQL and even APEX. To facilitate their business requirements, they had custom extensions written (in part, by our team) into the core APEX product. But this type of solution becomes difficult to maintain, because every release of APEX requires migration and rewrite of these custom extensions.
A number of months ago, I met with the Oracle Academy team to try and encourage them to move the service creation of APEX workspaces into their own custom interfaces. I told them that everything is provided to easily and programmatically create APEX workspaces, create database users (schemas), create administrators and developers within each workspace, and even pre-load APEX applications and custom database objects in each workspace, at the time of service creation.
Naturally, they asked for an example script to accomplish all of these tasks, which I authored and shared with them. Because this type of logic is very relevant for many other purposes, e.g., testing, continuous integration, DevOps, I wish to share these same annotated scripts here. If you are someone who has been using APEX for 10 years, you won't learn anything new here. But for those just getting started with APEX, I hope you find it fruitful.
Starting with an empty Oracle database, the requirements are to develop a single script which will:
- Create a tablespace (storage) for each workspace
- Create and associate multiple database users (schemas) with each workspace
- Create an APEX workspace
- Create an administrator and developer account in each workspace, restricting the access of each developer to only one of the schemas mapped to the workspace.
- Create custom database objects in each schema
And here we go...
set define '^' verify on
set concat on
set concat .
Rem
Rem Title: Demo_of_Provisioning.sql
Rem
Rem Description: This script will demonstrate use of all of the APIs and SQL statements necessary
Rem to create tablespaces, data files, database users, and APEX workspaces. From this
Rem example, it is assumed that the Academy team will be able to develop their own custom
Rem provisioning process and no longer rely upon custom extensions to the
Rem Oracle Application Express software.
Rem
Rem Notes: It is assumed that this script is run as user SYSTEM.
Rem
Rem
Rem MODIFIED (MM/DD/YYYY)
Rem jkallman 08/19/2018 - Created
column foo1 new_val LOG1
select 'Demo_of_Provisioning_'||to_char(sysdate,'YYYY-MM-DD_HH24-MI-SS')||'.log' as foo1 from sys.dual;
spool ^LOG1
timing start "Create demonstration tablespaces, schemas and workspaces"
--
-- Predefine the path used for tablespace datafile creation. If you're using Oracle Managed Files
-- or grid infrastructure, then this isn't necessary and you'll remove the 'datafile' portion of
-- the CREATE TABLESPACE statements
--
define DATAFILE_PATH='/u01/app/oracle/oradata/'
--
-- Step 1: Create the Tablespaces
--
-- Since Oracle Academy will want to group multiple database users/workspaces into a single tablespace, we'll need to
-- first create the tablespaces, and then the database users in step 2
--
create tablespace OACADEMY_DATA1 datafile '^DATAFILE_PATH.iacademy_01.dbf'
size 50M autoextend on next 50M maxsize 2G extent management local
autoallocate segment space management auto;
create tablespace OACADEMY_DATA2 datafile '^DATAFILE_PATH.iacademy_02.dbf'
size 50M autoextend on next 50M maxsize 2G extent management local
autoallocate segment space management auto;
--
-- Step 2: Create the Database Users (Schemas)
--
-- It's up to you how you wish to group database users/schemas into different tablespaces.
-- You can do it by total number or free space or ratio of users to tablespaces. It's all up to you.
--
begin
-- DB users in DATA1 tablespace
execute immediate 'create user OACADEMY_DB10 identified by "' || sys.dbms_random.string('X',30) ||
'" default tablespace OACADEMY_DATA1 quota unlimited on OACADEMY_DATA1 temporary tablespace TEMP account lock password expire';
execute immediate 'create user OACADEMY_DB11 identified by "' || sys.dbms_random.string('X',30) ||
'" default tablespace OACADEMY_DATA1 quota unlimited on OACADEMY_DATA1 temporary tablespace TEMP account lock password expire';
-- DB users in DATA2 tablespace
execute immediate 'create user OACADEMY_DB20 identified by "' || sys.dbms_random.string('X',30) ||
'" default tablespace OACADEMY_DATA2 quota unlimited on OACADEMY_DATA2 temporary tablespace TEMP account lock password expire';
execute immediate 'create user OACADEMY_DB21 identified by "' || sys.dbms_random.string('X',30) ||
'" default tablespace OACADEMY_DATA2 quota unlimited on OACADEMY_DATA2 temporary tablespace TEMP account lock password expire';
end;
/
--
-- Step 3: Create the APEX Workspaces
--
-- Create the APEX workspaces and associate a default schema with each
--
begin
apex_instance_admin.add_workspace(
p_workspace_id => null,
p_workspace => 'OACADEMY1',
p_primary_schema => 'OACADEMY_DB10');
end;
/
begin
apex_instance_admin.add_workspace(
p_workspace_id => null,
p_workspace => 'OACADEMY2',
p_primary_schema => 'OACADEMY_DB20');
end;
/
--
-- Step 4: Add additional schemas to the existing workspaces
--
--
begin
apex_instance_admin.add_schema(
p_workspace => 'OACADEMY1',
p_schema => 'OACADEMY_DB11');
end;
/
begin
apex_instance_admin.add_schema(
p_workspace => 'OACADEMY2',
p_schema => 'OACADEMY_DB21');
end;
/
--
-- Show a quick summary of the workspaces and schemas
--
column workspace_name format a50
column schema format a40
select workspace_name, schema from apex_workspace_schemas;
--
-- Step 5: Create an administrator account and a developer account in each worskpace
--
--
begin
-- We must set the APEX workspace security group ID in our session before we can call create_user
apex_util.set_security_group_id( apex_util.find_security_group_id( p_workspace => 'OACADEMY1'));
apex_util.create_user(
p_user_name => 'BOB',
p_email_address => 'bob@bob.com',
p_default_schema => 'OACADEMY_DB10',
p_allow_access_to_schemas => 'OACADEMY_DB10',
p_web_password => 'change_me',
p_developer_privs => 'ADMIN:CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL' ); -- workspace administrator
apex_util.create_user(
p_user_name => 'JUNE',
p_email_address => 'june@june.com',
p_default_schema => 'OACADEMY_DB11',
p_allow_access_to_schemas => 'OACADEMY_DB11',
p_web_password => 'change_me',
p_developer_privs => 'CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL' ); -- developer
commit;
end;
/
begin
-- We must set the APEX workspace security group ID in our session before we can call create_user
apex_util.set_security_group_id( apex_util.find_security_group_id( p_workspace => 'OACADEMY2'));
apex_util.create_user(
p_user_name => 'ALICE',
p_email_address => 'alice@alice.com',
p_default_schema => 'OACADEMY_DB20',
p_allow_access_to_schemas => 'OACADEMY_DB20',
p_web_password => 'change_me',
p_developer_privs => 'ADMIN:CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL' ); -- workspace administrator
apex_util.create_user(
p_user_name => 'AUGUST',
p_email_address => 'august@august.com',
p_default_schema => 'OACADEMY_DB21',
p_allow_access_to_schemas => 'OACADEMY_DB21',
p_web_password => 'change_me',
p_developer_privs => 'CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL' ); -- developer
commit;
end;
/
--
-- Show a quick summary of the APEX users
--
column workspace_name format a30
column user_name format a20
column email format a25
column is_admin format a10
column is_application_developer format a10
select workspace_name, user_name, email, is_admin, is_application_developer from apex_workspace_apex_users order by 1,2;
--
-- Install custom database objects in each schema by simply running one more SQL scripts. Note that the
-- script below is something that you author and maintain. It will do all DML and DDL you have in it,
-- and we simply iterate through the schemas and run the script each time.
--
alter session set current_schema = OACADEMY_DB10;
@custom.sql
alter session set current_schema = OACADEMY_DB11;
@custom.sql
alter session set current_schema = OACADEMY_DB20;
@custom.sql
alter session set current_schema = OACADEMY_DB21;
@custom.sql
timing stop
spool off
And to complete the lifecycle, I also authored a simple SQL script which will cleanup everything created above - removing the APEX workspaces, database users and tablespaces.
set define '^' verify on
set concat on
set concat .
Rem
Rem Title: Demo_of_Cleanup.sql
Rem
Rem Description: This script will cleanup all objects created by script Demo_of_Provisioning.sql
Rem
Rem Notes: It is assumed that this script is run as user SYSTEM.
Rem
Rem **** THIS SCRIPT IS DESTRUCTIVE **** - It will drop tablespaces, data files, workspaces, schemas, etc.
Rem
Rem
Rem MODIFIED (MM/DD/YYYY)
Rem jkallman 08/19/2018 - Created
column foo1 new_val LOG1
select 'Demo_of_Cleanup_'||to_char(sysdate,'YYYY-MM-DD_HH24-MI-SS')||'.log' as foo1 from sys.dual;
spool ^LOG1
timing start "Remove all workspaces, schemas and tablespaces"
--
-- Step 1: Remove the APEX Workspaces
--
--
begin
apex_instance_admin.remove_workspace(
p_workspace => 'OACADEMY1' );
end;
/
begin
apex_instance_admin.remove_workspace(
p_workspace => 'OACADEMY2' );
end;
/
--
-- Step 2: Drop the database users
--
--
drop user OACADEMY_DB10 cascade;
drop user OACADEMY_DB11 cascade;
drop user OACADEMY_DB20 cascade;
drop user OACADEMY_DB21 cascade;
--
-- Step 3: Drop the tablespaces
--
--
drop tablespace oacademy_data1 including contents and datafiles;
drop tablespace oacademy_data2 including contents and datafiles;
timing stop
spool off
No comments:
Post a Comment