2025年2月18日火曜日

Oracle APEX 24.2のビルダー拡張の自動サブスクリプションについて

Oracle APEX 24.1で追加されたビルダー拡張ですが(ビルダー拡張については、こちらの記事で紹介しています - Oracle APEX 24.1のビルダー拡張機能となるサンプル・アプリケーションを実装する)、Oracle APEX 24.2で自動サブスクリプションの機能が追加されました。

管理サービスワークスペースの管理にて、拡張機能のホストを許可にて、はい - 自動手動サブスクリプションを選択します。はい - 手動サブスクリプションの場合、Oracle APEX 24.2以前の動作になります。


自動手動サブスクリプションとは?と思ったので、英語を確認してみました。英語ではAutomatic Subscriptionなので、日本語の間違いのようです。


拡張リンクは、拡張機能をホストしているワークスペースで設定します。

管理ツールサービスの管理に含まれる拡張リンクの管理を開きます。


拡張リンクとして、外部リンクまたはワークスペースに作成されているアプリケーションを指すリンクを設定します。


Oracle APEX 24.2以前は、この拡張リンクをワークスペースから参照するには、拡張機能ワークスペースを明示的にサブスクライブする必要がありました。

Oracle APEX 24.2で拡張機能のホストを許可自動サブスクリプションが設定されている場合、拡張機能ワークスペースは自動的にサブスクリプションに追加されます。

拡張機能ワークスペースと同様に管理サービス拡張リンクの管理を開き、サブスクリプションのタブを開きます。拡張機能ワークスペースが自動的にサブスクリプションに追加されていることを確認できます。


ただし、不要であれば手動でサブスクライブを解除することもできます。


新規にワークスペースを作成した場合など、手作業でサブスクライブしなくても拡張リンクを使えるようになって欲しいという要望が多かったのだと思います。実際、拡張リンクが設定されている場合は、ほとんどのワークスペースがサブスクライブしているはずです。

今回の記事は以上になります。

2025年2月17日月曜日

SQLclを使ったExcelとAccess MDBファイルのインポートを試してみる

Oracle SQLcl 24.4.1では、接続しているデータベースにExcelファイルをインポートできるようになりました。LOADFORMATにxlsx(またはxls)を設定し、LOADコマンドを実行します。

Oracle Databaseの開発ツールのPMのJeff Smithさんが、以下のブログ記事にて紹介しています。

Oracle SQLcl 24.4.1 available with Excel & Access imports
https://www.thatjeffsmith.com/archive/2025/02/oracle-sqlcl-24-4-1-available-with-excel-access-imports/

記事のタイトルにありますが、SQLclを使ってAccessのMDBファイル(拡張子.mdbまたは.accdbのファイル)の表やビューおよびそのデータをインポートできます。SQLcl 24.3で追加されたMDBコマンドを使用します。

Oracle SQLcl 24.3 Release Notes
October 2024
https://www.oracle.com/tools/sqlcl/sqlcl-relnotes-24.3.html

最初にExcelのインポートについて確認してみます。

SQLclのLOADコマンドの説明はこちらになります。Excelをインポートする場合はSET LOADFORMATにXLSXを設定しますが、この機能が追加されたのが24.4.1のため、24.4のLOADFORMATの説明にXLSXは含まれていないようです。LOADFORMATの英語のHELPにはxlsとxlsxが含まれます。

SQL> help set loadformat

SET LOADFORMAT [ default|csv|delimited|html|insert|json|json-formatted|loader|t2|xml|xls|xlsx] [options...]

   

  default        : Load format properties return to default values 

  csv            : comma separated values

  delimited      : (CSV synonym) delimited format, comma separated values by default  

  html           : UNLOAD only, Hypertext Markup Language

  insert         : UNLOAD only, SQL insert statements

  json           : UNLOAD only, Java Script Object Notation

  json-formatted : UNLOAD only, "pretty" formatted JSON

  loader         : UNLOAD only, Oracle SQLLoader format

  t2             : UNLOAD only, T2 Metrics

  xml            : UNLOAD only, Extensible Markup Language

  xls            : Excel 97- Excel 2003 Workbook format

  xlsx           : Excel format for version 2007 or higher


where options represents the following clauses:


日本語のHELPにはxlsおよびxlsxは含まれていませんが、これは翻訳に反映されていないだけなので機能は使用できます。

SQL> help set loadformat

SET LOADFORMAT [ default|csv|delimited|html|insert|json|json-formatted|loader|t2|xml] [options...]

   

  default        : ロードの書式プロパティをデフォルト値に戻します 

  csv            : カンマ区切り値

  delimited      : (CSVシノニム)区切り形式。デフォルトではカンマ区切り値です 

  html           : UNLOADのみ。Hypertext Markup Language

  insert         : UNLOADのみ。SQL insert文

  json           : UNLOADのみ。Java Script Object Notation

  json-formatted : UNLOADのみ。"pretty"形式のJSON

  loader         : UNLOADのみ。Oracle SQLLoader形式

  t2             : UNLOADのみ。T2メトリック

  xml            : UNLOADのみ。Extensible Markup Language


オプションは次の句を表します:


国名、首都名、首都の経度、首都の緯度を列として持つExcelファイルCountries.xlsxを作成し、データベースにインポートします。


ドキュメントやヘルプ、およびコマンドのオプションなどから判断すると、SQLclでインポートできるのは、Excelファイルの先頭のシートに限定されるようです。

SQLclでインポート先となるデータベースに接続します。LOADコマンドはSQLclの機能なので、接続先のデータベースのバージョンに依存しません。

最初にloadformatのデフォルトの設定を確認します。デフォルトはCSVです。

SQL> show loadformat


csv

column_names on

delimiter ,

enclosures ""

double

encoding UTF8

row_limit off

row_terminator default

skip_rows 0

skip_after_names

SQL> 


loadformatxlsxを指定します。

SQL> set loadformat xlsx

SQL> 


設定されたloadformatのオプションを確認します。Excel形式のインポートについては、指定可能なオプションは無いようです。

SQL> show loadformat


xlsx

SQL> 


Countries.xlsxを読み込む際に作成される表を確認します。showオプションをつけて実行します。インポート先の表はTEST_COUNTRIESとします。

QL> load test_countries Countries.xlsx show


表のDDLを表示します WKSP_APEXDEV.TEST_COUNTRIES



CREATE TABLE WKSP_APEXDEV.TEST_COUNTRIES

 (

  国名 VARCHAR2(26),

  首都名 VARCHAR2(26),

  首都の緯度 VARCHAR2(26),

  首都の経度 VARCHAR2(26)

 )

;


成功: エラーなしで処理されました

SQL> 


Excelのデータの先頭行を列名として表定義を生成しています。このままの定義でインポート先となる表を作成されると扱いにくいため、 あらかじめ以下の定義で表TEST_COUNTRIESを作成します。
create table test_countries (
    country_name    varchar2(80 char),
    capital_name    varchar2(80 char),
    longitude       number,
    latitude        number
);

SQL> create table test_countries (

  2      country_name    varchar2(80 char),

  3      capital_name    varchar2(80 char),

  4      longitude       number,

  5      latitude        number

  6* );


Table TEST_COUNTRIESは作成されました。


SQL> 


LOADコマンドに設定されているオプションを確認します。

SQL> show load

batch_rows 50

batches_per_commit 10

clean_names transform

column_size rounded

commit on

date_format 

errors 50

map_column_names off

method insert

timestamp_format 

timestamptz_format 

locale

scan_rows 100

truncate off

unknown_columns_fail on

SQL> 


作成した表TEST_COUNTIRESの列とExcelの列の対応を、MAPNAMESとして設定します。

SQL> set load mapnames (国名=COUNTRY_NAME,首都名=CAPITAL_NAME,首都の経度=LONGITUDE,首都の緯度=LATITUDE)

SQL> 


再度、LOADコマンドに設定されたオプションを確認します。コマンドで指定したmapnamesmap_column_namesの短縮形です。

SQL> show load

batch_rows 50

batches_per_commit 10

clean_names transform

column_size rounded

commit on

date_format 

errors 50

map_column_names (首都名=CAPITAL_NAME, 首都の緯度=LATITUDE, 国名=COUNTRY_NAME, 首都の経度=LONGITUDE)

method insert

timestamp_format 

timestamptz_format 

locale

scan_rows 100

truncate off

unknown_columns_fail on

SQL> 


ExcelファイルCountries.xlsxを表TEST_COUNTRIESにロードします。

SQL> load test_countries Countries.xlsx


データを表にロードします WKSP_APEXDEV.TEST_COUNTRIES

batch_rows 50

batches_per_commit 10

clean_names transform

column_size rounded

commit on

date_format 

errors 50

map_column_names (首都名=CAPITAL_NAME, 首都の緯度=LATITUDE, 国名=COUNTRY_NAME, 首都の経度=LONGITUDE)

method insert

timestamp_format 

timestamptz_format 

locale

scan_rows 100

truncate off

unknown_columns_fail on


#INFO 処理された行数: 193

#INFO エラーのある行数: 0

#INFO 最後にコミットされたバッチで処理された最後の行: 193

成功: エラーなしで処理されました

SQL> 


以上で、ExcelファイルCountries.xlsxを表TEST_COUNTRIESにロードできました。

続いてAccess MDBファイルのインポートを確認してみます。

インポートの確認には、O'Reilly Mediaより出版されているExcel 2007: The Missing Manual(ISBN:9780596527594)のChapter 24で使用されているNorthwind.MDBを使用します。

SQLclでインポート先となるデータベースに接続します。

mdbコマンドのHELPを表示します。

MDBの内容を表示するにはlist、実際にMDBのデータをインポートするにはcopyコマンドを使用します。

SQL> help mdb

command facilitates the import of tables and data from MDB (Microsoft Access Database) files into an Oracle database

schema


サブコマンド:

  list

  List tables or saved queries(views) that exist in the specified MDB file and outputs the list


  copy

  Copy tables or views from MS Access database to Oracle Database


その他のヘルプ・トピック:

  MDB EXAMPLES

  MDB SYNTAX

  MDB LIST

  MDB COPY


SQL>


mdb listコマンドを実行し、Northwind.MDBの内容を確認します。

SQL> mdb list -file Northwind.MDB


TABLE_NAME                      |TABLE_TYPE 

-----------------------------------------

Categories                      |TABLE 

Customers                       |TABLE 

Employees                       |TABLE 

Order Details                   |TABLE 

Orders                          |TABLE 

Products                        |TABLE 

Shippers                        |TABLE 

Suppliers                       |TABLE 

Alphabetical List of Products   |VIEW  

Catalog                         |VIEW  

Current Product List            |VIEW  

Customers and Suppliers by City |VIEW  

Invoices                        |VIEW  

Order Details Extended          |VIEW  

Order Subtotals                 |VIEW  

Orders Qry                      |VIEW  

Products Above Average Price    |VIEW  

Products by Category            |VIEW  

Summary of Sales by Quarter     |VIEW  

Summary of Sales by Year        |VIEW  

Ten Most Expensive Products     |VIEW  

Employee Sales by Country       |VIEW  

SQL> 


mdb copyを実行する前にHELPを表示します。

SQL> help mdb copy

Copy tables or views from MS Access database to Oracle Database


使用方法:

  mdb|mdb  copy {OPTIONS}


オプション:

  -tables|-tabs

  Only the tables that exists in the specified MS Access file


  -views|-vw

  Only the views or saved queries that are saved in MS Access database


  -file|-fi <file> {FILE} [必須]

  Path of the MS database file


  -prefix|-pr <prefix>

  Name to add before the tables or views tables names


  -table|-tab <table>

  Copy a specific table from MDB file into Oracle Database


  -mode|-mo <mode> {APPEND|REPLACE|SKIP|TRUNCATE} (REPLACE)

  Specify the mode of operation for handling existing data in the destination table

  The available options are:

  replace: If the target table exists, drop it, then re-create it and add the new data

  append: Add the new data to the existing data in the target table, if any

  truncate: Clear all existing data in the target table before adding the new data

  skip: If the target table already exists, do nothing; otherwise, create the table and add the new data


その他のヘルプ・トピック:

  MDB COPY EXAMPLES

  MDB COPY SYNTAX


SQL> 


mdb copyを実行したときに作成される表名には、MDBファイルに含まれている表の名前がそのまま使用されます。データベースの同じスキーマに複数のMDBファイルをインポートすることもあり得るため、prefixを指定してcopyを実行します。

SQL> mdb copy -prefix mdb_ -file Northwind.MDB

Alphabetical List of Products has been inserted

Catalog has been inserted

Category Sales for 1995 has been inserted

Current Product List has been inserted

Customers and Suppliers by City has been inserted

Employee Sales by Country has been inserted

Invoices has been inserted

Invoices Filter has been inserted

Order Details Extended has been inserted

Order Subtotals has been inserted

Orders Qry has been inserted

Product Sales for 1995 has been inserted

Products Above Average Price has been inserted

Products by Category has been inserted

Quarterly Orders has been inserted

Quarterly Orders by Product has been inserted

Sales by Category has been inserted

Sales by Year has been inserted

Sales Totals by Amount has been inserted

Summary of Sales by Quarter has been inserted

Summary of Sales by Year has been inserted

Ten Most Expensive Products has been inserted

Tables has been successfully copied

SQL> 


作成された表を確認します。

SQL> select table_name from user_tables where table_name like 'MDB%' order by 1;


TABLE_NAME           

____________________ 

MDB_CATEGORIES       

MDB_CUSTOMERS        

MDB_EMPLOYEES        

MDB_ORDERS           

MDB_ORDER_DETAILS    

MDB_PRODUCTS         

MDB_SHIPPERS         

MDB_SUPPLIERS        

MDB__VIEWS_TABLE     


9行が選択されました。 


SQL> 


MDB_ORDERSを例にとって、作成された表のDDLを確認してみます。

ORDERIDが主キーの扱いですが、表MDB_ORDERDSとしては主キー制約は付いていません。また、順序とトリガーを使って値の生成を行っています。
  CREATE TABLE "MDB_ORDERS" 
   (	"ORDERID" NUMBER(10,0) NOT NULL ENABLE, 
	"CUSTOMERID" VARCHAR2(5 CHAR), 
	"EMPLOYEEID" NUMBER(10,0), 
	"ORDERDATE" TIMESTAMP (6), 
	"REQUIREDDATE" TIMESTAMP (6), 
	"SHIPPEDDATE" TIMESTAMP (6), 
	"SHIPVIA" NUMBER(10,0), 
	"FREIGHT" NUMBER(38,2), 
	"SHIPNAME" VARCHAR2(40 CHAR), 
	"SHIPADDRESS" VARCHAR2(60 CHAR), 
	"SHIPCITY" VARCHAR2(15 CHAR), 
	"SHIPREGION" VARCHAR2(15 CHAR), 
	"SHIPPOSTALCODE" VARCHAR2(10 CHAR), 
	"SHIPCOUNTRY" VARCHAR2(15 CHAR)
   ) ;

  CREATE OR REPLACE EDITIONABLE TRIGGER "MDB_ORDERS_ORDERID_TRIG" BEFORE INSERT OR UPDATE ON mdb_Orders
FOR EACH ROW
DECLARE 
v_newVal NUMBER(12) := 0;
v_incval NUMBER(12) := 0;
BEGIN
  IF INSERTING AND :new.OrderID IS NULL THEN
    SELECT  mdb_Orders_OrderID_SEQ.NEXTVAL INTO v_newVal FROM DUAL;
    -- If this is the first time this table have been inserted into (sequence == 1)
    IF v_newVal = 1 THEN 
      --get the max indentity value from the table
      SELECT NVL(max(OrderID),0) INTO v_newVal FROM mdb_Orders;
      v_newVal := v_newVal + 1;
      --set the sequence to that value
      LOOP
           EXIT WHEN v_incval>=v_newVal;
           SELECT mdb_Orders_OrderID_SEQ.nextval INTO v_incval FROM dual;
      END LOOP;
    END IF;
   -- assign the value from the sequence to emulate the identity column
   :new.OrderID := v_newVal;
  END IF;
END;
/
ALTER TRIGGER "MDB_ORDERS_ORDERID_TRIG" ENABLE;
表MDB_ORDER_DETAILSを確認します。以下のDDLで表が作成されています。主キーの設定がなく、また、列ORDERIDや列PRODUCTIDに外部キーが設定されていません。
  CREATE TABLE "MDB_ORDER_DETAILS" 
   (	"ORDERID" NUMBER(10,0) NOT NULL ENABLE, 
	"PRODUCTID" NUMBER(10,0) NOT NULL ENABLE, 
	"UNITPRICE" NUMBER(38,2) NOT NULL ENABLE, 
	"QUANTITY" NUMBER(10,0) NOT NULL ENABLE, 
	"DISCOUNT" NUMBER(38,0) NOT NULL ENABLE
   ) ;
Microsoft Accessでも主キーや外部キーは設定できるはずなので、インポートしたNorthwind.MDBに設定されていないのか、SQLclでは主キーや外部キーの設定が反映されないのか不明です。

Microsoft Accessを持っていないのと、持っていたとしてもMacでは実行できないので、確認のしようがないのですが、Oracle APEXがフォームやレポートを生成するに当たって、主キーと外部キーの設定は重要です。

そのため、以下のコマンドを実行して、とりあえず主キー制約と外部キー制約を追加します。
alter table mdb_customers modify customerid primary key;
alter table mdb_employees modify employeeid primary key;
alter table mdb_orders modify orderid primary key;
alter table mdb_products modify productid primary key;
alter table mdb_shippers modify shipperid primary key;
alter table mdb_suppliers modify supplierid primary key;
alter table mdb_orders add constraint mdb_orders_fk1 foreign key(customerid) references mdb_customers(customerid);
alter table mdb_orders add constraint mdb_orders_fk2 foreign key(employeeid) references mdb_employees(employeeid);
alter table mdb_order_details add constraint mdb_order_details_fk1 foreign key(orderid) references mdb_orders(orderid);
alter table mdb_order_details add constraint mdb_order_details_fk2 foreign key(productid) references mdb_products(productid);
以上で、インポートしたデータを元にAPEXのアプリケーションを作成してみます。

今回は、生成AIを使用してアプリケーションを作成します。


APEXアシスタントに以下のプロンプトを与えます。

「表名がMDBで始まる表をソースとして、販売管理アプリケーションを作成してください。」

SQLclによるMDBファイルのインポートの対象は表やデータで、Accessのアプリケーション自体はインポートされません。そのため、アプリケーションは作り直す必要があります。しかし、Accessのアプリケーション自体はすでに作成できているので、生成AIにたいしてどのようなアプリケーションを作成して欲しいか、より具体的なプロンプトが与えられるでしょう。


APEXアシスタントから、アプリケーションについて提案されました。これで、アプリケーション作成を実行します。


アプリケーション作成ウィザードが起動します。

アプリケーションの作成を実行します。


アプリケーションが作成されます。


プロンプトとしてはNorthwind.MDBからインポートした表を使って、というのと、アプリケーション名は販売管理システムにして、というだけの指定で以下ようなアプリケーションができています。


今回の記事は以上になります。