2026-10-04 08:36:14

This commit is contained in:
support committed 2026-10-04 10:36:14 +02:00
1 parent 4f6a34cfcc
commit fc997210bf
2 files changed
+226 -4

No files matched your search

+56 -4
View File
@@ -1,13 +1,20 @@
# Oracle E-commerce and Accounting Workload
This project contains three SQL*Plus/SQLcl scripts for creating and exercising
an Oracle e-commerce and accounting schema.
This project contains SQL*Plus/SQLcl scripts for creating and exercising an
Oracle e-commerce and accounting schema, including background workload jobs.
## Requirements
- Oracle Database 12c or later. The schema uses identity columns and daily
interval partitioning.
- Run the scripts while connected as the schema owner.
- The Scheduler management procedures require the schema owner to have the
`CREATE JOB` system privilege. A DBA can grant it directly:
```sql
GRANT CREATE JOB TO your_schema;
```
- The activity procedure uses `DBMS_LOCK.SLEEP`. The schema owner may need a
direct grant from a DBA:
@@ -25,11 +32,13 @@ Run these scripts in order from SQL*Plus or SQLcl:
@oracle_ecommerce_schema.sql
@oracle_ecommerce_seed_2gb.sql
@oracle_ecommerce_activity.sql
@oracle_ecommerce_job_management.sql
```
The schema script creates objects only. The seed script expects the schema to
be empty and should be run once. The activity script creates or replaces the
workload procedure and can be rerun to install procedure changes.
be empty and should be run once. The activity and job-management scripts
create or replace their procedures and can be rerun to install procedure
changes.
## `oracle_ecommerce_schema.sql`
@@ -110,3 +119,46 @@ EXEC simulate_commerce_activity(100, 2, 5.5);
The procedure prints a one-line summary for each iteration and a final total
and realized average. `DBMS_OUTPUT` is buffered, so SQL*Plus/SQLcl may display
the output after the procedure completes.
## `oracle_ecommerce_job_management.sql`
Creates four procedures for managing one-time Oracle Scheduler jobs that run
`SIMULATE_COMMERCE_ACTIVITY` asynchronously. A created job is enabled
immediately, starts as soon as Scheduler can run it, executes the specified
number of iterations, and remains in the schema's Scheduler job list after
completion (`AUTO_DROP` is disabled).
```sql
SET SERVEROUTPUT ON
-- Create a background job: name, iterations, seconds between iterations,
-- average DML rows per iteration.
EXEC create_commerce_activity_job('COMMERCE_LOAD_01', 10000, 3, 5.5);
-- List Scheduler jobs for SIMULATE_COMMERCE_ACTIVITY.
EXEC list_commerce_activity_jobs;
-- Stop and disable a pending or running job; it remains listed.
EXEC stop_commerce_activity_job('COMMERCE_LOAD_01');
-- Remove the job. FORCE also stops it if it is still running.
EXEC remove_commerce_activity_job('COMMERCE_LOAD_01');
```
The list procedure reports the job state, enabled status, run/failure counts,
and last start time. `STOP` disables the job and force-stops it if running;
it does not resume automatically. `REMOVE` drops the job and force-stops it
if necessary. These operations apply to jobs owned by the connected schema.
For run history and Scheduler error messages, query the job run details view:
```sql
SELECT log_date, status, error#, additional_info
FROM user_scheduler_job_run_details
WHERE job_name = 'COMMERCE_LOAD_01'
ORDER BY log_date DESC;
```
The activity procedure's `DBMS_OUTPUT` is generated in the Scheduler worker
session and is not normally returned to the session that submitted the job.
Use Scheduler run details to inspect completion status and errors.
@@ -0,0 +1,170 @@
-- Scheduler helpers for running SIMULATE_COMMERCE_ACTIVITY asynchronously.
-- Run as the schema owner after oracle_ecommerce_activity.sql.
-- The schema owner needs the CREATE JOB system privilege.
WHENEVER SQLERROR EXIT SQL.SQLCODE
SET DEFINE OFF
SET SERVEROUTPUT ON SIZE UNLIMITED
CREATE OR REPLACE PROCEDURE create_commerce_activity_job (
p_job_name IN VARCHAR2,
p_iterations IN PLS_INTEGER,
p_seconds_between_iterations IN NUMBER,
p_average_rows_per_iteration IN NUMBER
) AS
l_job_name VARCHAR2(128);
BEGIN
IF p_job_name IS NULL OR TRIM(p_job_name) IS NULL THEN
RAISE_APPLICATION_ERROR(-20010, 'p_job_name must not be empty');
END IF;
l_job_name := DBMS_ASSERT.SIMPLE_SQL_NAME(UPPER(TRIM(p_job_name)));
IF p_iterations IS NULL OR p_iterations < 0 THEN
RAISE_APPLICATION_ERROR(-20011, 'p_iterations must be a non-negative integer');
END IF;
IF p_seconds_between_iterations IS NULL OR p_seconds_between_iterations < 0 THEN
RAISE_APPLICATION_ERROR(-20012, 'p_seconds_between_iterations must be non-negative');
END IF;
IF p_average_rows_per_iteration IS NULL OR p_average_rows_per_iteration < 0
OR p_average_rows_per_iteration > 10000 THEN
RAISE_APPLICATION_ERROR(-20013, 'p_average_rows_per_iteration must be between 0 and 10000');
END IF;
DBMS_SCHEDULER.CREATE_JOB(
job_name => l_job_name,
job_type => 'STORED_PROCEDURE',
job_action => 'SIMULATE_COMMERCE_ACTIVITY',
number_of_arguments => 3,
start_date => SYSTIMESTAMP,
enabled => FALSE,
auto_drop => FALSE,
comments => 'Background e-commerce activity simulation'
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
job_name => l_job_name,
argument_position => 1,
argument_value => TO_CHAR(p_iterations, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,''')
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
job_name => l_job_name,
argument_position => 2,
argument_value => TO_CHAR(
p_seconds_between_iterations, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,'''
)
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
job_name => l_job_name,
argument_position => 3,
argument_value => TO_CHAR(
p_average_rows_per_iteration, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,'''
)
);
DBMS_SCHEDULER.ENABLE(l_job_name);
DBMS_OUTPUT.PUT_LINE(
'Enabled Scheduler job ' || l_job_name ||
' to run SIMULATE_COMMERCE_ACTIVITY in the background.'
);
END;
/
CREATE OR REPLACE PROCEDURE list_commerce_activity_jobs AS
l_jobs_found PLS_INTEGER := 0;
BEGIN
DBMS_OUTPUT.PUT_LINE(
RPAD('JOB NAME', 32) || RPAD('STATE', 16) ||
RPAD('ENABLED', 10) || RPAD('RUNS', 8) ||
RPAD('FAILURES', 10) || 'LAST START'
);
DBMS_OUTPUT.PUT_LINE(RPAD('-', 100, '-'));
FOR job_rec IN (
SELECT job_name, state, enabled, run_count, failure_count, last_start_date
FROM user_scheduler_jobs
WHERE job_type = 'STORED_PROCEDURE'
AND job_action = 'SIMULATE_COMMERCE_ACTIVITY'
ORDER BY job_name
) LOOP
l_jobs_found := l_jobs_found + 1;
DBMS_OUTPUT.PUT_LINE(
RPAD(job_rec.job_name, 32) ||
RPAD(job_rec.state, 16) ||
RPAD(CASE WHEN job_rec.enabled = 'TRUE' THEN 'YES' ELSE 'NO' END, 10) ||
RPAD(TO_CHAR(job_rec.run_count), 8) ||
RPAD(TO_CHAR(job_rec.failure_count), 10) ||
NVL(
TO_CHAR(job_rec.last_start_date, 'YYYY-MM-DD HH24:MI:SS TZH:TZM'),
'never'
)
);
END LOOP;
IF l_jobs_found = 0 THEN
DBMS_OUTPUT.PUT_LINE('No SIMULATE_COMMERCE_ACTIVITY Scheduler jobs found.');
END IF;
END;
/
CREATE OR REPLACE PROCEDURE stop_commerce_activity_job (
p_job_name IN VARCHAR2
) AS
l_job_name VARCHAR2(128);
l_job_count PLS_INTEGER;
BEGIN
IF p_job_name IS NULL OR TRIM(p_job_name) IS NULL THEN
RAISE_APPLICATION_ERROR(-20020, 'p_job_name must not be empty');
END IF;
l_job_name := DBMS_ASSERT.SIMPLE_SQL_NAME(UPPER(TRIM(p_job_name)));
SELECT COUNT(*)
INTO l_job_count
FROM user_scheduler_jobs
WHERE job_name = l_job_name
AND job_type = 'STORED_PROCEDURE'
AND job_action = 'SIMULATE_COMMERCE_ACTIVITY';
IF l_job_count = 0 THEN
RAISE_APPLICATION_ERROR(-20021, 'No activity Scheduler job named ' || l_job_name);
END IF;
DBMS_SCHEDULER.DISABLE(
name => l_job_name,
force => TRUE
);
DBMS_OUTPUT.PUT_LINE('Stopped and disabled Scheduler job ' || l_job_name || '.');
END;
/
CREATE OR REPLACE PROCEDURE remove_commerce_activity_job (
p_job_name IN VARCHAR2
) AS
l_job_name VARCHAR2(128);
l_job_count PLS_INTEGER;
BEGIN
IF p_job_name IS NULL OR TRIM(p_job_name) IS NULL THEN
RAISE_APPLICATION_ERROR(-20030, 'p_job_name must not be empty');
END IF;
l_job_name := DBMS_ASSERT.SIMPLE_SQL_NAME(UPPER(TRIM(p_job_name)));
SELECT COUNT(*)
INTO l_job_count
FROM user_scheduler_jobs
WHERE job_name = l_job_name
AND job_type = 'STORED_PROCEDURE'
AND job_action = 'SIMULATE_COMMERCE_ACTIVITY';
IF l_job_count = 0 THEN
RAISE_APPLICATION_ERROR(-20031, 'No activity Scheduler job named ' || l_job_name);
END IF;
DBMS_SCHEDULER.DROP_JOB(
job_name => l_job_name,
force => TRUE
);
DBMS_OUTPUT.PUT_LINE('Removed Scheduler job ' || l_job_name || '.');
END;
/
SHOW ERRORS PROCEDURE create_commerce_activity_job
SHOW ERRORS PROCEDURE list_commerce_activity_jobs
SHOW ERRORS PROCEDURE stop_commerce_activity_job
SHOW ERRORS PROCEDURE remove_commerce_activity_job