Native PL/SQL Application to Capture Source Code and Configuration Data
As Of: January 28, 2025
This is a comparison between Open Source ODBCapture and Oracle’s SQL*cl.
NOTE: Both tools are complex and currently being enhanced. Any errors in this comparison are not intentional and will be corrected upon notice.
Notes:
ODBCapture | SQL*cl | Description |
---|---|---|
Yes | Yes | DBMS_METADATA for DDL/DCL Script Generation |
Yes | Yes | Separate Scripts for Each Schema/Object |
Yes | Yes | Create Folder Structure for Scripts |
Yes | Yes | Install Multiple Integrated Users/Schemas |
Yes | Yes | Multiple Oracle DB Versions/Editions/Options |
Yes | Yes | Track Installed Versions of Application |
Yes* | Yes | Generate Deployable Artifact (Zip File) |
Yes* | Yes | Create Scripts Directly in File System |
Yes | Yes | Separate Scripts for SYS actions |
Yes | Yes* | CSV formatted Data Files |
Yes | . | Generated SQL*Loader Control File and SQL Script |
Yes | . | Separate Scripts for SYSTEM/DBA actions |
Yes | . | Master Installation Wrapper Script |
Yes | . | Build Layer Installation with Dependencies |
Yes | . | Configurable Database Object Type Sequencing |
Yes | . | Configurable Script File Name Extensions |
Yes | . | Filtering of System Generated Database Objects |
Yes | . | SQL*Plus/Windows Special Character Handling |
Yes | . | US7ASCII Conversion of all Data and Scripts |
Yes | . | Stored Configuration of Data Filters |
Yes | . | Foreign Key DISABLE for Data Loading |
Yes | . | Table Trigger DISABLE for Data Loading |
Yes | . | Table Loading of Installation Log Files |
Yes | . | Tailored Install Status Reporting Scripts |
Yes | . | JUnit (XML) Install Status Reporting |
Yes | . | ORA-01720: “WORKAROUND” on Dependent Views |
Yes | . | Internal to the Database (Nothing External) |
Yes | . | Complete ZIP File Created in Database |
. | Yes* | Generate INSERT statements for Data Loading |
. | Yes | Generate Git Project Status Files |
. | Yes | Generate/Deploy/Verify Diff Scripts |
. | Yes | Liquibase Integration |
ODBCapture and SQL*cl have similar goals for source code files. Additionally, both track the version of scripts installed into a database.
Each feature is listed with explanation.
Capturing data in source code, like configuration data and test data, can be daunting when using INSERT statements. CSV formatted files are easier to edit in a modern spreadsheet. However, another process, like SQL*Loader is needed to load the CSV formatted data. SQL*Loader requires a control file to describe layout of the data in a CSV formatted file. Additionally, there is some pre-processing and post-processing that may be required for each data load. ODBCapture handles all of these cases by creating the needed SQL*Loader Control File and adding the needed pre-processing and post-processing to the SQL script that calls SQL*Loader.
Highly secured production environments can have increased scrutiny. This scrutiny can require additional approvals for database modifications that require SYS privileges, versus privileges granted to SYSTEM or other DBAs. ODBCapture separates installation tasks that require SYS privileges from the others. This can simiplify deployment when requirements for SYS privileges are easily identifiable.
SQL*cl is required to execute the installation scripts it generates. This additional need for a tool that is not installed with the database can pose problems for highly secured production environments. ODBCapture creates fully self-contained installation scripts that accomplish the needed tasks using only tools installed with the database.
Build Layers are covered extensively on the Build Script Layering Webpage
There is no absolute correct sequence for database object type installation in Oracle. Oracle’s Export utility uses dependency relationships to properly order each database object in an export. This complexity is out of scope for ODBCapture. The default sequence is acceptable for almost all circumstances. The sequence can be modified if needed.
The default File Name Extensions chosen for ODBCapture specifically avoids extensions recognized by database development tools popular with Oracle. Files with recognized extensions require specific formatting to work properly in the development tool. These formats are not common across tools. ODBCapture avoids these formatting conficts by default, but allows recognized extensions to be configured.
The Oracle database will silently create/generate additional database objects when some database objects are created. These additional objects can cause problems if they are captured and installed from source code. ODBCapture filters these silently created database objects from source code.
Installation scripts can suffer greatly from a variety of “special character” occurances. ODBCapture accounts for many potential problems with the contents of installation scripts and their usage in different environments.
ODBCapture stores data filters and other data capture configurations in the DLOAD_CONF table. SQL*cl requires queries to be saved in files and run manually (or scripted) to capture specific configuration data.
ODBCapture accomodates dependent object restrictions during data loading.
The installation scripts generated by ODBCapture included comprehensive status and reporting capabilities:
ODBCapture includes special handling for inter-dependencies between views as described in ASK TOM.
Many companies have enacted highly restrictive security policies for their production databases. DBAs no longer can allow developer access to the production database. ODBCapture can be presented to the DBAs for installation on a production database. ODBCapture can be deployed to a production database by the DBAs without any unique tool connection. ODBCapture procedures can be executed by the DBAs to generate/capture source code and configuration data from the production database. DBAs can download and provide the resulting ZIP file to the developers for source code audit processing.
Queries are used in SQL*cl to capture source code data (ex. sample data). There are several “sqlformat” options availalable for the output of those queries. In the SQL*cl User Guide, an example is given where the “sqlformat” INSERT is used to generate/capture data from the database. In Step 8 of Ticket 1, the documentation says, “… copy and paste the following statements to the end of the file and then save the file.” However, there is no documentation found regarding Database Data Types supported by the SQL*cl “sqlformat” output formatting”. Sample data and queries were created to check basic functionality of these data types using SQL*cl.
Notes:
ODBCapture | SQL*cl | Database Data Type |
---|---|---|
. | Yes | BINARY_DOUBLE |
. | Yes | BINARY_FLOAT |
Yes | Yes** | BLOB |
Yes | Yes** | BFILE |
Yes | Yes* | CHAR |
Yes | Yes* | CLOB |
Yes | Yes | DATE |
Yes | Yes | INTERVAL_DAY_TO_SECOND |
Yes | Yes | INTERVAL_YEAR_TO_MONTH |
Yes | Yes* | JSON |
. | Yes* | LONG |
. | Yes | LONG RAW |
. | ? | MLSLABEL |
Yes | Yes* | NCHAR |
Yes | Yes* | NCLOB |
Yes | Yes | NUMBER |
Yes | Yes* | NVARCHAR |
Yes | Yes | RAW |
. | Yes | ROWID |
Yes | Yes | TIMESTAMP |
Yes | Yes | TIMESTAMP_WITH_LOCAL_TZ |
Yes | Yes | TIMESTAMP_WITH_TZ |
. | ? | UROWID |
Yes | Yes** | User Defined Object Types (Limited) |
Yes | Yes* | VARCHAR2 |
Yes | Yes* | XMLTYPE |
Database Object Types supported by the SQL*cl Project Export
command can be found at SQL Developer Command Line Release 24.3 User’s Guide 4.1.1 Supported Objects. Note: All types not included in the following list can be added using the project stage add-custom command with any custom SQL. For more information about the add-custom sub-command, enter help project stage add-custom in the SQLcl command-line help.
ODBCapture | SQL*cl | Database Object Type |
---|---|---|
. | Yes | APEX_APP |
Yes | . | AQ_QUEUE |
Yes | . | AQ_QUEUE_TABLE |
. | . | AQ_TRANSFORM |
. | . | ASSOCIATION |
. | . | AUDIT |
. | . | AUDIT_OBJ |
. | . | CLUSTER |
Yes | Yes | COMMENT |
Yes | Yes | CONTEXT |
Yes | . | DB_LINK |
. | . | DBMS_JOBS |
. | . | DEFAULT_ROLE |
Yes | Yes? | DATABASE_TRIGGER |
. | . | DIMENSION |
Yes | . | DIRECTORY |
. | . | FGA_POLICY |
Yes | Yes | FUNCTION |
Yes | . | HOST_ACL |
. | . | INDEX_STATISTICS |
. | . | INDEXTYPE |
Yes | . | JAVA_SOURCE |
. | . | LIBRARY |
Yes | . | MATERIALIZED_VIEW |
Yes | Yes? | MATERIALIZED_VIEW_INDEX |
Yes | . | MATERIALIZED_VIEW_LOG |
Yes | Yes? | MATERIALIZED_REF_CONSTRAINT |
Yes | Yes | OBJECT_GRANT |
. | . | ON_USER_GRANT |
. | . | OPERATOR |
Yes | Yes | PACKAGE_SPEC |
Yes | Yes | PACKAGE_BODY |
Yes | Yes | PROCEDURE |
. | . | PROFILE |
. | . | PROXY |
Yes | . | PUBLIC_SYNONYM |
. | . | REFRESH_GROUP |
. | . | RESOURCE_COST |
. | . | RLS_CONTEXT |
. | . | RLS_GROUP |
. | . | RLS_POLICY |
. | . | RMGR_CONSUMER_GROUP |
. | . | RMGR_INTITIAL_CONSUMER_GROUP |
. | . | RMGR_PLAN |
. | . | RMGR_PLAN_DIRECTIVE |
Yes | . | ROLE |
Yes | Yes | ROLE_GRANT |
. | . | ROLLBACK_SEGMENT |
Yes | . | SCHEDULER_JOB |
Yes | . | SCHEDULER_PROGRAM |
Yes | . | SCHEDULER_SCHEDULE |
Yes | Yes? | SCHEMA TRIGGER |
Yes | Yes | SEQUENCE |
Yes | Yes | SYNONYM |
Yes | Yes | SYS_OBJ_GRANT |
Yes | Yes | SYSTEM_PRIV_GRANT |
Yes | Yes | TABLE |
Yes | Yes | TABLE_CONSTRAINTS |
Yes | . | TABLE_DATA |
Yes | Yes | TABLE_INDEX |
Yes | Yes | TABLE_TRIGGER |
Yes | Yes | TABLE_REF_CONSTRAINT |
. | . | TABLE_STATISTICS |
. | . | TABLESPACE |
. | . | TABLESPACE_QUOTA |
. | . | TRANSPORTABLE_EXPORT |
. | . | TRUSTED_DB_LINK |
. | . | TRIGGER_XS_ACL |
. | . | TRUSTED_DB_LINK |
Yes | Yes | TYPE_SPEC |
Yes | Tes | TYPE_BODY |
Yes | Yes | USER |
Yes | Yes | VIEW |
Yes | Yes? | VIEW_REF_CONSTRAINT |
Yes | Yes? | VIEW_TRIGGER |
Yes | . | WALLET_ACL |
Yes | . | XMLSCHEMA |
Yes | . | XDB_ACL |
Yes | . | XS_ACL (RAS_ACL) |
Yes | . | XS_ACL_PARAM |
. | . | XS_ACL_PARAM INDEX |
Yes | . | XS_DATA_SECURITY |
. | . | XS_NAMESPACE |
Yes | . | XS_ROLE |
. | . | XS_ROLESET |
Yes | . | XS_ROLE_GRANT |
. | . | XS_SECURITY_CLASS |
Yes | . | XS_USER |
Commands Used:
docker run --rm -it --entrypoint /bin/bash container-registry.oracle.com/database/sqlcl:24.3.2
# https://github.com/oracle/docker-images/issues/2210
export JAVA_TOOL_OPTIONS="-Doracle.net.disableOob=true"
mkdir ss
cd ss
sql -nolog
connect -savepwd -save c1 sys/password@localhost:1521/DEVPDB as sysdba
project init -schemas HR,OE,PM -con c1
project export
exit
exit
File/Folder Structure:
src/
database/
README.md
hr/
comments/
countries.sql
departments.sql
employees.sql
job_history.sql
jobs.sql
locations.sql
regions.sql
indexes/
dept_location_ix.sql
emp_department_ix.sql
emp_job_ix.sql
emp_manager_ix.sql
emp_name_ix.sql
jhist_department_ix.sql
jhist_employee_ix.sql
jhist_job_ix.sql
loc_city_ix.sql
loc_country_ix.sql
loc_state_province_ix.sql
object_grants/
object_grants_as_grantor.hr.table.countries.sql
object_grants_as_grantor.hr.table.departments.sql
object_grants_as_grantor.hr.table.employees.sql
object_grants_as_grantor.hr.table.job_history.sql
object_grants_as_grantor.hr.table.jobs.sql
object_grants_as_grantor.hr.table.locations.sql
procedures/
add_job_history.sql
secure_dml.sql
ref_constraints/
countr_reg_fk.sql
dept_loc_fk.sql
dept_mgr_fk.sql
emp_dept_fk.sql
emp_job_fk.sql
emp_manager_fk.sql
jhist_dept_fk.sql
jhist_emp_fk.sql
jhist_job_fk.sql
loc_c_id_fk.sql
sequences/
departments_seq.sql
employees_seq.sql
locations_seq.sql
tables/
countries.sql
departments.sql
employees.sql
job_history.sql
jobs.sql
locations.sql
regions.sql
triggers/
secure_employees.sql
update_job_history.sql
views/
emp_details_view.sql
oe/
comments/
customers.sql
inventories.sql
order_items.sql
orders.sql
product_descriptions.sql
product_information.sql
warehouses.sql
functions/
get_phone_number_f.sql
indexes/
cust_account_manager_ix.sql
cust_email_ix.sql
cust_lname_ix.sql
inv_product_ix.sql
item_order_ix.sql
item_product_ix.sql
ord_customer_ix.sql
ord_order_date_ix.sql
ord_sales_rep_ix.sql
order_items_uk.sql
prod_name_ix.sql
prod_supplier_ix.sql
'sys_fk0000075797n00008$.sql'
'sys_fk0000075797n00010$.sql'
whs_location_ix.sql
object_grants/
object_grants_as_grantor.oe.table.customers.sql
object_grants_as_grantor.oe.table.inventories.sql
object_grants_as_grantor.oe.table.order_items.sql
object_grants_as_grantor.oe.table.orders.sql
object_grants_as_grantor.oe.table.product_descriptions.sql
object_grants_as_grantor.oe.table.product_information.sql
object_grants_as_grantor.oe.table.warehouses.sql
ref_constraints/
customers_account_manager_fk.sql
inventories_product_id_fk.sql
inventories_warehouses_fk.sql
order_items_order_id_fk.sql
order_items_product_id_fk.sql
orders_customer_id_fk.sql
orders_sales_rep_fk.sql
pd_product_id_fk.sql
warehouses_location_fk.sql
sequences/
orders_seq.sql
synonyms/
countries.sql
departments.sql
employees.sql
job_history.sql
jobs.sql
locations.sql
tables/
categories_tab.sql
customers.sql
inventories.sql
order_items.sql
orders.sql
product_descriptions.sql
product_information.sql
promotions.sql
purchaseorder.sql
warehouses.sql
triggers/
insert_ord_line.sql
orders_items_trg.sql
orders_trg.sql
'purchaseorder$xd.sql'
type_bodies/
catalog_typ.sql
composite_category_typ.sql
leaf_category_typ.sql
type_specs/
action_t.sql
action_v.sql
actions_t.sql
catalog_typ.sql
category_typ.sql
composite_category_typ.sql
corporate_customer_typ.sql
cust_address_typ.sql
customer_typ.sql
inventory_list_typ.sql
inventory_typ.sql
leaf_category_typ.sql
lineitem_t.sql
lineitem_v.sql
lineitems_t.sql
order_item_list_typ.sql
order_item_typ.sql
order_list_typ.sql
order_typ.sql
part_t.sql
phone_list_typ.sql
product_information_typ.sql
product_ref_list_typ.sql
purchaseorder_t.sql
rejection_t.sql
shipping_instructions_t.sql
subcategory_ref_list_typ.sql
'sys_yoid0000075921$.sql'
'sys_yoid0000075922$.sql'
'sys_yoid0000075923$.sql'
'sys_yoid0000075925$.sql'
'sys_yoid0000075928$.sql'
warehouse_typ.sql
views/
account_managers.sql
bombay_inventory.sql
customers_view.sql
oc_corporate_customers.sql
oc_customers.sql
oc_inventories.sql
oc_orders.sql
oc_product_information.sql
orders_view.sql
product_prices.sql
products.sql
sydney_inventory.sql
toronto_inventory.sql
pm/
indexes/
'sys_fk0000075860n00007$.sql'
ref_constraints/
printmedia_fk.sql
tables/
print_media.sql
type_specs/
adheader_typ.sql
textdoc_tab.sql
textdoc_typ.sql
sys/
object_grants/
object_grants_as_grantor.sys.directory.media_dir.sql
object_grants_as_grantor.sys.directory.ss_oe_xmldir.sql
object_grants_as_grantor.sys.directory.subdir.sql
object_grants_as_grantor.sys.package.dbms_stats.sql