diff --git a/23cfree/apex-property-graphs/apex-property-graphs.md b/23cfree/apex-property-graphs/apex-property-graphs.md index 3e729f12c..234e04d2e 100644 --- a/23cfree/apex-property-graphs/apex-property-graphs.md +++ b/23cfree/apex-property-graphs/apex-property-graphs.md @@ -99,29 +99,33 @@ This lab assumes: ![Install the application](images/install-application.png) -8. Click Run Application. - ![Run the application](images/run-application.png) +8. Click Install Supporting Objects. + + ![Install supporting objects](images/install-supporting-objects.png) +9. Click Run Application. + + ![Run the application](images/run-application.png) -9. Login. +10. Login. **NOTE:** admin is case-sensitive. ![Log back in](images/login-final.png) -10. Click Property Graph queries with SQL box. +11. Click Property Graph queries with SQL box. ![Property graph queries selection](images/property-graph-queries.png) -11. Scroll through output to see the queries that you had ran in the prior lab visualized. +12. Scroll through output to see the queries that you had ran in the prior lab visualized. ![Final scroll through the output](images/final-output.png) -12. Click the hamburger menu in the upper left corner of the application and click "Using the Graph Visualization Plugin". +13. Click the hamburger menu in the upper left corner of the application and click "Using the Graph Visualization Plugin". -13. Scroll through the output to see the Graph Viz plugin utilized. +14. Scroll through the output to see the Graph Viz plugin utilized. ![Graph viz](images/graph-viz.png) -14. You have now completed this lab. +15. You have now completed this lab. ## Learn More * [Oracle Property Graph](https://docs.oracle.com/en/database/oracle/property-graph/index.html) diff --git a/23cfree/apex-property-graphs/images/install-supporting-objects.png b/23cfree/apex-property-graphs/images/install-supporting-objects.png new file mode 100644 index 000000000..aa9f46041 Binary files /dev/null and b/23cfree/apex-property-graphs/images/install-supporting-objects.png differ diff --git a/23cfree/apex-property-graphs/images/run-application.png b/23cfree/apex-property-graphs/images/run-application.png index 2fb6fc347..8dba2a248 100644 Binary files a/23cfree/apex-property-graphs/images/run-application.png and b/23cfree/apex-property-graphs/images/run-application.png differ diff --git a/23cfree/property-graphs-setup/images/connect.png b/23cfree/property-graphs-setup/images/connect.png new file mode 100644 index 000000000..b655422d4 Binary files /dev/null and b/23cfree/property-graphs-setup/images/connect.png differ diff --git a/23cfree/property-graphs-setup/images/create-connection.png b/23cfree/property-graphs-setup/images/create-connection.png new file mode 100644 index 000000000..3cd595344 Binary files /dev/null and b/23cfree/property-graphs-setup/images/create-connection.png differ diff --git a/23cfree/property-graphs-setup/images/new-db-connection.png b/23cfree/property-graphs-setup/images/new-db-connection.png new file mode 100644 index 000000000..b18648990 Binary files /dev/null and b/23cfree/property-graphs-setup/images/new-db-connection.png differ diff --git a/23cfree/property-graphs-setup/property-graphs-setup.md b/23cfree/property-graphs-setup/property-graphs-setup.md index 770a0aa8e..6a6c6cb9a 100644 --- a/23cfree/property-graphs-setup/property-graphs-setup.md +++ b/23cfree/property-graphs-setup/property-graphs-setup.md @@ -82,11 +82,13 @@ This lab assumes you have: ![Command to start SQL](images/startup-sql.png) -2. On the left side menu, you'll see hol23c_freepdb1 underneath Oracle Connections. Double click it to open the connection. +2. On the left side menu, you'll see hol23c_freepdb1 underneath Oracle Connections. Double click it to open the connection. + >**Note:** If you do **not** see the hol23c_freepdb1 connection available on the menu, please complete Task 3: Add the user connection and then go to step 4. ![Open the connection](images/hol23c-connection.png) + 3. Fill out the connection information with your password. The default password we will be using throughout this lab is Welcome123. If you have changed yours, please use that one. After you click okay, you should be connected to your user. ![Login information](images/login-connection.png) @@ -117,8 +119,19 @@ This lab assumes you have: 10. Your schema setup is now complete. +## (Optional) Task 3: Add the user connection + +1. If you do not already have the hol23c_freepdb1 connection, then click the box that says 'Create a Connection Manually'. + + ![Create a connection manually](images/create-connection.png) + +2. Fill out the fields inside of the box to match this image exactly. Make sure that the password you fill out is what you set it to for the user in Lab 1. To ensure it works, click the 'Test' button and ensure it says 'Status: Success' in the bottom left corner. + + ![Test connection](images/new-db-connection.png) +3. Click 'Connect'. + ![Connect](images/connect.png) ## Learn More * [Oracle Property Graph](https://docs.oracle.com/en/database/oracle/property-graph/index.html) diff --git a/23cfree/property-graphs/images/run-script-icon.png b/23cfree/property-graphs/images/run-script-icon.png new file mode 100644 index 000000000..20c416c90 Binary files /dev/null and b/23cfree/property-graphs/images/run-script-icon.png differ diff --git a/23cfree/property-graphs/property-graphs.md b/23cfree/property-graphs/property-graphs.md index 341f5c24b..c1be948fb 100644 --- a/23cfree/property-graphs/property-graphs.md +++ b/23cfree/property-graphs/property-graphs.md @@ -41,7 +41,7 @@ Watch the video below for a quick walk-through of the lab. ## Task 1 : Define a graph view on these tables -1. In your SQL Developer window, click on the tab named hol23c_freepdb1, not the CreateKeys.sql tab that you are currently in. +1. In your SQL Developer window, click on the tab named hol23c_freepdb1 or hol23c, not the CreateKeys.sql tab that you are currently in. ![Open hol23c tab](images/sql-hol23-tab.png) ​ @@ -244,7 +244,9 @@ A common query in analyzing money flows is to see if there is a sequence of tran ​ Now, let's insert some more data into BANK\_TRANSFERS. We will see that when rows are inserted in to the BANK\_TRANSFERS table, the BANK\_GRAPH is updated with corresponding edges. - Run this + Run this by clicking the button to run the entire script, instead of the green play button. + + ![Run script icon](images/run-script-icon.png) ``` @@ -295,6 +297,8 @@ A common query in analyzing money flows is to see if there is a sequence of tran 12. So let’s insert more transfers which create some circular payment chains. We will be adding transfers from accounts **599**, **982**, and **407** into account **39**. + + Run this by clicking the button to run the entire script, instead of the green play button. ``` diff --git a/23cfree/sql-extended/sql-extended.md b/23cfree/sql-extended/sql-extended.md index 5f4dfe6f3..06eb210f7 100644 --- a/23cfree/sql-extended/sql-extended.md +++ b/23cfree/sql-extended/sql-extended.md @@ -28,11 +28,13 @@ This lab assumes you have: SELECT name FROM race where race_id = 204; - INSERT INTO race_dv VALUES ('{"raceId" : 204, - "name" : "Miami Grand Prix", - "laps" : 57, - "date" : "2022-05-08T00:00:00", - "podium" : {}}'); + + INSERT INTO race_dv VALUES ('{"_id" : 204, + "name" : "Miami Grand Prix", + "laps" : 57, + "date" : "2022-05-08T00:00:00", + "podium" : {}}'); + SELECT name FROM race where race_id = 204; @@ -43,13 +45,13 @@ This lab assumes you have: ``` SELECT json_serialize(data PRETTY) - FROM race_dv WHERE json_value(data, '$.raceId') = 205; + FROM race_dv WHERE json_value(data, '$._id') = 205; INSERT INTO race VALUES(205, 'Japanese Grand Prix', 53, TO_DATE('2022-10-08','YYYY-MM-DD'), '{}'); SELECT json_serialize(data PRETTY) - FROM race_dv WHERE json_value(data, '$.raceId') = 205; + FROM race_dv WHERE json_value(data, '$._id') = 205; ``` ![Image alt text](images/task_1_2.png " ") @@ -62,7 +64,7 @@ This lab assumes you have: SELECT json_serialize(data PRETTY) - FROM race_dv WHERE json_value(data, '$.raceId') = 204; + FROM race_dv WHERE json_value(data, '$._id') = 204; UPDATE race SET name = 'Miami Grand Prix', @@ -80,7 +82,7 @@ This lab assumes you have: COMMIT; SELECT json_serialize(data PRETTY) - FROM race_dv WHERE json_value(data, '$.raceId') = 204; + FROM race_dv WHERE json_value(data, '$._id') = 204; ``` @@ -91,7 +93,7 @@ This lab assumes you have: ``` SELECT json_serialize(data PRETTY) - FROM race_dv WHERE json_value(data, '$.raceId') = 205; + FROM race_dv WHERE json_value(data, '$._id') = 205; ``` ![Image alt text](images/task_2_2.png " ") @@ -104,7 +106,7 @@ This lab assumes you have: UPDATE race_dv SET data = ('{"_metadata": {"etag" : "BECAB2B6E186FEFB59EBD977418BA26F"}, - "raceId" : 205, + "_id" : 205, "name" : "Japanese Grand Prix", "laps" : 53, "date" : "2022-03-20T00:00:00", @@ -127,13 +129,9 @@ This lab assumes you have: "position" : 3, "driverId" : 104, "name" : "Carlos Sainz Jr"}]}') - WHERE json_value(data, '$.raceId') = 205; - + WHERE json_value(data, '$._id') = 205; COMMIT; - - SELECT name, race_date FROM race where race_id = 205; - SELECT race_id, driver_id, position from driver_race_map where race_id = 205; ``` ![Image alt text](images/task_2_3.png " ") @@ -143,7 +141,10 @@ This lab assumes you have: 1. We're going to delete a couple entries, but we want to see the current state of these tables first. Copy the code below and click **Run Script**. ``` - SELECT json_serialize(data PRETTY) FROM race_dv WHERE json_value(data, '$.raceId') = 204; + SELECT name, race_date FROM race where race_id = 205; + SELECT race_id, driver_id, position from driver_race_map where race_id = 205; + + SELECT json_serialize(data PRETTY) FROM race_dv WHERE json_value(data, '$._id') = 204; SELECT json_serialize(data PRETTY) FROM driver_dv WHERE json_value(data, '$.race.raceId') = 204; SELECT * FROM race where race_id = 204; @@ -171,7 +172,7 @@ This lab assumes you have: ``` - SELECT json_serialize(data PRETTY) FROM race_dv WHERE json_value(data, '$.raceId') = 204; + SELECT json_serialize(data PRETTY) FROM race_dv WHERE json_value(data, '$._id') = 204; SELECT json_serialize(data PRETTY) FROM driver_dv WHERE json_value(data, '$.race.raceId') = 204; SELECT * FROM race where race_id = 204; @@ -184,13 +185,14 @@ This lab assumes you have: ``` - SELECT json_serialize(data PRETTY) FROM race_dv WHERE json_value(data, '$.raceId') = 205; + + SELECT json_serialize(data PRETTY) FROM race_dv WHERE json_value(data, '$._id') = 205; SELECT json_serialize(data PRETTY) FROM driver_dv WHERE json_value(data, '$.race.raceId') = 205; SELECT * FROM race where race_id = 205; - DELETE FROM race_dv dv WHERE dv.data.raceId = 205; + DELETE FROM race_dv dv WHERE dv.data."_id" = 205; - SELECT json_serialize(data PRETTY) FROM race_dv WHERE json_value(data, '$.raceId') = 205; + SELECT json_serialize(data PRETTY) FROM race_dv WHERE json_value(data, '$._id') = 205; SELECT json_serialize(data PRETTY) FROM driver_dv WHERE json_value(data, '$.race.raceId') = 205; SELECT * FROM race where race_id = 205; diff --git a/23cfree/sql-json/sql-json.md b/23cfree/sql-json/sql-json.md index 6c6d434ea..8247ea49a 100644 --- a/23cfree/sql-json/sql-json.md +++ b/23cfree/sql-json/sql-json.md @@ -30,7 +30,7 @@ This lab assumes you have: ``` SELECT json_serialize(data PRETTY) - FROM race_dv WHERE json_value(data, '$.raceId') = 201; + FROM race_dv WHERE json_value(data, '$._id') = 201; ``` @@ -50,7 +50,7 @@ This lab assumes you have: UPDATE race_dv SET data = ('{"_metadata": {"etag" : "2E8DC09543DD25DC7D588FB9734D962B"}, - "raceId" : 201, + "_id" : 201, "name" : "Bahrain Grand Prix", "laps" : 57, "date" : "2022-03-20T00:00:00", @@ -77,8 +77,8 @@ This lab assumes you have: "position" : 4, "driverId" : 105, "name" : "George Russell"} ]}') - WHERE json_value(data, '$.raceId') = 201; - + WHERE json_value(data, '$._id') = 201; + COMMIT; ``` @@ -88,7 +88,7 @@ This lab assumes you have: ``` SELECT json_serialize(data PRETTY) - FROM race_dv WHERE json_value(data, '$.raceId') = 201; + FROM race_dv WHERE json_value(data, '$._id') = 201; ``` ![Image alt text](images/task_2_3.png " ") @@ -143,7 +143,7 @@ Switch Charles Leclerc's and George Russell's teams. This can be done by updatin UPDATE team_dv dv SET data = ('{_metadata : {"etag" : "855840B905C8CAFA99FB9CBF813992E5"}, - "teamId" : 2, + "_id" : 2, "name" : "Mercedes", "points" : 40, "driver" : [ {"driverId" : 106, @@ -156,7 +156,7 @@ Switch Charles Leclerc's and George Russell's teams. This can be done by updatin UPDATE team_dv dv SET data = ('{_metadata : {"etag" : "DA69DD103E8BAE95A0C09811B7EC9628"}, - "teamId" : 302, + "_id" : 302, "name" : "Ferrari", "points" : 30, "driver" : [ {"driverId" : 105, @@ -207,7 +207,7 @@ Switch Charles Leclerc's and George Russell's teams. This can be done by updatin UPDATE driver_dv dv SET DATA = ('{_metadata : {"etag" : "FCD4CEC63897F60DEA1EC2F64D3CE53A"}, - "driverId" : 103, + "_id" : 103, "name" : "Charles Leclerc", "points" : 25, "teamId" : 2, @@ -222,7 +222,7 @@ Switch Charles Leclerc's and George Russell's teams. This can be done by updatin } ] }') - WHERE dv.data.driverId = 103; + WHERE dv.data."_id" = 103; ``` ![Image alt text](images/task_5_1.png " ") @@ -235,7 +235,7 @@ Switch Charles Leclerc's and George Russell's teams. This can be done by updatin ``` - DELETE FROM race_dv dv WHERE dv.data.raceId = 201; + DELETE FROM race_dv dv WHERE dv.data."_id" = 201; SELECT json_serialize(data PRETTY) FROM race_dv; SELECT json_serialize(data PRETTY) FROM driver_dv; diff --git a/23cfree/sql-schema/sql-schema.md b/23cfree/sql-schema/sql-schema.md index 752f2a8e1..8b256ba0f 100644 --- a/23cfree/sql-schema/sql-schema.md +++ b/23cfree/sql-schema/sql-schema.md @@ -154,7 +154,8 @@ Note: The script uses the new 23c syntax of if exists and if not exists. This pr ``` CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW race_dv AS - SELECT JSON {'raceId' IS r.race_id, + SELECT JSON { + '_id' IS r.race_id, 'name' IS r.name, 'laps' IS r.laps WITH NOUPDATE, 'date' IS r.race_date, @@ -179,7 +180,7 @@ Note: The script uses the new 23c syntax of if exists and if not exists. This pr ``` CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW driver_dv AS - SELECT JSON {'driverId' IS d.driver_id, + SELECT JSON {'_id' IS d.driver_id, 'name' IS d.name, 'points' IS d.points, UNNEST @@ -207,7 +208,7 @@ Note: The script uses the new 23c syntax of if exists and if not exists. This pr ``` CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW team_dv AS - SELECT JSON {'teamId' IS t.team_id, + SELECT JSON {'_id' IS t.team_id, 'name' IS t.name, 'points' IS t.points, 'driver' IS @@ -227,17 +228,17 @@ Note: The script uses the new 23c syntax of if exists and if not exists. This pr ``` - INSERT INTO team_dv VALUES ('{"teamId" : 301, - "name" : "Red Bull", - "points" : 0, - "driver" : [ {"driverId" : 101, + INSERT INTO team_dv VALUES ('{"_id" : 301, + "name" : "Red Bull", + "points" : 0, + "driver" : [ {"driverId" : 101, "name" : "Max Verstappen", "points" : 0}, - {"driverId" : 102, + {"driverId" : 102, "name" : "Sergio Perez", "points" : 0} ]}'); - INSERT INTO team_dv VALUES ('{"teamId" : 302, + INSERT INTO team_dv VALUES ('{"_id" : 302, "name" : "Ferrari", "points" : 0, "driver" : [ {"driverId" : 103, @@ -247,7 +248,7 @@ Note: The script uses the new 23c syntax of if exists and if not exists. This pr "name" : "Carlos Sainz Jr", "points" : 0} ]}'); - INSERT INTO team_dv VALUES ('{"teamId" : 2, + INSERT INTO team_dv VALUES ('{"_id" : 2, "name" : "Mercedes", "points" : 0, "driver" : [ {"driverId" : 105, @@ -265,19 +266,19 @@ Note: The script uses the new 23c syntax of if exists and if not exists. This pr ``` - INSERT INTO race_dv VALUES ('{"raceId" : 201, + INSERT INTO race_dv VALUES ('{"_id" : 201, "name" : "Bahrain Grand Prix", "laps" : 57, "date" : "2022-03-20T00:00:00", "podium" : {}}'); - INSERT INTO race_dv VALUES ('{"raceId" : 202, + INSERT INTO race_dv VALUES ('{"_id" : 202, "name" : "Saudi Arabian Grand Prix", "laps" : 50, "date" : "2022-03-27T00:00:00", "podium" : {}}'); - INSERT INTO race_dv VALUES ('{"raceId" : 203, + INSERT INTO race_dv VALUES ('{"_id" : 203, "name" : "Australian Grand Prix", "laps" : 58, "date" : "2022-04-09T00:00:00", diff --git a/mds-intro/enabledbm/enabledbm.md b/mds-intro/enabledbm/enabledbm.md new file mode 100644 index 000000000..d44871f63 --- /dev/null +++ b/mds-intro/enabledbm/enabledbm.md @@ -0,0 +1,171 @@ +# Introduction + +In this lab, you will learn how to enable Database Management for MySQL HeatWave on Oracle Cloud Infrastructure (OCI) and use it to monitor your DB system performance. + +Estimated Time: 15 minutes + +### About Database Management for MySQL HeatWave +Database Management for MySQL HeatWave is a free service to monitor and manage your database environment deployments, it provides a single-pane-of-glass view of your MySQL HeatWave deployments for quickly assessing top resource utilization as well as alarm status for your entire fleet. + +Here are some of the tasks you can perform using Database Management, which are categorized under database monitoring and management areas. + +* **Fleet Monitoring** + * Obtain an overview of your fleet of MySQL HeatWave systems + * View inventory configuration and monitoring status of your fleet + * View a consolidated resource usage among all deployments + * View open alarms for your deployments + +* **Performance Diagnostics** + * Diagnose database system performance quickly + * Explore database performance utilizing metrics and Performance Hub + * View alerts for non-optimized queries + +* **Database Administration** + * View configuration variables for the MySQL database system + + +### Objectives + +In this lab, you will be guided through the following steps: + +* Verify if Database Management service is enabled for your MySQL HeatWave DB system (enable it if not) +* Manage MySQL HeatWave Database Service + +## Prerequisites + +* An Oracle Free Tier, Always Free, Paid or LiveLabs Cloud Account +* An active MySQL HeatWave Service DB System + +## Task 1: Verify Database Management is enabled for MySQL HeatWave + +By default, the service is enabled during the provisioning of your MySQL HeatWave deployment, but you can enable the service from the MySQL HeatWave DB system details page if not already enabled. Once enabled, you will have additional monitoring capabilities including a fleet overview of your MySQL HeatWave deployments and Performance Hub monitoring for database systems. + +1. Log in to the Oracle Cloud Console, click the **Navigation Menu** in the upper left, navigate to **Databases**, and select **DB Systems** under MySQL HeatWave + ![Database Systems](https://oracle-livelabs.github.io/common/images/console/database-dbsys.png "Database Systems") + +2. In the DB systems section, select **HeatWave_DB**. + ![Database list](./images/mysql-list.png "DB System list") + +3. Verify Database Management is enabled in the Associated services section of the DB system information. + + **If already enabled, proceed to the next task** + ![Verify database management](./images/dbsystem-details.png "Verify Database Management") + +4. If Database Management is **not enabled**, click on the **Enable** link to launch the enablement window. + + ![Enable database management](./images/enable-dbm.png "Enable Database Management") + +5. Click on the **enable** button. + ![Confirm database management](./images/confirm-enable-dbm.png "ConfirmDatabase Management") + + +## Task 2: Overview of MySQL Database Management + +1. Click the **Navigation Menu** in the upper left, navigate to **Observability & Management**, and select **Overview under Database Management** + ![Select Database Management menu](./images/menu-dbm.png "Select Database Management menu") + +2. The MySQL databases (on the Overview page) displays the total number of MySQL HeatWave deployments in the compartment and the number of MySQL HeatWave deployments for which Database Management is **enabled** + ![Overview Database Management](./images/overview-dbm.png "Overview Database Management") + + + +## Task 3: Database Management for MySQL HeatWave fleet summary + +1. On the left pane, click **MySQL HeatWave** to navigate to the MySQL HeatWave fleet summary page. + + ![Select MySQL HeatWave](./images/select-dbm-fleet.png "Select MySQL HeatWave") + + The following tiles are available on the fleet summary page: + * **Inventory:** Displays the number of MySQL HeatWave systems in the compartment and enables quick assessment of version disparity between the monitored systems. + * **Monitoring status:** Displays the monitoring status of the MySQL HeatWave systems. The overall health of your systems can be seen here. + * **Resource usage:** Displays a summary of the overall CPU, storage, and memory utilization of all deployed and monitored HeatWave systems. + * **Alarms:** Displays all open alarms in your monitored MySQL HeatWave systems. You can view more granular details on the alarms by clicking the link. + * **MySQL HeatWave system:** A table listing top individual statistics for a monitored HeatWave system. You can assess the overall resource utilization and health of your environment at a glance. The table provides a search feature as well as sortable columns to find systems consuming the most resources. + + ![MySQL HeatWave Fleet](./images/dbm-mysql-fleet.png "MySQL HeatWave Fleet") + + +## Task 4: Monitor a single MySQL HeatWave instance +1. Select **HeatWave_DB** from the list of monitored deployments. + ![Fleet Summary](./images/dbm-mysql-select.png "Fleet Summary") + + * **MySQL database information section** : We can view information for the MySQL HeatWave DB system as well as associated alarms. The alarms section allows drill down to specific errors to quickly resolve any issues that may be occurring within your database. + ![Fleet Summary](./images/fleet-summary.png "Fleet Summary") + + * **Summary section**: We can monitor database performance attributes for the time period selected in the Time period menu on the top of this page. Last 60 min is the default time period, and the visual representations or charts provide a quick insight into the health of the database system during the selected time period. + + * **Monitoring status timeline**: Shows if Database Management can collect monitoring metrics for the resource. The Monitoring stopped status indicates metric collection issues caused by network, connection, missing data, or that a resource is down. + + * **Top metric charts**: Key metrics are provided in a single group of charts in the summary section to quickly assess the overall health of your DB system. Resource charts can be toggled between utilization and usage to provide additional granularity. + + ![Fleet Summary Sections](./images/fleet-summary-sections.png "Fleet Summary Sections") + +2. On the left pane, click **All metrics** section + ![Select all metrics](./images/all-metrics-select.png "Select all metrics") + + Here, you can monitor a wide range of key MySQL database metrics across areas to proactively investigate and identify the root cause of performance issues. The charts in this section include those displayed in the Summary section and other metric charts. + +3. In addition to the charts displayed in this section, you can select other metric charts from the Select charts drop-down list for an in-depth examination using different indicators. Click the **Select charts** button + + ![Select metrics charts](./images/all-metrics-select-charts.png "Select metrics charts") + + +3. Here, you can toggle which metrics to include in the console. + ![Select metrics charts](./images/metric-charts-select.png "Select metrics charts") + +4. On the left pane, click **Configuration Variables** section + + Here, you can monitor the configuration variables that are **currently used** by the MySQL database. + ![Select Config Variables Section](./images/config-var-select.png "Select Config Variables Section") + + * **Note:** Configuration variables are the user, system, initialization, or service-specific variables that define the operation of a MySQL DB system. The Configuration variables section provides the details of the variables and the option of navigating to the MySQL HeatWave service to edit the variables if required. + +4. You can filter and sort the configuration variables based on **source**, **dynamic property**, or **configuration details** utilizing filters in the Filters section + ![Config Variables Section](./images/config-var.png "Config Variables Section") + +## Task 5: Realtime Performance Diagnosis +1. On the top of the **HeatWave_DB** details page, click the **Performance Hub** button. + ![Select Performance Hub](./images/hub-select.png "Select Performance Hub") + +2. This will launch the Performance Hub page. + * Performance Hub provides a single view of the DB system’s performance and enables you to perform a rapid diagnosis of its issues. + * It provides holistic performance management capabilities providing a single view of the database performance using a varied set of features, such as Active statement latency, statement count charts, top 100 queries sorted by metrics, and the ability to drill down into specific SQL details. + * Additional details for SQL statements include SQL text, execution statistics, row information, temporary table usage, and select and sort counts. + * It enables developers and DBAs to quickly improve the performance of their database applications by monitoring query performance. Accurately pinpoint the SQL code that is causing a slowdown by making use of the rich graphs that drill down into detailed query information, thereby providing significantly better visibility into database performance issues. With Performance Hub, developers can improve SQL code during active development as well as continuously monitor and tune queries running on production systems. + + ![Performancee Hub Page](./images/performance-hub.png "Performancee Hub Page") + +3. The default sorting for statements is Average statement latency. Click on the **top SQL** to see additional details on the query. + + ![Performancee Hub Select SQL](./images/performance-hub-select.png "Performancee Hub Select SQL") + + * SQL details provide in-depth metrics associated with a query, it consists of different sections: + + * **First and last seen times** provide more information on when a SQL was loaded into the database and narrows the scope of impact on the database. + ![Performancee Hub Select SQL](./images/last-seen.png "Performancee Hub Select SQL") + + * **Normalized SQL** displays the Full SQL text, to validate the query running against the database. + ![Performancee Hub Select SQL](./images/sql-text.png "Performancee Hub Select SQL") + + * **Execution time** provides key details into query performance over time and allows a DBA to see variability associated with a statements performance utilizing maximum/minimum run times and quantiles to compare execution length for all runs of the query + ![Performancee Hub Select SQL](./images/exec-time.png "Performancee Hub Select SQL") + + + * **Rows** provide work associated with the query + ![Performancee Hub Select SQL](./images/rows.png "Performancee Hub Select SQL") + + * **Executions** provide a total count of executions for a single query and their usage of indexes to retrieve the data. + ![Performancee Hub Select SQL](./images/exec.png "Performancee Hub Select SQL") + + * Additional tiles provide performance data to further analyze the overall performance for a single query and allows the DBA and developers tools to assess impact and tune query performance. + + + +## Acknowledgements + +- **Author** - Derik Harlow, MySQL Product Manager +- **Contributors** - Derik Harlow, MySQL Product Manager; Sriram Vrinda, MySQL Product Manager; Perside Foster, MySQL Solution Engineering; Selena Sánchez MySQL Solution Engineering +- **Last Updated By/Date** - Selena Sánchez, MySQL Solution Engineering, March 2024 + + + diff --git a/mds-intro/enabledbm/images/all-metrics-select-charts.png b/mds-intro/enabledbm/images/all-metrics-select-charts.png new file mode 100644 index 000000000..a5df3f102 Binary files /dev/null and b/mds-intro/enabledbm/images/all-metrics-select-charts.png differ diff --git a/mds-intro/enabledbm/images/all-metrics-select.png b/mds-intro/enabledbm/images/all-metrics-select.png new file mode 100644 index 000000000..8d4bbf2fa Binary files /dev/null and b/mds-intro/enabledbm/images/all-metrics-select.png differ diff --git a/mds-intro/enabledbm/images/config-var-select.png b/mds-intro/enabledbm/images/config-var-select.png new file mode 100644 index 000000000..18c85d89f Binary files /dev/null and b/mds-intro/enabledbm/images/config-var-select.png differ diff --git a/mds-intro/enabledbm/images/config-var.png b/mds-intro/enabledbm/images/config-var.png new file mode 100644 index 000000000..bf5656b35 Binary files /dev/null and b/mds-intro/enabledbm/images/config-var.png differ diff --git a/mds-intro/enabledbm/images/confirm-enable-dbm.png b/mds-intro/enabledbm/images/confirm-enable-dbm.png new file mode 100644 index 000000000..720a4da37 Binary files /dev/null and b/mds-intro/enabledbm/images/confirm-enable-dbm.png differ diff --git a/mds-intro/enabledbm/images/dbm-mysql-fleet.png b/mds-intro/enabledbm/images/dbm-mysql-fleet.png new file mode 100644 index 000000000..a8fc0c370 Binary files /dev/null and b/mds-intro/enabledbm/images/dbm-mysql-fleet.png differ diff --git a/mds-intro/enabledbm/images/dbm-mysql-select.png b/mds-intro/enabledbm/images/dbm-mysql-select.png new file mode 100644 index 000000000..704c07997 Binary files /dev/null and b/mds-intro/enabledbm/images/dbm-mysql-select.png differ diff --git a/mds-intro/enabledbm/images/dbsystem-details.png b/mds-intro/enabledbm/images/dbsystem-details.png new file mode 100644 index 000000000..62849e35f Binary files /dev/null and b/mds-intro/enabledbm/images/dbsystem-details.png differ diff --git a/mds-intro/enabledbm/images/enable-dbm.png b/mds-intro/enabledbm/images/enable-dbm.png new file mode 100644 index 000000000..546c7105a Binary files /dev/null and b/mds-intro/enabledbm/images/enable-dbm.png differ diff --git a/mds-intro/enabledbm/images/exec-time.png b/mds-intro/enabledbm/images/exec-time.png new file mode 100644 index 000000000..a2e21e6c5 Binary files /dev/null and b/mds-intro/enabledbm/images/exec-time.png differ diff --git a/mds-intro/enabledbm/images/exec.png b/mds-intro/enabledbm/images/exec.png new file mode 100644 index 000000000..3ef08541c Binary files /dev/null and b/mds-intro/enabledbm/images/exec.png differ diff --git a/mds-intro/enabledbm/images/fleet-summary-sections.png b/mds-intro/enabledbm/images/fleet-summary-sections.png new file mode 100644 index 000000000..a12e29134 Binary files /dev/null and b/mds-intro/enabledbm/images/fleet-summary-sections.png differ diff --git a/mds-intro/enabledbm/images/fleet-summary.png b/mds-intro/enabledbm/images/fleet-summary.png new file mode 100644 index 000000000..2f2f775a5 Binary files /dev/null and b/mds-intro/enabledbm/images/fleet-summary.png differ diff --git a/mds-intro/enabledbm/images/hub-select.png b/mds-intro/enabledbm/images/hub-select.png new file mode 100644 index 000000000..28de0e680 Binary files /dev/null and b/mds-intro/enabledbm/images/hub-select.png differ diff --git a/mds-intro/enabledbm/images/last-seen.png b/mds-intro/enabledbm/images/last-seen.png new file mode 100644 index 000000000..c31484d33 Binary files /dev/null and b/mds-intro/enabledbm/images/last-seen.png differ diff --git a/mds-intro/enabledbm/images/menu-dbm.png b/mds-intro/enabledbm/images/menu-dbm.png new file mode 100644 index 000000000..fb9bc474f Binary files /dev/null and b/mds-intro/enabledbm/images/menu-dbm.png differ diff --git a/mds-intro/enabledbm/images/metric-charts-select.png b/mds-intro/enabledbm/images/metric-charts-select.png new file mode 100644 index 000000000..2d1bebcac Binary files /dev/null and b/mds-intro/enabledbm/images/metric-charts-select.png differ diff --git a/mds-intro/enabledbm/images/mysql-list.png b/mds-intro/enabledbm/images/mysql-list.png new file mode 100644 index 000000000..286d9f5f4 Binary files /dev/null and b/mds-intro/enabledbm/images/mysql-list.png differ diff --git a/mds-intro/enabledbm/images/overview-dbm.png b/mds-intro/enabledbm/images/overview-dbm.png new file mode 100644 index 000000000..0fe8055fb Binary files /dev/null and b/mds-intro/enabledbm/images/overview-dbm.png differ diff --git a/mds-intro/enabledbm/images/performance-hub-select.png b/mds-intro/enabledbm/images/performance-hub-select.png new file mode 100644 index 000000000..baae3195e Binary files /dev/null and b/mds-intro/enabledbm/images/performance-hub-select.png differ diff --git a/mds-intro/enabledbm/images/performance-hub.png b/mds-intro/enabledbm/images/performance-hub.png new file mode 100644 index 000000000..d467de4b0 Binary files /dev/null and b/mds-intro/enabledbm/images/performance-hub.png differ diff --git a/mds-intro/enabledbm/images/rows.png b/mds-intro/enabledbm/images/rows.png new file mode 100644 index 000000000..fe4a95ec7 Binary files /dev/null and b/mds-intro/enabledbm/images/rows.png differ diff --git a/mds-intro/enabledbm/images/select-dbm-fleet.png b/mds-intro/enabledbm/images/select-dbm-fleet.png new file mode 100644 index 000000000..f14c83dc0 Binary files /dev/null and b/mds-intro/enabledbm/images/select-dbm-fleet.png differ diff --git a/mds-intro/enabledbm/images/sql-text.png b/mds-intro/enabledbm/images/sql-text.png new file mode 100644 index 000000000..f6e55c923 Binary files /dev/null and b/mds-intro/enabledbm/images/sql-text.png differ diff --git a/mds-intro/workshops/freetier/manifest.json b/mds-intro/workshops/freetier/manifest.json index 5e251fa03..15bce9f70 100644 --- a/mds-intro/workshops/freetier/manifest.json +++ b/mds-intro/workshops/freetier/manifest.json @@ -21,6 +21,10 @@ "title": "Lab 2: Create and connect to a MySQL Heatwave DB System", "filename": "../../launchmds/launchmds.md" }, + { + "title": "Lab 3: Enable and explore Database Management for MySQL Heatwave", + "filename": "../../enabledbm/enabledbm.md" + }, { "title": "Need Help?", "description": "Solutions to Common Problems and Directions for Receiving Live Help", diff --git a/serverless-with-nosql-database/setup-environment/setup-environment-green.md b/serverless-with-nosql-database/setup-environment/setup-environment-green.md index b9943c683..92ad09b28 100644 --- a/serverless-with-nosql-database/setup-environment/setup-environment-green.md +++ b/serverless-with-nosql-database/setup-environment/setup-environment-green.md @@ -105,9 +105,9 @@ Please make note of the **Region** you are assigned. If you are assigned Phoenix cd $HOME rm -rf serverless-with-nosql-database BaggageData serverless-with-nosql-database.zip demo-lab-nosql-main - curl https://c4u04.objectstorage.us-ashburn-1.oci.customer-oci.com/p/EcTjWk2IuZPZeNnD_fYMcgUhdNDIDA6rt9gaFj_WZMiL7VvxPBNMY60837hu5hga/n/c4u04/b/livelabsfiles/o/data-management-library-files/demo-lab-nosql-main.zip -o serverless-with-nosql-database.zip + curl https://c4u04.objectstorage.us-ashburn-1.oci.customer-oci.com/p/EcTjWk2IuZPZeNnD_fYMcgUhdNDIDA6rt9gaFj_WZMiL7VvxPBNMY60837hu5hga/n/c4u04/b/livelabsfiles/o/data-management-library-files/demo-lab-nosql.zip -o serverless-with-nosql-database.zip unzip serverless-with-nosql-database.zip - mv demo-lab-nosql-main serverless-with-nosql-database + mv demo-lab-nosql serverless-with-nosql-database cp ~/NoSQLLabPrivateKey.pem ~/serverless-with-nosql-database/express-nosql cp ~/serverless-with-nosql-database/env-livelab.sh ~/serverless-with-nosql-database/env.sh cd serverless-with-nosql-database diff --git a/serverless-with-nosql-database/setup-environment/setup-environment-paid.md b/serverless-with-nosql-database/setup-environment/setup-environment-paid.md index 77d2c11b9..758fe3745 100644 --- a/serverless-with-nosql-database/setup-environment/setup-environment-paid.md +++ b/serverless-with-nosql-database/setup-environment/setup-environment-paid.md @@ -27,7 +27,7 @@ This lab assumes you have: 1. Log into the Oracle Cloud Console using your tenancy. Please make note of what region you are at. ![Oracle Cloud Console](https://oracle-livelabs.github.io/common/images/console/home-page.png) - + 2. On left side drop down (left of Oracle Cloud banner), go to **Identity & Security** and then **Compartments.** ![Identity & Security](https://oracle-livelabs.github.io/common/images/console/id-compartment.png) @@ -81,9 +81,9 @@ In this task we will copy over a data bundle stored on object storage and place cd $HOME rm -rf serverless-with-nosql-database BaggageData serverless-with-nosql-database.zip demo-lab-nosql-main - curl https://c4u04.objectstorage.us-ashburn-1.oci.customer-oci.com/p/EcTjWk2IuZPZeNnD_fYMcgUhdNDIDA6rt9gaFj_WZMiL7VvxPBNMY60837hu5hga/n/c4u04/b/livelabsfiles/o/data-management-library-files/demo-lab-nosql-main.zip -o serverless-with-nosql-database.zip + curl https://c4u04.objectstorage.us-ashburn-1.oci.customer-oci.com/p/EcTjWk2IuZPZeNnD_fYMcgUhdNDIDA6rt9gaFj_WZMiL7VvxPBNMY60837hu5hga/n/c4u04/b/livelabsfiles/o/data-management-library-files/demo-lab-nosql.zip -o serverless-with-nosql-database.zip unzip serverless-with-nosql-database.zip - mv demo-lab-nosql-main serverless-with-nosql-database + mv demo-lab-nosql serverless-with-nosql-database cp ~/NoSQLLabPrivateKey.pem ~/serverless-with-nosql-database/express-nosql cp ~/info.json ~/serverless-with-nosql-database/express-nosql cp ~/serverless-with-nosql-database/env-freetier.sh ~/serverless-with-nosql-database/env.sh diff --git a/serverless-with-nosql-database/setup-environment/setup-environment.md b/serverless-with-nosql-database/setup-environment/setup-environment.md index 9549a0aef..5b2304acf 100644 --- a/serverless-with-nosql-database/setup-environment/setup-environment.md +++ b/serverless-with-nosql-database/setup-environment/setup-environment.md @@ -84,9 +84,9 @@ In this task we will copy over a data bundle stored on object storage and place cd $HOME rm -rf serverless-with-nosql-database BaggageData serverless-with-nosql-database.zip demo-lab-nosql-main - curl https://c4u04.objectstorage.us-ashburn-1.oci.customer-oci.com/p/EcTjWk2IuZPZeNnD_fYMcgUhdNDIDA6rt9gaFj_WZMiL7VvxPBNMY60837hu5hga/n/c4u04/b/livelabsfiles/o/data-management-library-files/demo-lab-nosql-main.zip -o serverless-with-nosql-database.zip + curl https://c4u04.objectstorage.us-ashburn-1.oci.customer-oci.com/p/EcTjWk2IuZPZeNnD_fYMcgUhdNDIDA6rt9gaFj_WZMiL7VvxPBNMY60837hu5hga/n/c4u04/b/livelabsfiles/o/data-management-library-files/demo-lab-nosql.zip -o serverless-with-nosql-database.zip unzip serverless-with-nosql-database.zip - mv demo-lab-nosql-main serverless-with-nosql-database + mv demo-lab-nosql serverless-with-nosql-database cp ~/NoSQLLabPrivateKey.pem ~/serverless-with-nosql-database/express-nosql cp ~/info.json ~/serverless-with-nosql-database/express-nosql cp ~/serverless-with-nosql-database/env-freetier.sh ~/serverless-with-nosql-database/env.sh diff --git a/xmldb/index/images/img-10.png b/xmldb/index/images/img-10.png index c7691fd76..81afdccea 100644 Binary files a/xmldb/index/images/img-10.png and b/xmldb/index/images/img-10.png differ diff --git a/xmldb/index/images/img-11.png b/xmldb/index/images/img-11.png index a332b5a07..41e57aa59 100644 Binary files a/xmldb/index/images/img-11.png and b/xmldb/index/images/img-11.png differ diff --git a/xmldb/index/images/img-12.png b/xmldb/index/images/img-12.png index 5f57bee93..cc7948053 100644 Binary files a/xmldb/index/images/img-12.png and b/xmldb/index/images/img-12.png differ diff --git a/xmldb/index/images/img-13.png b/xmldb/index/images/img-13.png index cd6073953..5530c3a0f 100644 Binary files a/xmldb/index/images/img-13.png and b/xmldb/index/images/img-13.png differ diff --git a/xmldb/index/images/img-3.png b/xmldb/index/images/img-3.png index 2d0345196..aed2dbfc7 100644 Binary files a/xmldb/index/images/img-3.png and b/xmldb/index/images/img-3.png differ diff --git a/xmldb/index/images/img-5.png b/xmldb/index/images/img-5.png index 5d0a32afa..b691c43e1 100644 Binary files a/xmldb/index/images/img-5.png and b/xmldb/index/images/img-5.png differ diff --git a/xmldb/index/images/img-6.png b/xmldb/index/images/img-6.png index c6cb0f16c..33baacdd7 100644 Binary files a/xmldb/index/images/img-6.png and b/xmldb/index/images/img-6.png differ diff --git a/xmldb/index/images/img-9.png b/xmldb/index/images/img-9.png index dab24d522..ac405c2af 100644 Binary files a/xmldb/index/images/img-9.png and b/xmldb/index/images/img-9.png differ diff --git a/xmldb/index/index.md b/xmldb/index/index.md index 9e41e6d1b..cafd89e6c 100644 --- a/xmldb/index/index.md +++ b/xmldb/index/index.md @@ -1,289 +1,238 @@ -# Index XML data +# Index your XML documents ## Introduction Indexing XML data will give you quick access to the data and significantly improve the query performance. The use of indexes is particularly recommended for online transaction processing (OLTP) environments involving few updates. -Generally, when your XML data contains an island of structured, predictable data and your queries are known, we recommend using XMLIndex with a structured component. When you need to support ad-hoc XML queries, range, or text search queries, we recommend using the XML Search index. In this lab, we will explore both XMLIndex and XML Search Index. +Generally, when your XML data contains structured, predictable fragments of data and your queries are known, we recommend using XMLIndex with a structured component. When you need to support ad-hoc XML queries, range, or text search queries, we recommend using the XML Search index. In this lab, we will explore both XMLIndex and XML Search Index. -Estimated Time: 45 minutes +Estimated Time: 20 minutes ### Objectives In this lab, you will learn: -- Using XMLIndex, -- Using XML Search Index. +- How to use Structured XMLIndex, +- How to use XML Search Index. ### Prerequisites -- Be logged into your Oracle Cloud Account. +- Be logged into your Oracle Cloud Account and have access to the SQL Worksheet in Database Actions. -## Task 1: Open Database Actions -1. Log in to the Oracle Cloud. -2. If you are using a Free Trial or Always Free account, and you want to use Always Free Resources, you need to be in a region where Always Free Resources are available. You can see your current default Region in the top, right-hand corner of the page. -3. Click the navigation menu in the upper left to show top-level navigation choices. -4. Click on Oracle Database and choose Autonomous Transaction Processing. -5. If using FreeTier, your compartment should be the root compartment for your tenancy. -Note: Avoid the use of the ManagedCompartmentforPaaS compartment as this is an Oracle default used for Oracle Platform Services. -6. You should see your database XMLDB listed in the center. Click on the database name "XMLDB". -7. On the database page, choose Database Actions. -8. You are now in Database Actions. -Database Actions allows you to connect to your Autonomous Database through various browser-based tools. We will just be using the SQL workshop tool. -9. You should be in the Database Actions panel. Click on the SQL card - -## Task 2: Index XML Data - -1. Create XMLIndex +## Task 1: Create and use structured XMLIndexes - Often times users know the structure or pattern of the queries. For example, consider the following few examples: - - ``` - - SELECT - XMLQUERY('/PurchaseOrder/LineItems/LineItem/@ItemNumber' - PASSING P.DOC - RETURNING CONTENT).GETCLOBVAL() - FROM - PURCHASEORDER P - WHERE - XMLEXISTS ( '/PurchaseOrder[Reference="ROY-1PDT"]' - PASSING P.DOC - ); - - ``` - - - ``` - - SELECT - XMLQUERY('/PurchaseOrder/LineItems/LineItem/Part/text()' - PASSING P.DOC - RETURNING CONTENT).GETCLOBVAL() - FROM - PURCHASEORDER P - WHERE - XMLEXISTS ( '/PurchaseOrder[Reference="ROY-1PDT"]' - PASSING P.DOC - ); - - ``` - - - All the queries use a similar pattern, and we can leverage that. Users can create an index focusing on those cases only. By doing that they will significantly reduce the index size and at the same time, we will get a significant performance improvement. - - ``` - - DROP INDEX PURCHASEORDER_IDX; - - BEGIN - DBMS_XMLINDEX.DROPPARAMETER('PO_SXI_PARAMETERS'); - END; - / - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![Drop index and parameters](./images/img-1.png) - - - - ``` - - BEGIN - DBMS_XMLINDEX.REGISTERPARAMETER('PO_SXI_PARAMETERS', 'GROUP PO_LINEITEM - XMLTABLE PO_INDEX_MASTER ''/PurchaseOrder'' +Often times users know the structure or pattern of the queries and consequently the fragments of their XML documents that are used for selective access. For example, consider the following few examples: + +``` + +SELECT + XMLQUERY('/PurchaseOrder/LineItems/LineItem/@ItemNumber' + PASSING P.DOC + RETURNING CONTENT).GETCLOBVAL() as ItemNumber +FROM + PURCHASEORDER P +WHERE + XMLEXISTS ('/PurchaseOrder[Reference="CJONES-2022PST"]' + PASSING P.DOC + ); + +``` + +``` + +CREATE OR REPLACE VIEW V_ORDERITEM AS + SELECT M.REFERENCE, L.* + FROM PURCHASEORDER P, + XMLTABLE ('/PurchaseOrder' PASSING P.DOC COLUMNS - REFERENCE varchar2(30) PATH ''Reference/text()'', - LINEITEM xmlType PATH ''LineItems/LineItem'' - VIRTUAL XMLTABLE PO_INDEX_LINEITEM ''/LineItem'' - PASSING lineitem + REFERENCE VARCHAR2(30) PATH 'Reference/text()', + LINEITEMS XMLTYPE PATH 'LineItems/LineItem') M, + XMLTABLE ('/LineItem' PASSING M.LINEITEMS COLUMNS - ITEMNO number(38) PATH ''@ItemNumber'', - UPC varchar2(14) PATH ''Part/text()'', - DESCRIPTION varchar2(256) PATH ''Part/@Description'' - '); - END; - / - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![Register parameters](./images/img-2.png) - - - - Please grant the required privileges if needed. - - ``` - - CREATE INDEX PURCHASEORDER_IDX ON - PURCHASEORDER ( - DOC - ) - INDEXTYPE IS XDB.XMLINDEX PARAMETERS ( 'PARAM PO_SXI_PARAMETERS' ); - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![Create index](./images/img-3.png) - - - - ``` - - -- we can even create a secondary index on primary index columns. - -- creating a secondary index on the REFERENCE column - CREATE UNIQUE INDEX REFERENCE_IDX ON - PO_INDEX_MASTER ( - REFERENCE - ); - - -- creating a secondary index on the UPC column - CREATE INDEX UPC_IDX ON - PO_INDEX_LINEITEM ( - UPC - ); - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![Secondary indexes](./images/img-4.png) - - - - - ``` - - SELECT - XMLQUERY('/PurchaseOrder/LineItems/LineItem/@ItemNumber' - PASSING P.DOC - RETURNING CONTENT).GETCLOBVAL() - FROM - PURCHASEORDER P - WHERE - XMLEXISTS ( '/PurchaseOrder[Reference="ROY-1PDT"]' - PASSING P.DOC - ); - - ``` - - Copy the above statement into the worksheet area and press "Explain Plan". - - ![Explain plan 1](./images/img-5.png) - - - - - ``` - - SELECT - XMLQUERY('/PurchaseOrder/LineItems/LineItem/Part/text()' - PASSING P.DOC - RETURNING CONTENT).GETCLOBVAL() - FROM - PURCHASEORDER P - WHERE - XMLEXISTS ( '/PurchaseOrder[Reference="ROY-1PDT"]' - PASSING P.DOC - ); - - ``` + ITEMNO NUMBER(38) PATH '@ItemNumber', + PARTNO VARCHAR2(14) PATH 'Part/@Id', + DESCRIPTION VARCHAR2(100) PATH 'Description', + QUANTITY NUMBER(5) PATH 'Quantity') L; + +``` + +The queries use a similar XPath to access /PurchaserOrder/Reference or /PurchaseOrder/LineItems/LineItem elements. We can create a structured XML index on these structured parts of the data. An XML index will also help the query performance significantly. + +Let us create a structured XML index for our sample table: +``` + +DROP INDEX PURCHASEORDER_IDX; + +CREATE INDEX PURCHASEORDER_IDX + ON purchaseorder(doc) INDEXTYPE IS XDB.XMLIndex + PARAMETERS (' + XMLTABLE PO_INDEX_MASTER + ''/PurchaseOrder'' + COLUMNS + reference VARCHAR2(30) PATH ''Reference/text()'', + lineitem XMLTYPE PATH ''LineItems/LineItem'' VIRTUAL + XMLTable PO_INDEX_LINEITEM + ''/LineItem'' PASSING lineitem + COLUMNS + ITEMNO number(38) PATH ''@ItemNumber'', + PARTNO varchar2(14) PATH ''Part/@Id'', + DESCRIPTION varchar2(30) PATH ''Description'', + QUANTITY NUMBER(5) PATH ''Quantity'' + '); + +``` +![Create index](./images/img-3.png) + +After you created the index, you will see an index PURCHASEORDER_IDX in your data dictionary, but you will also see two additional (structured) tables being created; those are so-called "path tables" that provide the structure for your XML index. You can describe them, however. + +The two internal XML index path tables PO\_INDEX\_MASTER and PO\_INDEX\_LINEITEM are named after the XMLTABLE parameters of your index creation statement. +- PO\_INDEX\_MASTER has columns reference and lineitem. Column lineitem is of type XMLTYPE which is virtual. It represents a collection and is passed to the second XMLTable construct to form the second-level relational index table, PO\_INDEX\_LINEITEM. +- PO\_INDEX\_LiNEITEM has columns itemno, partno, description, and quantity. + +Your queries are optimized through Structured XML Index directly from the underneath relational index tables. We will see this later in this lab. + +You can even create secondary indexes on the columns of these internal XML index tables, which will further improve the query performance. Let's do this now: +``` + +CREATE UNIQUE INDEX REFERENCE_IDX ON + PO_INDEX_MASTER ( + REFERENCE + ); + +-- creating a secondary index on the UPC column +CREATE INDEX UPC_IDX ON + PO_INDEX_LINEITEM ( + PARTNO + ); + +``` + +Copy the above statement into the worksheet area and press "Run Statement". + +![Secondary indexes](./images/img-4.png) + +Now let's see our indexes at work, using some sample queries. + +``` + +SELECT + XMLQUERY('/PurchaseOrder/LineItems/LineItem/@ItemNumber' + PASSING P.DOC + RETURNING CONTENT).GETCLOBVAL() +FROM + PURCHASEORDER P +WHERE + XMLEXISTS ( '/PurchaseOrder[Reference="CJONES-2022PST"]' + PASSING P.DOC + ); + +``` + +Copy the above statement into the worksheet area and press "Explain Plan". + +![Explain plan 1](./images/img-5.png) + +You will see that the access path is driven by our secondary index on /PurchaseOrder/Reference (index REFERENCE\_IDX on our path table PO\_INDEX\_MASTER) since we have a very selective predicate "REFERENCE"='CJONES-2022PST'. + +Now let's create a view and see what happens when I am just selecting from my view: +``` + +CREATE OR REPLACE VIEW V_ORDERITEM AS + SELECT M.REFERENCE, L.* + FROM PURCHASEORDER P, + XMLTABLE ('/PurchaseOrder' PASSING P.DOC + COLUMNS + REFERENCE VARCHAR2(30) PATH 'Reference/text()', + LINEITEMS XMLTYPE PATH 'LineItems/LineItem') M, + XMLTABLE ('/LineItem' PASSING M.LINEITEMS + COLUMNS + ITEMNO NUMBER(38) PATH '@ItemNumber', + PARTNO VARCHAR2(14) PATH 'Part/@Id', + DESCRIPTION VARCHAR2(30) PATH 'Description', + QUANTITY NUMBER(5) PATH 'Quantity') L; - Copy the above statement into the worksheet area and press "Explain Plan". +SELECT * FROM V_ORDERITEM; + +``` - ![Explain plan 2](./images/img-6.png) +Copy the above statement into the worksheet area and press "Explain Plan". You see how the structures built for our structured XML index work together to optimize the master-detail access of our XML documents. - +![Explain plan 2](./images/img-6.png) -2. Create XML Search Index +## Task 2: Create and use XML Search Indexes - In the case of ad-hoc XML queries or queries requiring text search or range search, we recommend creating an XML Search index to get a performance boost. - - ``` - - BEGIN - CTX_DDL.DROP_PREFERENCE('STORAGE_PREFS'); - END; - / - - BEGIN - CTX_DDL.DROP_SECTION_GROUP('XQFT'); - END; - / - - BEGIN - CTX_DDL.CREATE_SECTION_GROUP('XQFT', 'PATH_SECTION_GROUP'); - CTX_DDL.SET_SEC_GRP_ATTR('XQFT', 'XML_ENABLE', 'T'); - CTX_DDL.CREATE_PREFERENCE('STORAGE_PREFS', 'BASIC_STORAGE'); - END; - / - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". +In case of ad-hoc or free-form XML queries, that don’t follow a well-defined structure as appropriate for the Structured XMLIndex discussed in the previous section, we recommend creating an XML Search Index instead. The search index can be used to get a performance boost on both full-text as well as range search queries. + +1. The first step is to create a section group and set the search preferences: + ``` + + BEGIN + CTX_DDL.DROP_PREFERENCE('STORAGE_PREFS'); + END; + / + + BEGIN + CTX_DDL.DROP_SECTION_GROUP('XQFT'); + END; + / + + BEGIN + CTX_DDL.CREATE_SECTION_GROUP('XQFT', 'PATH_SECTION_GROUP'); + CTX_DDL.SET_SEC_GRP_ATTR('XQFT', 'XML_ENABLE', 'T'); + CTX_DDL.CREATE_PREFERENCE('STORAGE_PREFS', 'BASIC_STORAGE'); + END; + / + + ``` + + Copy the above statement into the worksheet area and press "Run Statement". You can ignore the errors from the first two drop operations if you run this lab for the first time. The lab is built in a way that you can re-run individual sections. ![Set preferences](./images/img-7.png) - - - ``` - - CREATE INDEX PURCHASEORDER_XQFT_IDX ON - PURCHASEORDER ( - DOC - ) - INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS ( 'storage STORAGE_PREFS - section group XQFT' ); - - ``` +2. The second step is to actually create the search index on the base table using the preferences created in the previous step: + ``` + + CREATE INDEX PURCHASEORDER_XQFT_IDX ON + PURCHASEORDER ( + DOC + ) + INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS ( 'storage STORAGE_PREFS + section group XQFT' ); + + ``` Copy the above statement into the worksheet area and press "Run Statement". ![Create XML search index](./images/img-8.png) - +Now that the search index has been set up, try running a variety of different queries and verify if the index is picked for each one of them by clicking on explain plan. -3. Run queries and check explain plan - - 3.1. Finding addresses given a zipCode. After creating the search index, a query like this will significantly improve the query performance. +Let’s look at a few text-search queries: +1. Find all “Overnight” orders ``` SELECT - COUNT(*) + id FROM - PURCHASEORDER PO + PURCHASEORDER WHERE - XMLEXISTS ( '(#ora:use_xmltext_idx #) - {$P/PurchaseOrder/LineItems/LineItem[@ItemNumber > $num]}' - PASSING PO.DOC AS "P", - '0' AS "num" - ); + XMLEXISTS ('/PurchaseOrder/SpecialInstructions[. contains text "Overnight"]' + PASSING doc); ``` - Copy the above statement into the worksheet area and press "Explain Plan". ![Explain plan SIQ1](./images/img-9.png) - - - - 3.2. Search for a contains match on a phrase. The contains match is case sensitive. +2. Orders where the description contains “Harry” and “Potter” ``` SELECT - COUNT(*) + id FROM - PURCHASEORDER PO + PURCHASEORDER WHERE - XMLEXISTS ( ' (#ora:use_xmltext_idx #) - {$P/PurchaseOrder/ShippingInstructions/Address/street[contains(.,$PHRASE)]}' - PASSING PO.DOC AS "P", - 'Building' AS "PHRASE" + XMLEXISTS ( '/PurchaseOrder/LineItems/LineItem/Description[. contains text "Harry" ftand "Potter"]' + PASSING doc ); ``` @@ -292,20 +241,17 @@ Database Actions allows you to connect to your Autonomous Database through vario ![Explain plan SIQ2](./images/img-10.png) - - - 3.3. An XQuery Full-Text "contains text" search on a phrase. The index is used since "contains text" comparisons are case insensitive. +3. Orders where the description contains the words “C++” or “Java” ``` SELECT - COUNT(*) + id FROM - PURCHASEORDER PO + PURCHASEORDER WHERE - XMLEXISTS ( '(#ora:use_xmltext_idx #) {$P/PurchaseOrder/ShippingInstructions/Address/street[. contains text {$PHRASE}]}' - PASSING PO.DOC AS "P", - 'building' AS "PHRASE" + XMLEXISTS ( '/PurchaseOrder/LineItems/LineItem/Description[. contains text "Java" ftor "C++"]' + PASSING doc ); ``` @@ -315,18 +261,17 @@ Database Actions allows you to connect to your Autonomous Database through vario ![Explain plan SIQ3](./images/img-11.png) - 3.4. An XQuery Full-Text "contains text" search on a phrase with stemming. - +4. Orders with price > 50 ``` SELECT - COUNT(*) + id FROM - PURCHASEORDER PO + PURCHASEORDER WHERE - XMLEXISTS ( '$P/PurchaseOrder/ShippingInstructions/Address/street[. contains text {$PHRASE} using stemming]' - PASSING PO.DOC AS "P", - 'build' AS "PHRASE" + XMLEXISTS ( '(# ora:use_xmltext_idx #) + {/PurchaseOrder/LineItems/LineItem/Part[@UnitPrice > 50]}' + PASSING doc ); ``` @@ -336,19 +281,18 @@ Database Actions allows you to connect to your Autonomous Database through vario ![Explain plan SIQ4](./images/img-12.png) - 3.5. An XQuery Full-Text "contains text" search on a fragment using the ftand operator. +5. Orders where the Requestor name is lexicographically > “Jake” ``` SELECT - COUNT(*) + id FROM - PURCHASEORDER PO + PURCHASEORDER WHERE - XMLEXISTS ( '$P/PurchaseOrder/ShippingInstructions/Address[. contains text {$PHRASE1} ftand {$PHRASE2} using stemming]' - PASSING PO.DOC AS "P", - 'nil' AS "PHRASE1", - 'build' AS "PHRASE2" + XMLEXISTS ( '(# ora:use_xmltext_idx #) + {/PurchaseOrder[Requestor > "Jake"]}' + PASSING doc ); ``` @@ -356,62 +300,12 @@ Database Actions allows you to connect to your Autonomous Database through vario Copy the above statement into the worksheet area and press "Explain Plan". ![Explain plan SIQ5 with stemming](./images/img-13.png) - - - ``` - - SELECT - COUNT(*) - FROM - PURCHASEORDER PO - WHERE - XMLEXISTS ( '$P/PurchaseOrder/ShippingInstructions/Address[. contains text {$PHRASE1} ftand {$PHRASE2} using stemming window 2 words]' - PASSING PO.DOC AS "P", - 'nil' AS "PHRASE1", - 'build' AS "PHRASE2" - ); - - ``` - - Copy the above statement into the worksheet area and press "Explain Plan". - - ![Explain plan SIQ5 with stemming window 2](./images/img-14.png) - - - ``` - - SELECT - COUNT(*) - FROM - PURCHASEORDER PO - WHERE - XMLEXISTS ( '$P/PurchaseOrder/ShippingInstructions/Address[. contains text {$PHRASE1} ftand {$PHRASE2} using stemming window 5 words]' - PASSING PO.DOC AS "P", - 'nil' AS "PHRASE1", - 'build' AS "PHRASE2" - ); - - ``` - - Copy the above statement into the worksheet area and press "Explain Plan". - - ![Explain plan SIQ5 stemming window 5](./images/img-15.png) -You may now **proceed to the next lab**. - -## Learn More -- [Database 19c - JSON] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=638) -- [Developing with JSON and SODA in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=831) -- [JSON without Limits] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=836) -- [Using the Database API for MongoDB] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3152) -- [Database API for MongoDB - The Basics] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3221) -- [Full-Text Search in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3286) -- [Autonomous Database Dedicated](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=677) -- [Manage and Monitor Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=553) -- [Scaling and Performance in the Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=608) +You have now experienced both structured XML indexes and search XML indexes in action to optimize various predicates and search condition. Feel free to experience more with other variants of queries if you like. +You may now **proceed to the next lab**. ## Acknowledgements * **Author** - Harichandan Roy, Principal Member of Technical Staff, Oracle Document DB * **Contributors** - XDB Team -* **Last Updated By/Date** - Harichandan Roy, February 2023 +- **Last Updated By/Date** - Ernesto Alvarez, April 2024 diff --git a/xmldb/introduction/introduction.md b/xmldb/introduction/introduction.md index 3142ad5d9..bdda15a70 100644 --- a/xmldb/introduction/introduction.md +++ b/xmldb/introduction/introduction.md @@ -2,67 +2,71 @@ ## About This Workshop -In this workshop, we will discuss some of the basic capabilities of Oracle XML DB. After the workshop, the users will be able to understand how to store XML data in Oracle DB and how to access and manipulate them. +In this workshop, you will get to know the basic XML capabilities of Oracle's Converged Database. After the workshop, you will understand how to store XML data and how to access and manipulate it. -Estimated Workshop Time: 3 hours, 30 minutes +Estimated Workshop Time: 1 hours, 30 minutes -## What Is XML? +## Task 1: What Is XML? -XML is a human-readable, machine-readable, and self-describing format to represent data in a hierarchical format. Here is an example of an XML document containing information on a purchase order. +XML is a human-readable, machine-readable, and self-describing format to represent data in a hierarchical format. The following is an example of an XML document containing information about a purchase order. ``` - - ROY-1PDT - - - ROY-1 - - - - H. Roy 1 - ROY-1 - H1 - - H. Roy 1 -
- 1 Nil Rd, Building 1 - SFO-1 - CA - 99236 - USA -
- 269-1-4036 -
- Overnight - - - 1 - 1 - - - 1 - 1 - - - 1 - 1 - - + + + CJONES-2022PST + + + DJOHN + + + Cindy Jones + CJONES + D30 + + Cindy Jones +
+ 200 Oracle Parkway + Redwood Shores + CA + 94065 + USA +
+ 650-506-7400 +
+ Overnight + + + Harry Potter and the Goblet of Fire + + 2 + + + Lord of the Rings + + 1 + + + Harry Potter and the Prisoner of Azkaban + + 5 + +
``` -## Why Do We Need To Manage XML Documents? +### Why Do You Need To Manage XML Documents? -XML is one of the popular ways to persist and exchange business-critical information. XML is an open standard, managed by the W3C, and under the control of no single vendor. Many industry segments have developed XML-based standards for representing information. These standards are typically based on XML Schema, a W3C-developed standard for defining the expected contents of a given XML File. XML-based standards can be found in healthcare, financial services, manufacturing, publishing, law enforcement, and the public sector. XML also provides the foundation for SOAP-based application development. In a growing number of situations, government regulation mandates the use of such standards when exchanging information. These trends have led to massive increases in the volume of XML that an organization needs to deal with and forced organizations to adopt XML platforms that manage XML with a similar degree of rigor and security to operational data. +XML is one of the popular ways to persist and exchange business-critical information. XML is an open standard, managed by the W3C, and under the control of no single vendor. Various industries have established XML-based standards, often leveraging XML Schema to define data structures. These standards are pervasive across sectors such as healthcare, finance, manufacturing, publishing, law enforcement, and government. These standards are typically based on XML Schema, a W3C-developed standard for defining the expected contents of a given XML File. XML also provides the foundation for SOAP-based application development. With governmental regulations increasingly mandating adherence to such standards, organizations are experiencing a surge in XML volume, necessitating the adoption of robust XML platforms that ensure data integrity and security comparable to operational data systems. -## What Does Oracle XML DB Offer? -To meet this need, Oracle developed Oracle XML DB. Oracle XML DB is a high-performance, native XML storage, and retrieval technology that is delivered as a part of Oracle Database. Oracle XML DB allows an organization to manage XML content in the same way that it manages traditional relational data. This allows organizations to save costs and improve return on investment by using a single platform to manage and secure all their mission-critical data. Oracle XML DB was first released with Oracle 9iR2, and it has been enhanced in each subsequent major release of the database. +### XML with the Oracle Database +To address these requirements, Oracle implemented XML capabilities natively in the database, commonly known as Oracle XML DB. Oracle XML DB is a high-performance, native XML storage, and retrieval technology that is integral part of Oracle's Converged Database. Oracle XML DB allows an organization to manage XML content in the same way that it manages traditional relational data. This allows organizations to save costs and improve return on investment by using a single platform to manage and secure all their mission-critical data. Oracle XML DB was first introduced with Oracle Database 9i Release 2, and it has been enhanced in each subsequent release of the database since then. -## Objectives -In this workshop, we intend to cover the following topics: +### Objectives + +In this workshop, you will learn about the following topics: - How to provision an Oracle Autonomous Database - Fundamentals of XML, XQuery, SQL/XML - How to store, query, process, and update XML data @@ -77,18 +81,13 @@ In this workshop, we intend to cover the following topics: You may now **proceed to the next lab**. ## Learn More -- [Database 19c - JSON] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=638) -- [Developing with JSON and SODA in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=831) -- [JSON without Limits] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=836) -- [Use the Database API for MongoDB] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3152) -- [Database API for MongoDB - The Basics] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3221) -- [Full-Text Search in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3286) -- [Autonomous Database Dedicated](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=677) -- [Manage and Monitor Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=553) -- [Scale and Performance in the Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=608) + +- [O.com: Oracle XML DB](https://www.oracle.com/database/technologies/appdev/xmldb.html) +- [O.com: Oracle Autonomous Database](https://www.oracle.com/database/autonomous-database.html) +- [Documentation: XML DB Developer Guide](https://docs.oracle.com/en/database/oracle/oracle-database/23/adxdb/index.html) ## Acknowledgements * **Author** - Harichandan Roy, Principal Member of Technical Staff, Oracle Document DB -* **Contributors** - XDB Team -* **Last Updated By/Date** - Harichandan Roy, February 2023 +* **Contributors** - XML Development, Oracle +* **Last Updated By/Date** - Ernesto Alvarez, April 2024 diff --git a/xmldb/populate/images/database_actions.png b/xmldb/populate/images/database_actions.png new file mode 100644 index 000000000..2c1c54b6f Binary files /dev/null and b/xmldb/populate/images/database_actions.png differ diff --git a/xmldb/populate/images/img-1.png b/xmldb/populate/images/img-1.png index 838dc7bdb..b730f4e0e 100644 Binary files a/xmldb/populate/images/img-1.png and b/xmldb/populate/images/img-1.png differ diff --git a/xmldb/populate/images/img-3--opt2.png b/xmldb/populate/images/img-3--opt2.png new file mode 100644 index 000000000..f1aa0e0d4 Binary files /dev/null and b/xmldb/populate/images/img-3--opt2.png differ diff --git a/xmldb/populate/images/img-3.png b/xmldb/populate/images/img-3.png index 3f1e75d45..90991d45a 100644 Binary files a/xmldb/populate/images/img-3.png and b/xmldb/populate/images/img-3.png differ diff --git a/xmldb/populate/images/img-5.png b/xmldb/populate/images/img-5.png index cb06d0e9c..de93650f3 100644 Binary files a/xmldb/populate/images/img-5.png and b/xmldb/populate/images/img-5.png differ diff --git a/xmldb/populate/images/img-6--opt2.png b/xmldb/populate/images/img-6--opt2.png new file mode 100644 index 000000000..4469f6932 Binary files /dev/null and b/xmldb/populate/images/img-6--opt2.png differ diff --git a/xmldb/populate/images/img-6.png b/xmldb/populate/images/img-6.png new file mode 100644 index 000000000..e3398764e Binary files /dev/null and b/xmldb/populate/images/img-6.png differ diff --git a/xmldb/populate/images/img-7.png b/xmldb/populate/images/img-7.png new file mode 100644 index 000000000..39588c537 Binary files /dev/null and b/xmldb/populate/images/img-7.png differ diff --git a/xmldb/populate/populate.md b/xmldb/populate/populate.md index 92288c6a8..e5c62e180 100644 --- a/xmldb/populate/populate.md +++ b/xmldb/populate/populate.md @@ -1,7 +1,7 @@ -# Create tables and populate data +# Create your first XML table and insert some XML documents ## Introduction -This lab will use the SQL Workshop in Database Actions from the Autonomous Transaction Processing page. We will create a simple table with an XMLType column in it and populate the table with some XML documents. +You will use the SQL Worksheet in Database Actions from your Autonomous Database. We will create a sample table with an XMLType column and populate the table with some XML documents. Estimated Time: 15 minutes @@ -10,29 +10,23 @@ In this lab, you will learn: 1. How to create and populate a table with an XMLType column ### Prerequisites -- Be logged into your Oracle Cloud Account +- Access to an Oracle Autonomous Database, Database Actions web interface. ## Task 1: Open Database Actions 1. Log in to the Oracle Cloud. -2. If you are using a Free Trial or Always Free account, and you want to use Always Free Resources, you need to be in a region where Always Free Resources are available. You can see your current default Region in the top, right-hand corner of the page. -3. Click the navigation menu in the upper left to show top-level navigation choices. -4. Click on Oracle Database and choose Autonomous Transaction Processing. -5. If using FreeTier, your compartment should be the root compartment for your tenancy. -Note: Avoid the use of the ManagedCompartmentforPaaS compartment as this is an Oracle default used for Oracle Platform Services. -6. You should see your database XMLDB listed in the center. Click on the database name "XMLDB". -7. On the database page, choose Database Actions. -8. You are now in Database Actions. -Database Actions allows you to connect to your Autonomous Database through various browser-based tools. We will just be using the SQL workshop tool. -9. You should be in the Database Actions panel. Click on the SQL card. +6. Navigate to your previously created Autonomous Database "XMLDB" (or the name you have chosen). +7. On the database detail page, choose Database Actions. You can navigate to the Database Actions overview page or go directly to the SQL Worksheet + +![Database Actions](./images/database_actions.png) ## Task 2: Create and Populate a Table with an XMLType Column -1. Go to Database Actions panel +1. Enter the SQL Worksheet - Click on the SQL card. When you first enter SQL, you will get a tour of the features. We recommend you step through it, but you can skip the tour by clicking on the "X". The tour is available at any time by clicking the tour button. You can dismiss the warning that you are logged in as an ADMIN user. + When you first enter SQL, you will get a tour of the features. We recommend you step through it, but you can skip the tour by clicking on the "X" The tour is available at any time by clicking the tour button. You can dismiss the warning that you are logged in as an ADMIN user. 2. Create a table with XMLType column - We will create a simple table to record the sample purchase orders. It contains a numeric column for purchase ID and an XMLType column for purchase details. + We will create a simple table to record the sample purchase orders. It contains a numeric column for purchase ID and an XMLType column for our purchase details. Copy the following into the 'Worksheet' area and press the "Run Statement" button: @@ -41,21 +35,12 @@ Database Actions allows you to connect to your Autonomous Database through vario -- By default, the storage type is Binary XML CREATE TABLE purchaseorder ( - id NUMBER, + id NUMBER PRIMARY KEY, doc XMLTYPE );
``` - ``` - - -- You can also specify the storage type - CREATE TABLE PURCHASEORDER ( - ID NUMBER, - DOC XMLTYPE - ) XMLTYPE DOC STORE AS BINARY XML; - - ``` You should see the message "Table PURCHASEORDER created". ![Create table](./images/img-1.png) @@ -64,29 +49,22 @@ Database Actions allows you to connect to your Autonomous Database through vario ![Table list](./images/img-2.png) + You can check the storage type 'BINARY' of your XMLtype column in the data dictionary + ``` + + SELECT column_name, storage_type + FROM user_xml_tab_cols + WHERE table_name ='PURCHASEORDER' + + ``` + + 3. Populate the table with a few rows Use the 'trashcan' icon to delete the previous statement from the Worksheet area. Copy the following SQL into the worksheet area. Make sure you highlight the whole statement with your mouse and press the "Run Statement" button: - Here we are assuming that the XML files are stored in the Object store. So, we will now load the XML data to our table from the Object store. If you are very new to the Object Store, then please consider finishing the Lab 5 from here [Full-Text workshop] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/run-workshop?p210_wid=3286&p210_wec=&session=123567123391417). - - **Note:** The value of OBJECT_URI has been modified here. ```url/livelab-xmldoc-1.xml``` is not the actual value. - The actual link is the authenticated link retrieved from the object store. Please refer to object store how to get it. - If you find it difficult to load the data into the tables, please use other approaches you find appropriate. The most easy to follow approach is ```insert into [TABLE] (...)```. + Here we are using XML files stored in the Object store. The files are created with pre-authentication, so you do not need to provide a credential for authentication and authorization. - ``` - - -- Create the credentials - begin - DBMS_CLOUD.create_credential( - credential_name => 'OBJ_STORE_CRED', - username => 'your_email_address', - password => 'your_password' - ); - end; - / - - ``` Now let’s insert the documents from the object store. ``` @@ -96,8 +74,8 @@ Database Actions allows you to connect to your Autonomous Database through vario BLOB_IN BLOB; X XMLTYPE; BEGIN - BLOB_IN := DBMS_CLOUD.GET_OBJECT(CREDENTIAL_NAME => 'OBJ_STORE_CRED', - OBJECT_URI => 'url/livelab-xmldoc-1.xml' + BLOB_IN := DBMS_CLOUD.GET_OBJECT(CREDENTIAL_NAME => null, + OBJECT_URI => 'https://c4u04.objectstorage.us-ashburn-1.oci.customer-oci.com/p/EcTjWk2IuZPZeNnD_fYMcgUhdNDIDA6rt9gaFj_WZMiL7VvxPBNMY60837hu5hga/n/c4u04/b/livelabsfiles/o/labfiles/livelab-xmldoc-1.xml' ); X := XMLTYPE(BLOB_IN, nls_charset_id('AL32UTF8')); INSERT INTO PURCHASEORDER VALUES ( @@ -110,101 +88,79 @@ Database Actions allows you to connect to your Autonomous Database through vario ![Insert from the object store](./images/img-3.png) - Similarly, we can insert other sample documents. + You can also use the external table approach to load the XML documents into your table. Here is the link for more info: [External table approach to load the data](https://blogs.oracle.com/datawarehousing/post/loading-xml-data-from-your-object-store-into-autonomous-database) ``` - -- Inserting xmldoc-2 - DECLARE - BLOB_IN BLOB; - X XMLTYPE; BEGIN - BLOB_IN := DBMS_CLOUD.GET_OBJECT(CREDENTIAL_NAME => 'OBJ_STORE_CRED', - OBJECT_URI => 'url/livelab-xmldoc-2.xml' - ); - X := XMLTYPE(BLOB_IN, nls_charset_id('AL32UTF8')); - INSERT INTO PURCHASEORDER VALUES ( - 2, - X + DBMS_CLOUD.CREATE_EXTERNAL_TABLE ( + table_name =>'STAGING_TABLE', credential_name =>null, + format => json_object('delimiter' value '%$#^@%$', 'recorddelimiter' value '0x''02'''), + file_uri_list =>'https://c4u04.objectstorage.us-ashburn-1.oci.customer-oci.com/p/EcTjWk2IuZPZeNnD_fYMcgUhdNDIDA6rt9gaFj_WZMiL7VvxPBNMY60837hu5hga/n/c4u04/b/livelabsfiles/o/labfiles/livelab-xmldoc-2.xml', + column_list => 'xml_document clob', + field_list => 'xml_document CHAR(1000000)' ); END; - - ``` + / - ``` - - -- Inserting xmldoc-3 - DECLARE - BLOB_IN BLOB; - X XMLTYPE; - BEGIN - BLOB_IN := DBMS_CLOUD.GET_OBJECT(CREDENTIAL_NAME => 'OBJ_STORE_CRED', - OBJECT_URI => 'url/livelab-xmldoc-3.xml' - ); - X := XMLTYPE(BLOB_IN, nls_charset_id('AL32UTF8')); - INSERT INTO PURCHASEORDER VALUES ( - 3, - X - ); - END; - - COMMIT; + INSERT INTO PURCHASEORDER SELECT 2, XMLTYPE(xml_document) FROM staging_table; ``` - ``` - - -- Check if all docs are inserted correctly - SELECT - t.DOC.GETCLOBVAL() - FROM - PURCHASEORDER t; - - ``` - - You can also use the external table approach to load the XML documents into your table. Here is the link for more info: [External table approach to load the data] (https://blogs.oracle.com/datawarehousing/post/loading-xml-data-from-your-object-store-into-autonomous-database) + ![External table](./images/img-6.png) - If your XML documents are smaller, you can even use the ‘insert into’ statements to insert the docs into your table. + If your XML documents are smaller, you can even use the INSERT INTO’ statements to insert the XML documents into your table. ``` INSERT INTO PURCHASEORDER VALUES ( 3, ' - ROY-1PDT - H. Roy 1 - ROY-1 - H1 - - H. Roy 1 -
- 1 Nil Rd, Building 1 - SFO-1 - CA - 99236 - USA -
-
- Overnight - - - 1 - 1 - - - 1 - 1 - - - 1 - 1 - - -
' + MAllen-2024PST + + + BLAKE + + + Michael Allen + MALLEN + T10 + + Michael Allen +
+ 300 Oracle Parkway + Redwood Shores + CA + 94065 + USA +
+ 650-506-7300 +
+ Overnight + + + Java complete reference + + 5 + + + Julius Caesar + + 10 + + + anthology of short stories + + 5 + + + ' );
``` + ![External table](./images/img-7.png) + You can choose any of the above approaches to insert the XML documents into the table. Let's insert two more documents - this time NULL document. @@ -221,17 +177,19 @@ Database Actions allows you to connect to your Autonomous Database through vario
``` + Now the table PURCHASEORDER table should have 5 rows. + ``` -- Check if all docs are inserted correctly SELECT - t.DOC.GETCLOBVAL() + COUNT(*) FROM - PURCHASEORDER t; + PURCHASEORDER; ``` - Now the table PURCHASEORDER table should have 5 rows. + ![Number of rows](./images/img-4.png) @@ -245,7 +203,8 @@ Database Actions allows you to connect to your Autonomous Database through vario t.id, t.doc.getclobval() FROM - PURCHASEORDER t; + PURCHASEORDER t + ORDER BY t.id;
``` @@ -259,18 +218,13 @@ Database Actions allows you to connect to your Autonomous Database through vario You may now **proceed to the next lab**. ## Learn More -- [Database 19c - JSON] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=638) -- [Developing with JSON and SODA in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=831) -- [JSON without Limits] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=836) -- [Using the Database API for MongoDB] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3152) -- [Database API for MongoDB - The Basics] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3221) -- [Full-Text Search in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3286) -- [Autonomous Database Dedicated](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=677) -- [Manage and Monitor Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=553) -- [Scaling and Performance in the Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=608) + +* [Get started with Oracle Autonomous Database Serverless ](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/videos.html) +- [XML DB Developer's Guide](https://docs.oracle.com/en/database/oracle/oracle-database/23/adxdb/index.html) +- [Oracle XML DB](https://www.oracle.com/database/technologies/appdev/xmldb.html) ## Acknowledgements * **Author** - Harichandan Roy, Principal Member of Technical Staff, Oracle Document DB * **Contributors** - XDB Team -* **Last Updated By/Date** - Harichandan Roy, February 2023 +- **Last Updated By/Date** - Ernesto Alvarez, April 2024 diff --git a/xmldb/provision/images/atp.png b/xmldb/provision/images/atp.png index 07bf41568..cf6e89af4 100644 Binary files a/xmldb/provision/images/atp.png and b/xmldb/provision/images/atp.png differ diff --git a/xmldb/provision/images/configuration.png b/xmldb/provision/images/configuration.png index c2a9f6ee5..47d3a4492 100644 Binary files a/xmldb/provision/images/configuration.png and b/xmldb/provision/images/configuration.png differ diff --git a/xmldb/provision/images/last.jpg b/xmldb/provision/images/last.jpg new file mode 100644 index 000000000..e17fde22a Binary files /dev/null and b/xmldb/provision/images/last.jpg differ diff --git a/xmldb/provision/images/last.png b/xmldb/provision/images/last.png new file mode 100644 index 000000000..6a7ee025f Binary files /dev/null and b/xmldb/provision/images/last.png differ diff --git a/xmldb/provision/images/provisioning.png b/xmldb/provision/images/provisioning.png deleted file mode 100644 index 5a1303d09..000000000 Binary files a/xmldb/provision/images/provisioning.png and /dev/null differ diff --git a/xmldb/provision/provision.md b/xmldb/provision/provision.md index d45f99b78..907c3d352 100644 --- a/xmldb/provision/provision.md +++ b/xmldb/provision/provision.md @@ -23,13 +23,10 @@ In this lab, you will: 1. Log in to the Oracle Cloud. - - -2. If you are using a Free Trial or Always Free account, and you want to use Always Free Resources, you need to be in a region where Always Free Resources are available. You can see your current default **Region** in the top, right-hand corner of the page. +2. If you are using a Free Trial or Always Free account, and you want to use Always Free Resources, you need to be in your Home region where Always Free Resources are available. You can see your current default **Region** in the top, right-hand corner of the page. ![Select region on the far upper-right corner of the page.](./images/region.png " ") - 2. If you are using a LiveLabs account, you need to be in the region your account was provisioned in. You can see your current default **Region** in the top, right-hand corner of the page. Make sure that it matches the region on the LiveLabs Launch page. @@ -103,16 +100,11 @@ In this lab, you will: 6. Configure the database: - - - __Always Free__ - If your Cloud Account is an Always Free account, you can select this option to create an always free autonomous database. An always free database comes with 1 CPU and 20 GB of storage. For this lab, we recommend you leave Always Free checked if you have that as an option. - - - __Always Free__ - For this lab, we recommend you leave Always Free checked if it is available to you. - - - __Choose database version__ - Select 19c from the database version. Note: This lab should work on a 21c AJD database as well. - - __OCPU count__ - Number of OCPUs for your service. For this lab, leave the default __1 OCPU__. If you choose an Always Free database, it comes with 1 OCPU. - - __Storage (TB)__ - Select your storage capacity in terabytes. For this lab, leave the default __1 TB__ of storage. If you choose an Always Free database, it comes with 20 GB of storage. - - __Auto Scaling__ - For this lab, keep auto scaling enabled, to allow the system to automatically use up to three times more CPU and IO resources to meet workload demand. + - __Choose database version__ - Select 19c from the database version. Note: This workshop will also run Autonomous Database 21c. + - ECPU count__ - Number of ECPUs for your service. For this lab, leave the default __2 ECPU__. If you choose an Always Free database, you won't be able to set an ECPU count. + - __Storage (TB)__ - Select your storage capacity in terabytes. For this lab, you can reduce the storage down to the minimum of __20 GB__ of storage. If you choose an Always Free database, it comes with 20 GB of storage. + - __Auto Scaling__ - For this lab, keep auto scaling enabled, to allow the system to automatically use up to three times more CPU and IO resources to meet workload demand. This option is not available for Always Free. *Note: You cannot scale up/down an Always Free autonomous database.* @@ -148,21 +140,20 @@ In this lab, you will: 10. Click __Create Autonomous Database__. - ![Click Create Autonomous Database.](./images/create-adb-final.png " ") - -11. Your instance will begin provisioning. In a few minutes, the state will turn from Provisioning to Available. At this point, your Autonomous database is ready to use! Have a look at your instance's details here including the Database Name, Database Version, OCPU Count, and Storage. + ![Click Create Autonomous Database.](./images/create-adb-final.png) - ![Database instance homepage.](./images/provisioning.png " ") +11. Your instance will begin provisioning. In a few minutes, the state will turn from Provisioning to Available. At this point, your Autonomous Database is ready to use! Have a look at your instance's details here including the Database Name, Database Version, OCPU Count, and Storage. + ![Database instance homepage.](./images/last.png) You may now **proceed to the next lab**. ## Learn More -* [Provision Autonomous JSON Database](https://docs.oracle.com/en/cloud/paas/autonomous-json-database/ajdug/autonomous-provision.html#GUID-0B230036-0A05-4CA3-AF9D-97A255AE0C08) +* [Get started with Oracle Autonomous Database Serverless ](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/videos.html) ## Acknowledgements - **Author** - Roger Ford, Principal Product Manager, Oracle Database - **Contributors** - Kamryn Vinson, Andres Quintana, James Zheng -- **Last Updated By/Date** - Roger Ford, March 2022 +- **Last Updated By/Date** - Ernesto Alvarez, April 2024 diff --git a/xmldb/queries/images/img-12.png b/xmldb/queries/images/img-12.png index 3ff3bbc99..aef334d01 100644 Binary files a/xmldb/queries/images/img-12.png and b/xmldb/queries/images/img-12.png differ diff --git a/xmldb/queries/images/img-13.png b/xmldb/queries/images/img-13.png index bd26c8fce..4817ab8a9 100644 Binary files a/xmldb/queries/images/img-13.png and b/xmldb/queries/images/img-13.png differ diff --git a/xmldb/queries/images/img-14.png b/xmldb/queries/images/img-14.png index c34371ba9..504836c2c 100644 Binary files a/xmldb/queries/images/img-14.png and b/xmldb/queries/images/img-14.png differ diff --git a/xmldb/queries/images/img-15.png b/xmldb/queries/images/img-15.png index 7cc588a14..391955d12 100644 Binary files a/xmldb/queries/images/img-15.png and b/xmldb/queries/images/img-15.png differ diff --git a/xmldb/queries/images/img-19.png b/xmldb/queries/images/img-19.png new file mode 100644 index 000000000..3f40ccc15 Binary files /dev/null and b/xmldb/queries/images/img-19.png differ diff --git a/xmldb/queries/images/img-2.png b/xmldb/queries/images/img-2.png index 85299bbc9..19f883964 100644 Binary files a/xmldb/queries/images/img-2.png and b/xmldb/queries/images/img-2.png differ diff --git a/xmldb/queries/images/img-3.png b/xmldb/queries/images/img-3.png index 0d3cb782c..ca6c82b15 100644 Binary files a/xmldb/queries/images/img-3.png and b/xmldb/queries/images/img-3.png differ diff --git a/xmldb/queries/images/img-4.png b/xmldb/queries/images/img-4.png index 6da923d63..36f10d1e6 100644 Binary files a/xmldb/queries/images/img-4.png and b/xmldb/queries/images/img-4.png differ diff --git a/xmldb/queries/images/img-5.png b/xmldb/queries/images/img-5.png index d7cae5ba5..ab66f0096 100644 Binary files a/xmldb/queries/images/img-5.png and b/xmldb/queries/images/img-5.png differ diff --git a/xmldb/queries/images/img-6.png b/xmldb/queries/images/img-6.png index b72338ae4..63d0e0d55 100644 Binary files a/xmldb/queries/images/img-6.png and b/xmldb/queries/images/img-6.png differ diff --git a/xmldb/queries/images/img-8.png b/xmldb/queries/images/img-8.png index d0f21b80e..5cbd5dc34 100644 Binary files a/xmldb/queries/images/img-8.png and b/xmldb/queries/images/img-8.png differ diff --git a/xmldb/queries/images/img-9.png b/xmldb/queries/images/img-9.png index 1d5539142..e862a75cd 100644 Binary files a/xmldb/queries/images/img-9.png and b/xmldb/queries/images/img-9.png differ diff --git a/xmldb/queries/queries.md b/xmldb/queries/queries.md index 654c1f089..95a082629 100644 --- a/xmldb/queries/queries.md +++ b/xmldb/queries/queries.md @@ -1,18 +1,16 @@ -# Run queries +# Analyze your data using SQL and XQuery ## Introduction -This lab will use the SQL Workshop in Database Actions from the Autonomous Transaction Processing page. Here we will explore XQuery to query XML content stored in Oracle XML DB. It is one of the main ways that you interact with XML data in Oracle XML DB. It is the W3C language designed for querying and updating XML data. +This lab will use the SQL Worksheet from your Autonomous Database. We will explore XQuery to query XML content stored in Oracle XML DB. It is one of the main ways that you interact with XML data in Oracle XML DB. It is the W3C language designed for querying and updating XML data. The support for the XQuery Language is provided through a native implementation of SQL/XML functions: XMLQuery, XMLTable, XMLExists, and XMLCast. These SQL/XML functions are defined by the SQL/XML standard as a general interface between the SQL and XQuery languages. -Estimated Time: 60 minutes +Estimated Time: 45 minutes ### Objectives -In this lab, you will learn: -- XQuery basics, -- SQL/XML basics, +In this lab, you will execute the following tasks: - Querying XML documents or fragments, - Extracting XML nodes/scalar values, - Constructing new XML documents from stored documents, @@ -22,523 +20,327 @@ In this lab, you will learn: ### Prerequisites -- Be logged into your Oracle Cloud Account. +- Be logged into your Oracle Cloud Account and have access to the SQL Worksheet in Database Actions. -## Task 1: XQuery Basics +## Task 1: Get the number of not-null XML documents -XQuery is the W3C language designed for querying and updating XML data. The core part of it is the XQuery expression. XQuery expressions are case-sensitive. An XQuery expression is either a simple expression or an updating expression, the latter being an expression that represents data modification. More precisely, these are the possible XQuery expressions: +Let's first see how many non-null XML documents we have in our table. The WHERE clause in the following statement filters the not-null documents. -- Basic updating expression – an insert, delete, replace, or rename expression, or a call to an updating function. -- Updating expression – a basic updating expression or an expression (other than a transform expression) that contains another updating expression (this is a recursive definition). -- Simple expression – An XQuery 1.0 expression. It does not call for any updating. -Simple expressions include the following: - - Primary expression – literal, variable, or function application. A variable name starts with a dollar sign ($) – for example, $foo. Literals include numerals, strings, and character or entity references. - - XPath expression – Any XPath expression. The XPath 2.0 standard is a subset of XQuery. - - FLWOR expression – The most important XQuery expression, composed of the following, in order, from which FLWOR takes its name: for, let, where, order by, and return. - - XQuery sequence – The comma (,) constructor creates sequences. Sequence-manipulating functions such as union and intersect are also available. All XQuery sequences are effectively flat: a nested sequence is treated as its flattened equivalent. Thus, for instance, (1, 2, (3, 4, (5), 6), 7) is treated as (1, 2, 3, 4, 5, 6, 7). A singleton sequence, such as (42), acts the same in most XQuery contexts as does its single item, 42. Remember that the result of any XQuery expression is a sequence. -- And Conditional, Arithmetic, Relational expressions, and so on. +In SQL Worksheet, copy the following simple SELECT into the worksheet area and press "Run Statement". -In this lab, we don’t intend to discuss XQuery in detail, please refer to the links below for more information about XQuery. +``` + +SELECT + COUNT(*) +FROM + PURCHASEORDER +WHERE + DOC IS NOT NULL; + +``` -The overview of XQuery language: [XQuery Overview] (https://docs.oracle.com/en/database/oracle/oracle-database/21/adxdb/xquery-and-XML-DB.html#GUID-927FB610-9553-4772-8D3E-FAA7546C4371) +![Number of not-null documents](./images/img-1.png) -The W3C XQuery link: [W3C Xquery] (https://www.w3.org/TR/xquery-31/) -## Task 2: SQL/XML Basics +## Task 2: Search for the specific XML documents -SQL/XML functions, XMLQuery, XMLTable, XMLExists, and XMLCast, are defined by the SQL/XML standard as a general interface between SQL and XQuery languages. Using these functions, you can construct XML data using relational data, query relational data as if it were XML data, and construct relational data from XML data. +The XMLExists SQL/XML function can be used in the WHERE clause to filter rows based on an XQuery expression. It evaluates whether or not a given document contains a node that matches the specified XQuery expression. -Here is a short overview of these SQL/XML functions: -- XMLQuery - Use this function to construct or query XML data. It takes an XQuery expression as an argument and returns the result of evaluating the XQuery expression, as an XMLType instance. (Example in Task 4.3) +The following query will return the XML documents which satisfy the XPath /PurchaseOrder/Reference. -- XMLTable - Use this function XMLTable to decompose the result of an XQuery-expression evaluation into the relational rows and columns of a new, virtual table. You can insert this data into a pre-existing database table, or you can query it using SQL — in a join expression, for example. (Example in Task 4.5) +``` + +SELECT + P.DOC.GETCLOBVAL() XMLDOC +FROM + PURCHASEORDER P +WHERE + XMLEXISTS ('/PurchaseOrder/Reference' + PASSING P.DOC + ); + +``` -- XMLExists - Use this function to check whether a given XQuery expression returns a non-empty XQuery sequence. If so, the function returns TRUE. Otherwise, it returns FALSE. (Example in Task 4.2) +Copy the above statement into the worksheet area and press "Run Statement". All non-null documents are returned since all of them have the same XPath node. -- XMLCast - Use this function to cast an XQuery value to a SQL data type. (Example in Task 4.4) +![Documents satisfying the XPath](./images/img-2.png) -Here is the link for more information: [XQL/XML functions] (https://docs.oracle.com/en/database/oracle/oracle-database/21/adxdb/xquery-and-XML-DB.html#GUID-4805CF1C-A00D-4B88-AF2E-00A9DB6F3392) +The next query is even more specific, and it will return the XML documents where XPath /PurchaseOrder/Reference has 'CJONES-2022PST' as the value. -## Task 3: Open Database Actions +``` + +SELECT + P.DOC.GETCLOBVAL() XMLDOC +FROM + PURCHASEORDER P +WHERE + XMLEXISTS ('$p/PurchaseOrder[Reference="CJONES-2022PST"]' + PASSING P.DOC AS "p" + ); + +``` -1. Log in to the Oracle Cloud. -2. If you are using a Free Trial or Always Free account, and you want to use Always Free Resources, you need to be in a region where Always Free Resources are available. You can see your current default Region in the top, right-hand corner of the page. -3. Click the navigation menu in the upper left to show top-level navigation choices. -4. Click on Oracle Database and choose Autonomous Transaction Processing. -5. If using FreeTier, your compartment should be the root compartment for your tenancy. -Note: Avoid the use of the ManagedCompartmentforPaaS compartment as this is an Oracle default used for Oracle Platform Services. -6. You should see your database XMLDB listed in the center. Click on the database name "XMLDB". -7. On the database page, choose Database Actions. -8. You are now in Database Actions. -Database Actions allows you to connect to your Autonomous Database through various browser-based tools. We will just be using the SQL workshop tool. -9. You should be in the Database Actions panel. Click on the SQL card +Copy the above statement into the worksheet area and press "Run Statement". You'll see that we only have one document with a purchase order reference to 'CJONES-2022PST'. -## Task 4: Queries +![Documents satisfying the XPath and predicate](./images/img-3.png) -1. Get the number of not-null XML documents - - Let’s first see how many not-null XML documents we have. The ‘where’ clause in the following statement filters the not-null documents. - - Copy the following simple SELECT into the worksheet area and press "Run Statement". - - ``` - - SELECT - COUNT(*) - FROM - PURCHASEORDER - WHERE - DOC IS NOT NULL; - - ``` - - ![Number of not-null documents](./images/img-1.png) - -2. Search for the specific XML documents - - If we want to search for specific XML documents, we can use XMLExists SQL/XML function in the where clause. Based on the XQuery expression provided in the XMLExists function, it will filter out the XML documents we are looking for. - - This query will return the XML documents which satisfy the XPath /PurchaseOrder/Reference. - - ``` - - SELECT - P.DOC.GETCLOBVAL() XMLDOC - FROM - PURCHASEORDER P - WHERE - XMLEXISTS ( '/PurchaseOrder/Reference' - PASSING P.DOC - ); - - ``` +You can also use a bind variable to pass a value, as shown in the example below. Bind variables should always be used when a query will be executed multiple times with different predicates. - Copy the above statement into the worksheet area and press "Run Statement". + ``` + +SELECT + P.DOC.GETCLOBVAL() XMLDOC +FROM + PURCHASEORDER P +WHERE + XMLEXISTS ( '$p/PurchaseOrder[Reference=$REF]' + PASSING P.DOC AS "p", + 'CJONES-2022PST' AS "REF" + ); + +``` - ![Documents satisfying the XPath](./images/img-2.png) +Copy the above statement into the worksheet area and press "Run Statement". +![Documents satisfying the XPath and a bind predicate](./images/img-4.png) - The next query is even more specific, and it will return the XML documents where XPath /PurchaseOrder/Reference has 'ROY-1PDT' as the value. - - ``` - - SELECT - P.DOC.GETCLOBVAL() XMLDOC - FROM - PURCHASEORDER P - WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-1PDT"]' - PASSING P.DOC AS "p" - ); - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![Documents satisfying the XPath and predicate](./images/img-3.png) - - - ``` - - -- You can also use a bind variable to pass a value - SELECT - P.DOC.GETCLOBVAL() XMLDOC - FROM - PURCHASEORDER P - WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference=$REF]' - PASSING P.DOC AS "p", - 'ROY-1PDT' AS "REF" - ); - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![Documents satisfying the XPath and a bind predicate](./images/img-4.png) -3. Access fragments or nodes of the XML documents +## Task 3: Access fragments or nodes of your XML documents - In Q2, we get the specific XML documents. Now let's access the XMl fragments or nodes of those returned documents. To do that, we will use XMLQuery and pass an XQuery expression to XMLQuery to get the fragments or nodes we are looking for. + If we are not interested in all the information in the XML documents, but are interested in only seeing a fragment of the documents, we can use XMLQuery function which takes an XQuery expression and returns the fragments or nodes we are looking for. - The ‘where’ clause of this query will filter the documents that we are looking for and the XMLQuery will extract the fragments/nodes from those filtered XML documents. + The WHERE clause of this query will filter the documents that we are looking for and the XMLQuery will extract only the fragments/nodes of the shipping instruction information from our filtered XML documents. - ``` - - SELECT - XMLQUERY('/PurchaseOrder/ShippingInstructions' - PASSING P.DOC - RETURNING CONTENT).GETCLOBVAL() XMLNODE - FROM - PURCHASEORDER P - WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-1PDT"]' - PASSING P.DOC AS "p" - ); - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". +``` + +SELECT + XMLQUERY('/PurchaseOrder/ShippingInstructions' + PASSING P.DOC + RETURNING CONTENT).GETCLOBVAL() XMLNODE +FROM + PURCHASEORDER P +WHERE + XMLEXISTS ( '$p/PurchaseOrder[Reference="MAllen-2024PST"]' + PASSING P.DOC AS "p" + ); + +``` + +Copy the above statement into the worksheet area and press "Run Statement". You will see that only one row satisfied our filter criteria, and the returned data contains only the fragment of the shipping information. - ![Fragments satisfying the XPath and predicate](./images/img-5.png) +![Fragments satisfying the XPath and predicate](./images/img-5.png) -4. Extract the scalar value from XML fragments or nodes - In Q2, we filter out some XML documents and then access the fragments or nodes of those documents in Q3. Now let's extract the scalar value of those fragments or nodes. To do that, we can use XMLCast to map the XQuery result to a SQL type. +## Task 4: Extract the scalar value from XML fragments or nodes - This query will return the scalar value of the ‘name’ node in ‘ShippingInstructions’ of the documents having 'ROY-1PDT' as the Reference value. +So far we have worked with XML documents or fragments of XML documents. Very often it is desirable to extract portions of our documents as classical scalar values for display or further processing in SQL as relational data. If we want to extract the scalar value of fragments or nodes from your XML documents, we can use XMLCast function to map the XQuery result to a SQL data type. - ``` - - SELECT - XMLCAST(XMLQUERY('/PurchaseOrder/ShippingInstructions/name' - PASSING P.DOC - RETURNING CONTENT) AS VARCHAR2(50)) XMLNODE - FROM - PURCHASEORDER P - WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-1PDT"]' - PASSING P.DOC AS "p" - ); - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". +The following query will return the scalar value of the 'name' node in 'ShippingInstructions' of the documents having 'SBELL-2023PDT' as the Reference value. + +``` + +SELECT + XMLCAST(XMLQUERY('/PurchaseOrder/ShippingInstructions/name' + PASSING P.DOC + RETURNING CONTENT) AS VARCHAR2(50)) XMLNODE +FROM + PURCHASEORDER P +WHERE + XMLEXISTS ('$p/PurchaseOrder[Reference="SBELL-2023PDT"]' + PASSING P.DOC AS "p" + ); + +``` + +Copy the above statement into the worksheet area and press "Run Statement". You will see the name 'Sarah J. Bell' being returned as scalar value, the name element of our shipping instructions. - ![Value of the fragments satisfying the XPath and predicate](./images/img-6.png) +![Value of the fragments satisfying the XPath and predicate](./images/img-6.png) - You can also use the text() function for the same. +## Task 5: Generate relational data from XML data - ``` - - SELECT - XMLQUERY('/PurchaseOrder/ShippingInstructions/name/text()' +We just learned how to extract simple scalar values. However, XML documents consist of more complex structures, such as nested path or arrays. The XMLTable function allows us to decomposes the result of a XQuery evaluation into relational rows and columns of a new virtual table. We can insert this data into a relational table, or we can query it using SQL depending on the use cases. + +In task 3 we extracted the ShippingInstructions as an XML fragment. The following statement will give us the same fragment as a relational table. + +``` + +SELECT + SI.* +FROM + PURCHASEORDER P, + XMLTABLE ('/PurchaseOrder/ShippingInstructions' PASSING P.DOC - RETURNING CONTENT).GETCLOBVAL() XMLNODE_VAL - FROM - PURCHASEORDER P - WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-1PDT"]' - PASSING P.DOC AS "p" - ); - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![XMLCAST alternative](./images/img-7.png) - - -5. Generate relation data from XML data - - To decompose the result of an XQuery expression’s evaluation into the relational rows and columns of a new, virtual table, we will use XMLTable. We can insert this data into a relational table, or we can query it using SQL depending on the use cases. - - In Q3, we get the ShippingInstructions as an XML fragment. The following statement will give us the same fragment as a relational table. - - ``` - - SELECT - SI.* - FROM - PURCHASEORDER P, - XMLTABLE ( '/PurchaseOrder/ShippingInstructions' - PASSING P.DOC - COLUMNS - NAME VARCHAR2(15) PATH 'name', - STREET VARCHAR2(30) PATH 'Address/street', - CITY VARCHAR2(15) PATH 'Address/city', - STATE VARCHAR2(10) PATH 'Address/state', - ZIPCODE VARCHAR2(10) PATH 'Address/zipCode', - COUNTRY VARCHAR2(30) PATH 'Address/country', - TELEPHONE VARCHAR2(15) PATH 'telephone' - ) SI - WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-1PDT"]' - PASSING P.DOC AS "p" - ); - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![XML data to relational data](./images/img-8.png) - - - Furthermore, we can chain the XMLTable calls when we want to see data contained in multiple levels. For example, in the following example, the element PurchaseOrder is first decomposed to a relational view of two columns, reference as varchar2 and lineitem as XMLType. The lineitem column is then passed to a second XMLTable call to be broken into its various parts as multiple columns of relational values. - - ``` - - SELECT - PO.REFERENCE, - LI.* - FROM - PURCHASEORDER P, - XMLTABLE ( '/PurchaseOrder' - PASSING P.DOC - COLUMNS - REFERENCE VARCHAR2(30) PATH 'Reference', - LINEITEM XMLTYPE PATH 'LineItems/LineItem' - ) PO, - XMLTABLE ( '/LineItem' - PASSING PO.LINEITEM - COLUMNS - ITEMNO NUMBER(3) PATH '@ItemNumber', - PARTNO NUMBER(3) PATH 'Part', - DESCRIPTION VARCHAR2(25) PATH 'Part/@Description', - UNITPRICE NUMBER(8, 4) PATH 'Part/@UnitPrice', - QUANTITY NUMBER(12, 2) PATH 'Quantity' - ) LI - WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-1PDT"]' - PASSING P.DOC AS "p" - ); - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![XMLTABLE chain](./images/img-9.png) - - - In the above examples, we have used very simple XQuery expression, and XPath expression, and passed them to the XMLTable function. However, users can pass any XQuery expression they want. In the following queries, we will use a little bit of complex XQuery just for demonstration purposes. - - ``` - - SELECT - T.OBJECT_VALUE.GETCLOBVAL() - FROM - PURCHASEORDER P, - XMLTABLE ( 'for $r in /PurchaseOrder[Reference/text()=$REF] return $r' - PASSING P.DOC, - 'ROY-3PDT' AS "REF" - ) T; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![Complex xquery inside XMLTABLE](./images/img-10.png) - - - Similarly, we can have multiple predicates as follows: - - ``` - - SELECT - T.OBJECT_VALUE.GETCLOBVAL() - FROM - PURCHASEORDER P, - XMLTABLE ( 'for $r in /PurchaseOrder[CostCenter=$CC or Requestor=$REQUESTOR or count(LineItems/LineItem) > $QUANTITY]/Reference return $r' - PASSING P.DOC, - 'H1' AS "CC", - 'H. Roy 1' AS "REQUESTOR", - 1 AS "QUANTITY" - ) T; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". + COLUMNS + NAME VARCHAR2(15) PATH 'name', + STREET VARCHAR2(30) PATH 'Address/street', + CITY VARCHAR2(15) PATH 'Address/city', + STATE VARCHAR2(10) PATH 'Address/state', + ZIPCODE VARCHAR2(10) PATH 'Address/zipCode', + COUNTRY VARCHAR2(30) PATH 'Address/country', + TELEPHONE VARCHAR2(15) PATH 'telephone' + ) SI +WHERE + XMLEXISTS ('$p/PurchaseOrder[Reference="SBELL-2023PDT"]' + PASSING P.DOC AS "p" + ); +``` + +Copy the above statement into the worksheet area and press "Run Statement". - ![XQuery with multiple bind variables](./images/img-11.png) +![XML data to relational data](./images/img-8.png) + +Furthermore, we can chain (unnest) the XMLTable calls when we want to see data contained in multiple levels. For example, in the following example, the element PurchaseOrder is first decomposed to a relational view of two columns, reference as varchar2 and lineitem as XMLType. The lineitem column is then passed to a second XMLTable call to be broken into its various parts as multiple columns of relational values. + +``` + +SELECT + PO.REFERENCE, + LI.* +FROM + PURCHASEORDER P, + XMLTABLE ('/PurchaseOrder' + PASSING P.DOC + COLUMNS + REFERENCE VARCHAR2(30) PATH 'Reference', + LINEITEM XMLTYPE PATH 'LineItems/LineItem' + ) PO, + XMLTABLE ('/LineItem' + PASSING PO.LINEITEM + COLUMNS + ITEMNO NUMBER(3) PATH '@ItemNumber', + PARTNO NUMBER(12) PATH 'Part/@Id', + DESCRIPTION VARCHAR2(25) PATH 'Description', + UNITPRICE NUMBER(8, 4) PATH 'Part/@UnitPrice', + QUANTITY NUMBER(12, 2) PATH 'Quantity' + ) LI +WHERE + XMLEXISTS ('$p/PurchaseOrder[Reference="CJONES-2022PST"]' + PASSING P.DOC AS "p" + ); + +``` +Copy the above statement into the worksheet area and press "Run Statement". + +![XMLTABLE chain](./images/img-9.png) -6. Join relational tables with XML tables/columns +## Task 6: Join relational tables with XML tables/columns - In Q5, we saw that we can join XMLTable calls. Here, we will show that you can join relational tables with XMLTable as well. +In task 5 we used the XMLTable function to create an in-line relational view of XML content. The result can be used to join with other relational tables in the database. - Let’s first create a simple relational table, EMP, and then insert a few rows. +Let's first create a simple relational table, EMP, and then insert a few rows. We will use this table later on to join with our XML document table. - ``` - - CREATE TABLE EMP ( - ID NUMBER, - NAME VARCHAR(20) - ); +``` + +CREATE TABLE EMP ( + ID NUMBER, + NAME VARCHAR(20), + HIREDATE DATE +); - insert into emp values(1, 'H. Roy 1'); - insert into emp values(2, 'H. Roy 2'); - insert into emp values(3, 'H. Roy 3'); +insert into emp values(101, 'Sarah J. Bell', date '2001-06-01'); +insert into emp values(102, 'Cindy Jones', date '2019-01-20'); +insert into emp values(103, 'Michael Allen', date '2005-09-01'); - COMMIT; - - ``` +COMMIT; + +``` - Copy the above statement into the worksheet area and press "Run Statement". +Copy the above statement into the worksheet area and press "Run Statement" to insert our three sample rows. - ![EMP relational table](./images/img-12.png) +![EMP relational table](./images/img-12.png) - - ``` - - SELECT - * - FROM - EMP; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![EMP table entries](./images/img-13.png) - - - ``` - - SELECT - E.ID, - T.* - FROM - EMP E, - PURCHASEORDER P, - XMLTABLE ( 'for $r in /PurchaseOrder where $r/Reference=$REFERENCE return $r' - PASSING P.DOC, - 'ROY-1PDT' AS "REFERENCE" - COLUMNS - REQUESTOR PATH 'Requestor/text()', - INSTRUCTIONS PATH 'SpecialInstructions/text()' - ) T - WHERE - E.NAME = T.REQUESTOR - AND ROWNUM <= 5; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". +Check that we inserted the data correctly with the following statement. +``` + +SELECT + * +FROM + EMP; + +``` + +![EMP table entries](./images/img-13.png) + +Let us now join our relational table EMP with our XML documents on the extracted node REQUESTOR of our XML document. We could have also returned a combination of relational (scalar) data and XML documents or fragments. + +``` + +SELECT + E.ID, + T.* +FROM + EMP E, + PURCHASEORDER P, + XMLTABLE ('/PurchaseOrder' PASSING P.DOC + COLUMNS + REQUESTOR PATH 'Requestor/text()', + INSTRUCTIONS PATH 'SpecialInstructions/text()' + ) T +WHERE + E.NAME = T.REQUESTOR; + +``` + +Copy the above statement into the worksheet area and press "Run Statement". - ![Joining XMLTABLE and EMP, a relational table](./images/img-14.png) - - - In the above query, we have used the similar XMLTABLE query described in Q5 to keep it simple. Feel free to use other XMLTABLE queries and try different things. - -7. Construct a new response document - - Let’s assume we have some purchase order XML documents containing detailed purchase information. We want to generate a new and smaller XML document containing only the required information as a response to an application request. The following query just does that: - - ``` - - SELECT - XMLQUERY('{ - $XML/PurchaseOrder/Reference, - $XML/PurchaseOrder/User, - $XML/PurchaseOrder/SpecialInstructions - } - ' - PASSING P.DOC AS "XML" - RETURNING CONTENT).GETCLOBVAL() INITIAL_STATE - FROM - PURCHASEORDER P - WHERE - P.DOC IS NOT NULL; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". +![Joining XMLTABLE and EMP, a relational table](./images/img-14.png) + +## Task 7: Construct a new response XML document + +Let's assume we have some purchase order XML documents containing massive, detailed purchase information. We only want to generate a new and smaller XML document containing only the required information as a response to an application request. The following query just does that: + +``` + +SELECT + XMLQUERY('{ + $XML/PurchaseOrder/Reference, + $XML/PurchaseOrder/User, + $XML/PurchaseOrder/SpecialInstructions + } + ' + PASSING P.DOC AS "XML" + RETURNING CONTENT).GETCLOBVAL() INITIAL_STATE +FROM + PURCHASEORDER P +WHERE + P.DOC IS NOT NULL; + +``` + +Copy the above statement into the worksheet area and press "Run Statement". - ![Customized XML fragment](./images/img-15.png) - - - The following query will do just the same. - - ``` - - SELECT - T.OBJECT_VALUE.GETCLOBVAL() - FROM - PURCHASEORDER P, - XMLTABLE ( 'for $r in /PurchaseOrder - return - - { - $r/Reference, - $r/User, - $r/SpecialInstructions - } - ' - PASSING P.DOC - ) T - WHERE - P.DOC IS NOT NULL; - - ``` +![Customized XML fragment](./images/img-15.png) - Copy the above statement into the worksheet area and press "Run Statement". - - ![Customized XML fragment](./images/img-16.png) - - -8. Serialize XML data - - Now consider you have an application or product that does not support XMLType data. In that case, you can serialize the XML data as CLOB or BLOB and view or process it in your application or product. Oracle XML DB provides an XMLSerialize function to achieve this goal. XMLSerialize also allows control over the layout of the serialized XML: - - Here we are using the same Q7 queries inside the XMLSERIALIZE function. - - ``` - - SELECT - XMLSERIALIZE(CONTENT XMLQUERY('{ - $XML/PurchaseOrder/Reference, - $XML/PurchaseOrder/User, - $XML/PurchaseOrder/SpecialInstructions - } - ' - PASSING P.DOC AS "XML" - RETURNING CONTENT) AS CLOB INDENT SIZE = 2) XMLCONTENT - FROM - PURCHASEORDER P - WHERE - P.DOC IS NOT NULL; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![Serialize XML data](./images/img-17.png) - - - ``` - - SELECT - XMLSERIALIZE(CONTENT COLUMN_VALUE AS CLOB INDENT SIZE = 2) XMLCONTENT - FROM - PURCHASEORDER P, - XMLTABLE ( 'for $r in /PurchaseOrder - return - - { - $r/Reference, - $r/User, - $r/SpecialInstructions - } - ' - PASSING P.DOC - ) T - WHERE - P.DOC IS NOT NULL; - - ``` +## Task 8: Serialize XML data - Copy the above statement into the worksheet area and press "Run Statement". - - ![Serialize XML data](./images/img-18.png) +Consider you have an application or product that does not support XMLType data. In that case, you can serialize the XML data as CLOB or BLOB and view or process it in your application. Oracle XML DB provides an XMLSerialize function to achieve this goal. XMLSerialize also allows control over the layout of the serialized XML: -You may now **proceed to the next lab**. +``` + +SELECT XMLSERIALIZE(DOCUMENT doc as CLOB) XMLCONTENT +FROM purchaseorder p +WHERE XMLEXISTS ('$p/PurchaseOrder[Reference="MAllen-2024PST"]' + PASSING P.DOC AS "p" + ); + +``` + +![Customized XML fragment](./images/img-19.png)![Alt text](image.png) + +In this module you got a first taste of how to query and analyze your XML documents, combine it with relational data, and return your desired results in relational format, XML format, or a combination of both. You may now **proceed to the next lab**. ## Learn More -- [Database 19c - JSON] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=638) -- [Developing with JSON and SODA in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=831) -- [JSON without Limits] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=836) -- [Using the Database API for MongoDB] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3152) -- [Database API for MongoDB - The Basics] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3221) -- [Full-Text Search in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3286) -- [Autonomous Database Dedicated](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=677) -- [Manage and Monitor Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=553) -- [Scaling and Performance in the Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=608) + +* [Get started with Oracle Autonomous Database Serverless ](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/videos.html) +- [XML DB Developer's Guide](https://docs.oracle.com/en/database/oracle/oracle-database/23/adxdb/index.html) +- [Oracle XML DB](https://www.oracle.com/database/technologies/appdev/xmldb.html) ## Acknowledgements * **Author** - Harichandan Roy, Principal Member of Technical Staff, Oracle Document DB * **Contributors** - XDB Team -* **Last Updated By/Date** - Harichandan Roy, February 2023 +- **Last Updated By/Date** - Ernesto Alvarez, April 2024 diff --git a/xmldb/relational2xml/images/img-1.png b/xmldb/relational2xml/images/img-1.png index 38f79b9b4..33e2077e6 100644 Binary files a/xmldb/relational2xml/images/img-1.png and b/xmldb/relational2xml/images/img-1.png differ diff --git a/xmldb/relational2xml/images/img-2.png b/xmldb/relational2xml/images/img-2.png index e04c68e30..fb66eec8a 100644 Binary files a/xmldb/relational2xml/images/img-2.png and b/xmldb/relational2xml/images/img-2.png differ diff --git a/xmldb/relational2xml/images/img-3.png b/xmldb/relational2xml/images/img-3.png index 32d02b100..e8f80c594 100644 Binary files a/xmldb/relational2xml/images/img-3.png and b/xmldb/relational2xml/images/img-3.png differ diff --git a/xmldb/relational2xml/images/img-4.png b/xmldb/relational2xml/images/img-4.png index ea298b8e5..dd7fee5b5 100644 Binary files a/xmldb/relational2xml/images/img-4.png and b/xmldb/relational2xml/images/img-4.png differ diff --git a/xmldb/relational2xml/relational2xml.md b/xmldb/relational2xml/relational2xml.md index f3f699b80..f903f31d6 100644 --- a/xmldb/relational2xml/relational2xml.md +++ b/xmldb/relational2xml/relational2xml.md @@ -1,92 +1,71 @@ -# Convert relational data to XML data +# Generate XML data from relational tables ## Introduction -Some applications expect XML data or in some contexts, we might need data in XML format. Let's assume that we have all the data that we need to feed to applications in relational tables. Oracle XML DB will help you generate XML data from relational tables. -Estimated Time: 20 minutes +Estimated Time: 10 minutes ### Objectives In this lab, you will learn: -- Generating XML data from relational data +- How to generate XML data from relational data ### Prerequisites -- Be logged into your Oracle Cloud Account. +- Be logged into your Oracle Cloud Account and have access to the SQL Worksheet in Database Actions. -## Task 1: SQL/XML publishing functions -- XMLElement - Returns an XML value that is an XML element. -- XMLAttributes - Constructs XML attributes from the arguments. This function can be used only as an argument of the XMLELEMENT function. -- XMLForest - Returns an XML value that is a sequence of XML elements. -- XMLConcat - Returns a sequence containing the concatenation of a variable number of XML input arguments. -- XMLAgg - Returns an XML sequence containing an item for each non-null value in a set of XML values. +## Task 1: Generate XML data from relational tables -## Task 2: Open Database Actions -1. Log in to the Oracle Cloud. -2. If you are using a Free Trial or Always Free account, and you want to use Always Free Resources, you need to be in a region where Always Free Resources are available. You can see your current default Region in the top, right-hand corner of the page. -3. Click the navigation menu in the upper left to show top-level navigation choices. -4. Click on Oracle Database and choose Autonomous Transaction Processing. -5. If using FreeTier, your compartment should be the root compartment for your tenancy. -Note: Avoid the use of the ManagedCompartmentforPaaS compartment as this is an Oracle default used for Oracle Platform Services. -6. You should see your database XMLDB listed in the center. Click on the database name "XMLDB". -7. On the database page, choose Database Actions. -8. You are now in Database Actions. -Database Actions allows you to connect to your Autonomous Database through various browser-based tools. We will just be using the SQL workshop tool. -9. You should be in the Database Actions panel. Click on the SQL card - -## Task 3: Create XMLType Views -We have learned how to generate relational data from XML content in Lab 4. In this lab, we will do just the opposite. We will generate XML content from relational data. In many ways, it will be useful. Just for example, you can send data from relational tables as a response to an application’s request in XML format. Let’s see how to achieve that. +We have learned how to generate relational data from XML content in Lab 4. Now we will do the reverse and generate XML content from relational data. In many ways, it will be useful. Just for example, you can send data from relational tables as a response to an application’s request in XML format. Let’s see how to achieve that. First, we will create two relational tables and then populate them with some sample data. -Table departments: +Table locations: ``` -CREATE TABLE DEPARTMENTS ( - DEPARTMENT_ID NUMBER(4), - DEPARTMENT_NAME VARCHAR2(30), - MANAGER_ID NUMBER(6), - LOCATION_ID NUMBER(4) +CREATE TABLE LOCATIONS ( + LOCATION_ID NUMBER(4) PRIMARY KEY, + STREET_ADDRESS VARCHAR2(40), + POSTAL_CODE VARCHAR2(12), + CITY VARCHAR2(30), + STATE_PROVINCE VARCHAR2(25), + COUNTRY_ID CHAR(2) ); ``` Copy the above statement into the worksheet area and press "Run Statement". -![DEPARTMENTS table](./images/img-1.png) - +![LOCATIONS table](./images/img-2.png) -Table locations: +Table departments: ``` -CREATE TABLE LOCATIONS ( - LOCATION_ID NUMBER(4), - STREET_ADDRESS VARCHAR2(40), - POSTAL_CODE VARCHAR2(12), - CITY VARCHAR2(30), - STATE_PROVINCE VARCHAR2(25), - COUNTRY_ID CHAR(2) +CREATE TABLE DEPARTMENTS ( + DEPARTMENT_ID NUMBER(4) PRIMARY KEY, + DEPARTMENT_NAME VARCHAR2(30), + MANAGER_ID NUMBER(6), + LOCATION_ID NUMBER(4) REFERENCES LOCATIONS(LOCATION_ID) ); ``` Copy the above statement into the worksheet area and press "Run Statement". -![LOCATIONS table](./images/img-2.png) +![DEPARTMENTS table](./images/img-1.png) ``` -insert into departments values (10, 'Administration', 200, 1100); -insert into departments values (20, 'Human Resources', 203, 1200); -insert into departments values (30, 'Shipping', 121, 1300); -insert into departments values (40, 'Purchasing', 114, 1400); -insert into departments values (50, 'Marketing', 201, 1500); - insert into locations values (1100, '1291 Abc', '94061', 'Redwood City', 'CA', 'US'); insert into locations values (1200, '1292 Abc', '94061', 'Redwood City', 'CA', 'US'); insert into locations values (1300, '1293 Abc', '94061', 'Redwood City', 'CA', 'US'); insert into locations values (1400, '1294 Abc', '94061', 'Redwood City', 'CA', 'US'); insert into locations values (1500, '1295 Abc', '94061', 'Redwood City', 'CA', 'US'); +insert into departments values (10, 'Administration', 200, 1100); +insert into departments values (20, 'Human Resources', 203, 1200); +insert into departments values (30, 'Shipping', 121, 1300); +insert into departments values (40, 'Purchasing', 114, 1400); +insert into departments values (50, 'Marketing', 201, 1500); + commit; ``` @@ -95,164 +74,53 @@ Copy the above statement into the worksheet area and press "Run Statement". ![Populate and DEPARTMENTS LOCATIONS](./images/img-3.png) - - -1. Generate XML data - - This query will transform relational data into XML data. +This query will generate XML data from DEPARTMENTS table and LOCATIONS table based on the primary key and foreign key relationship of these two tables. - ``` - - SELECT +``` + +SELECT + XMLELEMENT( + "Department", + XMLATTRIBUTES( + D.DEPARTMENT_ID AS "DepartmentId" + ), XMLELEMENT( - "Department", - XMLATTRIBUTES( - D.DEPARTMENT_ID AS "DepartmentId" - ), - XMLELEMENT( - "Name", - D.DEPARTMENT_NAME - ), - XMLELEMENT( - "Location", - XMLFOREST(STREET_ADDRESS AS "Address", - CITY AS "City", - STATE_PROVINCE AS "State", - POSTAL_CODE AS "Zip", - COUNTRY_ID AS "Country") - ) - ).GETCLOBVAL() - FROM - DEPARTMENTS D, - LOCATIONS L - WHERE - D.LOCATION_ID = L.LOCATION_ID; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![XML data from relational data](./images/img-4.png) - - - -2. Create XMLType views - - Now we will create a persistent XMLType view and then run XQuery over it. - - ``` - - CREATE OR REPLACE VIEW V_DEPARTMENTS_XML OF XMLTYPE - WITH OBJECT ID - ( - XMLCAST(XMLQUERY('/Department/Name' PASSING OBJECT_VALUE - RETURNING CONTENT) AS VARCHAR2(30)) - ) - AS - SELECT + "Name", + D.DEPARTMENT_NAME + ), XMLELEMENT( - "Department", - XMLATTRIBUTES( - D.DEPARTMENT_ID AS "DepartmentId" - ), - XMLELEMENT( - "Name", - D.DEPARTMENT_NAME - ), - XMLELEMENT( - "Location", - XMLFOREST(STREET_ADDRESS AS "Address", - CITY AS "City", - STATE_PROVINCE AS "State", - POSTAL_CODE AS "Zip", - COUNTRY_ID AS "Country")) + "Location", + XMLFOREST(STREET_ADDRESS AS "Address", + CITY AS "City", + STATE_PROVINCE AS "State", + POSTAL_CODE AS "Zip", + COUNTRY_ID AS "Country") ) - FROM - DEPARTMENTS D, - LOCATIONS L - WHERE - D.LOCATION_ID = L.LOCATION_ID; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![XMLType view](./images/img-5.png) - - - - ``` - - SELECT - V.OBJECT_VALUE.GETCLOBVAL() - FROM - V_DEPARTMENTS_XML V; - - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![XMLType view content](./images/img-6.png) - - -3. Query over XMLType views - - Let's find a department named "Administration". - - ``` - - SELECT - T.GETCLOBVAL() - FROM - V_DEPARTMENTS_XML D, - XMLTABLE ( 'for $r in /Department[Name="Administration"] - return $r' - PASSING OBJECT_VALUE - ) T; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![Administration department](./images/img-7.png) - - - - Or let’s find the location of the Marketing department. + ).GETCLOBVAL() +FROM + DEPARTMENTS D, + LOCATIONS L +WHERE + D.LOCATION_ID = L.LOCATION_ID; + +``` - ``` - - SELECT - T.GETCLOBVAL() - FROM - V_DEPARTMENTS_XML D, - XMLTABLE ( 'for $r in /Department[Name="Marketing"] - return $r/Location' - PASSING OBJECT_VALUE - ) T; - - ``` +Copy the above statement into the worksheet area and press "Run Statement". - Copy the above statement into the worksheet area and press "Run Statement". +![XML data from relational data](./images/img-4.png) - ![Department location](./images/img-8.png) +You have just experienced in just a couple of minutes how easy it is to generate XML documents from relational data. It's equally easy to wrap such statements in a view and expose our XML documents transparently for any application, hiding the XML generation statement within a view definition. You may now **proceed to the next lab**. ## Learn More -- [Database 19c - JSON] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=638) -- [Developing with JSON and SODA in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=831) -- [JSON without Limits] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=836) -- [Using the Database API for MongoDB] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3152) -- [Database API for MongoDB - The Basics] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3221) -- [Full-Text Search in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3286) -- [Autonomous Database Dedicated](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=677) -- [Manage and Monitor Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=553) -- [Scaling and Performance in the Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=608) + +* [Get started with Oracle Autonomous Database Serverless ](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/videos.html) +- [XML DB Developer's Guide](https://docs.oracle.com/en/database/oracle/oracle-database/23/adxdb/index.html) +- [Oracle XML DB](https://www.oracle.com/database/technologies/appdev/xmldb.html) ## Acknowledgements * **Author** - Harichandan Roy, Principal Member of Technical Staff, Oracle Document DB * **Contributors** - XDB Team -* **Last Updated By/Date** - Harichandan Roy, February 2023 +- **Last Updated By/Date** - Ernesto Alvarez, April 2024 diff --git a/xmldb/update/images/img-0.png b/xmldb/update/images/img-0.png new file mode 100644 index 000000000..71c21be2d Binary files /dev/null and b/xmldb/update/images/img-0.png differ diff --git a/xmldb/update/images/img-1.png b/xmldb/update/images/img-1.png index 4c77b7eac..0d41f4787 100644 Binary files a/xmldb/update/images/img-1.png and b/xmldb/update/images/img-1.png differ diff --git a/xmldb/update/images/img-10.png b/xmldb/update/images/img-10.png index 8db82cad8..c5b96c1c9 100644 Binary files a/xmldb/update/images/img-10.png and b/xmldb/update/images/img-10.png differ diff --git a/xmldb/update/images/img-11.png b/xmldb/update/images/img-11.png index 8db82cad8..262a25123 100644 Binary files a/xmldb/update/images/img-11.png and b/xmldb/update/images/img-11.png differ diff --git a/xmldb/update/images/img-12.png b/xmldb/update/images/img-12.png index 1471b8009..54770c6f0 100644 Binary files a/xmldb/update/images/img-12.png and b/xmldb/update/images/img-12.png differ diff --git a/xmldb/update/images/img-13.png b/xmldb/update/images/img-13.png index 022df95f0..f14432b6e 100644 Binary files a/xmldb/update/images/img-13.png and b/xmldb/update/images/img-13.png differ diff --git a/xmldb/update/images/img-14.png b/xmldb/update/images/img-14.png index 2590057f9..f6cf81274 100644 Binary files a/xmldb/update/images/img-14.png and b/xmldb/update/images/img-14.png differ diff --git a/xmldb/update/images/img-4.png b/xmldb/update/images/img-4.png index 047e20c74..ab7431229 100644 Binary files a/xmldb/update/images/img-4.png and b/xmldb/update/images/img-4.png differ diff --git a/xmldb/update/images/img-5.png b/xmldb/update/images/img-5.png index 363c6ffe5..51931e4f6 100644 Binary files a/xmldb/update/images/img-5.png and b/xmldb/update/images/img-5.png differ diff --git a/xmldb/update/images/img-6.png b/xmldb/update/images/img-6.png index e5bf43404..3e3424632 100644 Binary files a/xmldb/update/images/img-6.png and b/xmldb/update/images/img-6.png differ diff --git a/xmldb/update/images/img-7.png b/xmldb/update/images/img-7.png index 3254e84ca..b880968e5 100644 Binary files a/xmldb/update/images/img-7.png and b/xmldb/update/images/img-7.png differ diff --git a/xmldb/update/images/img-8.png b/xmldb/update/images/img-8.png index 77bc6ab95..f62e74aa1 100644 Binary files a/xmldb/update/images/img-8.png and b/xmldb/update/images/img-8.png differ diff --git a/xmldb/update/images/img-9.png b/xmldb/update/images/img-9.png index d0d541f33..bd69f6c98 100644 Binary files a/xmldb/update/images/img-9.png and b/xmldb/update/images/img-9.png differ diff --git a/xmldb/update/update.md b/xmldb/update/update.md index cebd6343c..8f3d5846a 100644 --- a/xmldb/update/update.md +++ b/xmldb/update/update.md @@ -1,16 +1,13 @@ -# Update XML content +# Update your XML documents ## Introduction -This lab will use the SQL Workshop in Database Actions from the Autonomous Transaction Processing page. In this lab, we will explore XQuery to update and manipulate XML content in Oracle XML DB. XQuery is one of the main ways that you interact with XML data in Oracle XML DB. It is the W3C language designed for querying and updating XML data. -The support for the XQuery Language is provided through a native implementation of SQL/XML functions: XMLQuery, XMLTable, XMLExists, and XMLCast. These SQL/XML functions are defined by the SQL/XML standard as a general interface between the SQL and XQuery languages. +In this lab, we will explore XQuery to update and manipulate XML content in Oracle XML DB using SQL/XML functions. XQuery is one of the main ways that you interact with XML data in Oracle XML DB. It is the W3C language designed for querying and updating XML data. -Estimated Time: 30 minutes +Estimated Time: 20 minutes ### Objectives -In this lab, you will learn: -- XQuery basics, -- SQL/XML basics, +In this lab, you do the following exercises: - Updating an entire XML document, - Replacing XML nodes, - Inserting XML nodes, @@ -18,64 +15,29 @@ In this lab, you will learn: - Creating XML Views of customized data ### Prerequisites -- Be logged into your Oracle Cloud Account. +- Be logged into your Oracle Cloud Account and have access to the SQL Worksheet in Database Actions. -## Task 1: XQuery Basics -XQuery is the W3C language designed for querying and updating XML data. The core part of it is the XQuery expression. XQuery expressions are case-sensitive. An XQuery expression is either a simple expression or an updating expression, the latter being an expression that represents data modification. More precisely, these are the possible XQuery expressions: - -- Basic updating expression – an insert, delete, replace, or rename expression, or a call to an updating function. -- Updating expression – a basic updating expression or an expression (other than a transform expression) that contains another updating expression (this is a recursive definition). -- Simple expression – An XQuery 1.0 expression. It does not call for any updating. -Simple expressions include the following: - - Primary expression – literal, variable, or function application. A variable name starts with a dollar sign ($) – for example, $foo. Literals include numerals, strings, and character or entity references. - - XPath expression – Any XPath expression. The XPath 2.0 standard is a subset of XQuery. - - FLWOR expression – The most important XQuery expression, composed of the following, in order, from which FLWOR takes its name: for, let, where, order by, and return. - - XQuery sequence – The comma (,) constructor creates sequences. Sequence-manipulating functions such as union and intersect are also available. All XQuery sequences are effectively flat: a nested sequence is treated as its flattened equivalent. Thus, for instance, (1, 2, (3, 4, (5), 6), 7) is treated as (1, 2, 3, 4, 5, 6, 7). A singleton sequence, such as (42), acts the same in most XQuery contexts as does its single item, 42. Remember that the result of any XQuery expression is a sequence. -- And Conditional, Arithmetic, Relational expressions, and so on. - -In this lab, we don’t intend to discuss XQuery in detail, please refer to the links below for more information about XQuery. - -The overview of XQuery language: [XQuery Overview] (https://docs.oracle.com/en/database/oracle/oracle-database/21/adxdb/xquery-and-XML-DB.html#GUID-927FB610-9553-4772-8D3E-FAA7546C4371) - -The W3C XQuery link: [W3C Xquery] (https://www.w3.org/TR/xquery-31/) - -## Task 2: SQL/XML Basics - -SQL/XML functions, XMLQuery, XMLTable, XMLExists, and XMLCast, are defined by the SQL/XML standard as a general interface between SQL and XQuery languages. Using these functions, you can construct XML data using relational data, query relational data as if it were XML data, and construct relational data from XML data. - -Here is a short overview of these SQL/XML functions: -- XMLQuery - Use this function to construct or query XML data. It takes an XQuery expression as an argument and returns the result of evaluating the XQuery expression, as an XMLType instance. (Example in Task 4.2) - -- XMLTable - Use this function XMLTable to decompose the result of an XQuery-expression evaluation into the relational rows and columns of a new, virtual table. You can insert this data into a pre-existing database table, or you can query it using SQL — in a join expression, for example. - -- XMLExists - Use this function to check whether a given XQuery expression returns a non-empty XQuery sequence. If so, the function returns TRUE. Otherwise, it returns FALSE. (Example in Task 4.2) - -- XMLCast - Use this function to cast an XQuery value to a SQL data type. (Example in Task 4.5) - -Here is the link for more information: [XQL/XML functions] (https://docs.oracle.com/en/database/oracle/oracle-database/21/adxdb/xquery-and-XML-DB.html#GUID-4805CF1C-A00D-4B88-AF2E-00A9DB6F3392) - -## Task 3: Open Database Actions +## Task 1: Update an entire XML document + +We can simply use the standard SQL update statement to update an entire XML document. + +1. First, let's create a backup table that we want to use for rollback. With our web-based SQL Worksheet the communication with the database is through REST, so we cannot run an update statement and a subsequent rollback individually through the web interface. REST-based communication is using auto commit. + ``` + + DROP TABLE PO_BACKUP PURGE; -1. Log in to the Oracle Cloud. -2. If you are using a Free Trial or Always Free account, and you want to use Always Free Resources, you need to be in a region where Always Free Resources are available. You can see your current default Region in the top, right-hand corner of the page. -3. Click the navigation menu in the upper left to show top-level navigation choices. -4. Click on Oracle Database and choose Autonomous Transaction Processing. -5. If using FreeTier, your compartment should be the root compartment for your tenancy. -Note: Avoid the use of the ManagedCompartmentforPaaS compartment as this is an Oracle default used for Oracle Platform Services. -6. You should see your database XMLDB listed in the center. Click on the database name "XMLDB". -7. On the database page, choose Database Actions. -8. You are now in Database Actions. -Database Actions allows you to connect to your Autonomous Database through various browser-based tools. We will just be using the SQL workshop tool. -9. You should be in the Database Actions panel. Click on the SQL card + CREATE TABLE PO_BACKUP + AS + SELECT * + FROM + PURCHASEORDER; + + ``` + ![Backup table](./images/img-0.png) -## Task 4: Update XML Content -1. Update an entire XML document - - We can simply use the standard SQL update statement to update an entire XML document. - - Let’s check the content before issuing an updated statement. +2. Now let's check the content we are going to update before issuing the update statement. ``` @@ -90,11 +52,9 @@ Database Actions allows you to connect to your Autonomous Database through vario Copy the above statement into the worksheet area and press "Run Statement". - ![Pre-update](./images/img-1.png) + ![Pre-update](./images/img-1.png) - - - Then, run the following SQL update statement to update an entire XML document. +2. Then, run the following SQL update statement to update an entire XML document. Warning: this will override your sample content with, well, nothing that makes business sense. But it's at least valid XML ... ``` @@ -112,7 +72,7 @@ Database Actions allows you to connect to your Autonomous Database through vario - Now let’s check the updated content. + Now let’s check the updated content and see the "updated doc" that you just updated to. ``` @@ -129,23 +89,36 @@ Database Actions allows you to connect to your Autonomous Database through vario ![Post-update](./images/img-3.png) - You should see the updated XML doc for id 1. + You should see the updated XML doc for id 1. That's content we do not want to see, so let's do the next step. - Now roll back to the previous content. +3. Roll back to the previous content so that we can re-do this again at a later point in time if we want. + + ``` + + UPDATE PURCHASEORDER P + SET + P.DOC = (SELECT DOC FROM PO_BACKUP B WHERE B.ID = 1) + WHERE + P.ID = 1; + + SELECT P.DOC.GETCLOBVAL() FROM PURCHASEORDER P WHERE P.ID = 1; + + + ``` ![Rollback](./images/img-4.png) -2. Replace XML nodes +## Task 2: Replace XML nodes - In the previous example, we replaced the entire document. However, in most practical scenarios we just need to modify a part of the document. To do that, we can use XQuery update with a SQL update statement. +In the previous example, we replaced the entire document. However, in most practical scenarios we just need to modify a part of the document. To do that, we can use XQuery update with a SQL update statement. - In the following example, we will update the Requestor info in the XML document with the Reference value as 'ROY-3PDT'. +In the following example, we will update the Requestor info in the XML document with the Reference value as 'MAllen-2024PST'. - First, let's see the current value of the Requestor node. +1. First, let's see the current value of the Requestor node. ``` @@ -156,7 +129,7 @@ Database Actions allows you to connect to your Autonomous Database through vario FROM PURCHASEORDER PO WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-3PDT"]' + XMLEXISTS ( '$p/PurchaseOrder[Reference="MAllen-2024PST"]' PASSING PO.DOC AS "p" ); @@ -166,9 +139,7 @@ Database Actions allows you to connect to your Autonomous Database through vario ![Pre-update](./images/img-5.png) - - - Now we pass the new value 'XDB Team' as a variable $p2 to the XQuery expression and evaluate the expression for the documents having Reference value as 'ROY-3PDT'. +2. Now we pass the new value 'XDB Team' as a variable $p2 to the XQuery expression and evaluate the expression for the documents having Reference value as 'MAllen-2024PST'. ``` @@ -182,7 +153,7 @@ Database Actions allows you to connect to your Autonomous Database through vario 'XDB Team' AS "p2" RETURNING CONTENT) WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-3PDT"]' + XMLEXISTS ( '$p/PurchaseOrder[Reference="MAllen-2024PST"]' PASSING PO.DOC AS "p" ); @@ -194,7 +165,7 @@ Database Actions allows you to connect to your Autonomous Database through vario - Now let’s see the updated content. +3. Let’s see the updated content. ``` @@ -205,11 +176,9 @@ Database Actions allows you to connect to your Autonomous Database through vario FROM PURCHASEORDER PO WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-3PDT"]' + XMLEXISTS ( '$p/PurchaseOrder[Reference="MAllen-2024PST"]' PASSING PO.DOC AS "p" ); - - ROLLBACK; ``` @@ -217,13 +186,13 @@ Database Actions allows you to connect to your Autonomous Database through vario ![Post-update](./images/img-7.png) - +That is a change we like. You don't have to rollback the operation, but feel free to do so. -3. Insert XML nodes +## Task 3: Insert XML nodes - The user may want to add a new XML node to an XML document. This example inserts a new LineItem element as a child of the element LineItems. +The user may want to add a new XML node to an XML document. This example inserts a new LineItem element as a child of the element LineItems. - Before inserting a new XML node, let’s check the current content using this query: +1. Before inserting a new XML node, let’s check the current content using this query: ``` @@ -234,19 +203,17 @@ Database Actions allows you to connect to your Autonomous Database through vario FROM PURCHASEORDER PO WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-3PDT"]' + XMLEXISTS ( '$p/PurchaseOrder[Reference="MAllen-2024PST"]' PASSING PO.DOC AS "p" ); ``` - Copy the above statement into the worksheet area and press "Run Statement". - - ![Pre-update](./images/img-8.png) + Copy the above statement into the worksheet area and press "Run Statement". If you have not updated the data before and are arriving here for the first time, you will see that there is no XML node with itemNumber = 5. - + ![Pre-update](./images/img-8.png) - Now we will use the XQuery update statement to insert a new XML node into the document. The following query is inserting a new XML node LineItem with ItemNumber = 5 into an XML document having "ROY-3PDT" as its Reference value. +2. Now we will use the XQuery update statement to insert a new XML node into the document. The following query is inserting a new XML node LineItem with ItemNumber = 5 into an XML document having "MAllen-2024PST" as its Reference value. ``` @@ -259,12 +226,13 @@ Database Actions allows you to connect to your Autonomous Database through vario return $i' PASSING PO.DOC AS "p1", XMLTYPE(' - 1 - 1 - ') AS "p2" + + Keyboard + 1 + ') AS "p2" RETURNING CONTENT) WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-3PDT"]' + XMLEXISTS ( '$p/PurchaseOrder[Reference="MAllen-2024PST"]' PASSING PO.DOC AS "p" ); @@ -274,9 +242,7 @@ Database Actions allows you to connect to your Autonomous Database through vario ![Update](./images/img-9.png) - - - Whether the new XML node was inserted or not, let’s run this query and see if it’s there: +3. Whether the new XML node was inserted or not, let’s run this query and see if it’s there: ``` @@ -287,23 +253,21 @@ Database Actions allows you to connect to your Autonomous Database through vario FROM PURCHASEORDER PO WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-3PDT"]' + XMLEXISTS ( '$p/PurchaseOrder[Reference="MAllen-2024PST"]' PASSING PO.DOC AS "p" ); ``` - Copy the above statement into the worksheet area and press "Run Statement". + Copy the above statement into the worksheet area and press "Run Statement". If you have executed the update statement in the previous section, then you will see a new lineitem with ItemNumber=5 as shown below. Note the subtlety that the insertion of a new lineitem in your XML document is actually semantically an update of the document. ![Post-update](./images/img-10.png) +## Task 4: Delete XML nodes +In this example, we will use an XQuery update statement to delete an XML node, LineItem with ItemNumber = 5 from the XML documents having "MAllen-2024PST" as the Reference value. -4. Delete XML nodes - - In this example, we will use an XQuery update statement to delete an XML node, LineItem with ItemNumber = 5 from the XML documents having "ROY-3PDT" as the Reference value. - - Let’s first check the current content in the document: +1. Let’s first check the current content in the document. If you did the previous exercise, you should see an ItemNumber=5 ``` @@ -314,7 +278,7 @@ Database Actions allows you to connect to your Autonomous Database through vario FROM PURCHASEORDER PO WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-3PDT"]' + XMLEXISTS ( '$p/PurchaseOrder[Reference="MAllen-2024PST"]' PASSING PO.DOC AS "p" ); @@ -323,10 +287,9 @@ Database Actions allows you to connect to your Autonomous Database through vario Copy the above statement into the worksheet area and press "Run Statement". ![Pre-update](./images/img-11.png) - - Then run the following update statement to delete the XML node: +2. Let's now run the following update statement to delete the XML node: ``` @@ -338,7 +301,7 @@ Database Actions allows you to connect to your Autonomous Database through vario PASSING PO.DOC AS "p" RETURNING CONTENT) WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-3PDT"]' + XMLEXISTS ( '$p/PurchaseOrder[Reference="MAllen-2024PST"]' PASSING PO.DOC AS "p" ); @@ -346,11 +309,9 @@ Database Actions allows you to connect to your Autonomous Database through vario Copy the above statement into the worksheet area and press "Run Statement". - ![Update](./images/img-12.png) + ![Update](./images/img-12.png) - - - Now let’s check the updated content of the documents. +3. Now let’s check the updated content of the documents. ``` @@ -361,7 +322,7 @@ Database Actions allows you to connect to your Autonomous Database through vario FROM PURCHASEORDER PO WHERE - XMLEXISTS ( '$p/PurchaseOrder[Reference="ROY-3PDT"]' + XMLEXISTS ( '$p/PurchaseOrder[Reference="MAllen-2024PST"]' PASSING PO.DOC AS "p" ); @@ -369,103 +330,48 @@ Database Actions allows you to connect to your Autonomous Database through vario Copy the above statement into the worksheet area and press "Run Statement". - ![Post-update](./images/img-13.png) - - - -5. Create an XML View of customized data - - Sometimes the size of the XML document is very big, or it may have some information that users are not interested in or maybe some confidentiality or other reasons, the users may want to see some customized or synthesized or even null data in some fields of the documents. In this example, we will show you how to achieve that. This query nullifies some of its content. - - ``` - - SELECT - XMLQUERY('copy $i := $p1 modify - ((for $j in $i/PurchaseOrder/Actions - return replace value of node $j with ()), - (for $j in $i/PurchaseOrder/ShippingInstructions - return replace value of node $j with ()), - (for $j in $i/PurchaseOrder/LineItems - return replace value of node $j with ())) - return $i' - PASSING PO.DOC AS "p1" - RETURNING CONTENT).GETCLOBVAL() RESPONSE - FROM - PURCHASEORDER PO - WHERE - PO.ID = 2; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". - - ![Pre-update](./images/img-14.png) - - - - Now let’s create a view on this. - - ``` - - CREATE OR REPLACE VIEW V_PO_SUMMARY OF XMLTYPE - WITH OBJECT ID - ( - XMLCAST(XMLQUERY('/PurchaseOrder/Reference' PASSING OBJECT_VALUE - RETURNING CONTENT) AS VARCHAR2(30)) - ) - AS - SELECT - XMLQUERY('copy $i := $p1 modify - ((for $j in $i/PurchaseOrder/Actions - return replace value of node $j with ()), - (for $j in $i/PurchaseOrder/ShippingInstructions - return replace value of node $j with ()), - (for $j in $i/PurchaseOrder/LineItems - return replace value of node $j with ())) - return $i' - PASSING PO.DOC AS "p1" - RETURNING CONTENT) - FROM - PURCHASEORDER PO - WHERE - PO.ID = 2; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". + ![Post-update](./images/img-13.png) - ![Update](./images/img-15.png) +You just have experienced how easy it is to change your XML documents, either as a whole or individual fragments of your XML document. +## Task 5: Create an XML View of customized data +Sometimes the size of the XML document is very big, or it may have some information that users are not interested in or maybe some confidentiality or other reasons, the users may want to see some customized or synthesized or even null data in some fields of the documents. In this example, we will show you how to achieve that. This query nullifies some of its content and returns the remaining document. + +``` + +SELECT + XMLQUERY('copy $i := $p1 modify + ((for $j in $i/PurchaseOrder/Actions + return replace value of node $j with ()), + (for $j in $i/PurchaseOrder/ShippingInstructions + return replace value of node $j with ()), + (for $j in $i/PurchaseOrder/LineItems + return replace value of node $j with ())) + return $i' + PASSING PO.DOC AS "p1" + RETURNING CONTENT).GETCLOBVAL() RESPONSE +FROM + PURCHASEORDER PO +WHERE + PO.ID = 2; + +``` - ``` - - SELECT - T.OBJECT_VALUE.GETCLOBVAL() - FROM - V_PO_SUMMARY T; - - ``` - - Copy the above statement into the worksheet area and press "Run Statement". +Copy the above statement into the worksheet area and press "Run Statement". - ![Post-update](./images/img-16.png) +![Pre-update](./images/img-14.png) -You may now **proceed to the next lab**. +Congratulations. You went through all the basics of working with XML documents in the Oracle Database. You may now **proceed to the next lab** and clean up your environment, if desired. ## Learn More -- [Database 19c - JSON] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=638) -- [Developing with JSON and SODA in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=831) -- [JSON without Limits] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=836) -- [Using the Database API for MongoDB] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3152) -- [Database API for MongoDB - The Basics] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3221) -- [Full-Text Search in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3286) -- [Autonomous Database Dedicated](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=677) -- [Manage and Monitor Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=553) -- [Scaling and Performance in the Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=608) + +* [Get started with Oracle Autonomous Database Serverless ](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/videos.html) +- [XML DB Developer's Guide](https://docs.oracle.com/en/database/oracle/oracle-database/23/adxdb/index.html) +- [Oracle XML DB](https://www.oracle.com/database/technologies/appdev/xmldb.html) ## Acknowledgements * **Author** - Harichandan Roy, Principal Member of Technical Staff, Oracle Document DB * **Contributors** - XDB Team -* **Last Updated By/Date** - Harichandan Roy, February 2023 +- **Last Updated By/Date** - Ernesto Alvarez, April 2024 diff --git a/xmldb/workshops/desktop/manifest.json b/xmldb/workshops/desktop/manifest.json index aed05f7cb..cc51ffbf8 100644 --- a/xmldb/workshops/desktop/manifest.json +++ b/xmldb/workshops/desktop/manifest.json @@ -18,27 +18,27 @@ "filename": "../../provision/provision.md" }, { - "title": "Lab 2: Create tables and populate data", + "title": "Lab 2: Create your first XML table and insert some XML documents", "filename": "../../populate/populate.md" }, { - "title": "Lab 3: Run queries", + "title": "Lab 3: Analyze your data using SQL and XQuery", "filename": "../../queries/queries.md" }, { - "title": "Lab 4: Generate relational data from XML data", + "title": "Lab 4: Expose your XML documents transparently as relational data", "filename": "../../xml2relational/xml2relational.md" }, { - "title": "Lab 5: Convert relational data to XML data", + "title": "Lab 5: Generate XML documents from relational tables", "filename": "../../relational2xml/relational2xml.md" }, { - "title": "Lab 6: Index XML data", + "title": "Lab 6: Index your XML documents", "filename": "../../index/index.md" }, { - "title": "Lab 7: Update XML content", + "title": "Lab 7: Update your XML documents", "filename": "../../update/update.md" }, { diff --git a/xmldb/workshops/tenancy/manifest.json b/xmldb/workshops/tenancy/manifest.json index aed05f7cb..851fbd106 100644 --- a/xmldb/workshops/tenancy/manifest.json +++ b/xmldb/workshops/tenancy/manifest.json @@ -1,10 +1,10 @@ { - "workshoptitle": "Oracle XML DB: store and process XML documents", + "workshoptitle": "Oracle XML DB: Store, Manage, and Process XML documents in the Oracle Database", "help": "livelabs-help-db_us@oracle.com", "tutorials": [ { "title": "Introduction", - "description": "The introduction of Oracle XML DB basic capabilities.", + "description": "Introduction of Oracle XML DB capabilities", "filename": "../../introduction/introduction.md" }, { @@ -13,32 +13,32 @@ "filename": "https://oracle-livelabs.github.io/common/labs/cloud-login/pre-register-free-tier-account.md" }, { - "title": "Lab 1: Provision an autonomous database", + "title": "Lab 1: Provision an Autonomous Database", "description": "Labs that follow the introduction are numbered, starting with Lab 1", "filename": "../../provision/provision.md" }, { - "title": "Lab 2: Create tables and populate data", + "title": "Lab 2: Create XML tables and populate XML documents", "filename": "../../populate/populate.md" }, { - "title": "Lab 3: Run queries", + "title": "Lab 3: Run queries against your XML documents", "filename": "../../queries/queries.md" }, { - "title": "Lab 4: Generate relational data from XML data", + "title": "Lab 4: Generate relational data from your XML documents", "filename": "../../xml2relational/xml2relational.md" }, { - "title": "Lab 5: Convert relational data to XML data", + "title": "Lab 5: Convert relational data to XML documents", "filename": "../../relational2xml/relational2xml.md" }, { - "title": "Lab 6: Index XML data", + "title": "Lab 6: Index XML documents", "filename": "../../index/index.md" }, { - "title": "Lab 7: Update XML content", + "title": "Lab 7: Update XML documents", "filename": "../../update/update.md" }, { diff --git a/xmldb/xml2relational/images/img-1.png b/xmldb/xml2relational/images/img-1.png index f4a60fef0..d8b179fe2 100644 Binary files a/xmldb/xml2relational/images/img-1.png and b/xmldb/xml2relational/images/img-1.png differ diff --git a/xmldb/xml2relational/images/img-4.png b/xmldb/xml2relational/images/img-4.png index b626c206d..dcaff9e21 100644 Binary files a/xmldb/xml2relational/images/img-4.png and b/xmldb/xml2relational/images/img-4.png differ diff --git a/xmldb/xml2relational/images/img-5.png b/xmldb/xml2relational/images/img-5.png index a07f87d9c..21026e66e 100644 Binary files a/xmldb/xml2relational/images/img-5.png and b/xmldb/xml2relational/images/img-5.png differ diff --git a/xmldb/xml2relational/images/img-6.png b/xmldb/xml2relational/images/img-6.png index a1a298a09..dd37c07b3 100644 Binary files a/xmldb/xml2relational/images/img-6.png and b/xmldb/xml2relational/images/img-6.png differ diff --git a/xmldb/xml2relational/images/img-7.png b/xmldb/xml2relational/images/img-7.png index c88369478..1ba42a5cc 100644 Binary files a/xmldb/xml2relational/images/img-7.png and b/xmldb/xml2relational/images/img-7.png differ diff --git a/xmldb/xml2relational/images/result-2.png b/xmldb/xml2relational/images/result-2.png new file mode 100644 index 000000000..3ac9caca4 Binary files /dev/null and b/xmldb/xml2relational/images/result-2.png differ diff --git a/xmldb/xml2relational/images/result-3.png b/xmldb/xml2relational/images/result-3.png new file mode 100644 index 000000000..4fc0d749d Binary files /dev/null and b/xmldb/xml2relational/images/result-3.png differ diff --git a/xmldb/xml2relational/xml2relational.md b/xmldb/xml2relational/xml2relational.md index 175f0a91a..02261c9f0 100644 --- a/xmldb/xml2relational/xml2relational.md +++ b/xmldb/xml2relational/xml2relational.md @@ -1,75 +1,60 @@ -# Generate relational data from XML data +# Expose your XML documents transparently as relational data ## Introduction -Relational database views over XML data provide conventional, relational access to XML content. We will use XML-specific functions and methods provided by Oracle XML DB to create conventional database views. We will then use the views to work with XML content but in relational ways. +Often, your XML application has to make data available to systems or tools that rely on purely relational data representation of your data. Relational database views over XML data provide conventional, relational access over XML documents. We will use XML-specific functions and methods provided by Oracle XML DB to create conventional database views. We will then use the views to work with XML content but in relational ways. -Estimated Time: 30 minutes +Estimated Time: 20 minutes ### Objectives In this lab, you will learn: -- Creating relational views from XML data +- How to create relational views over XML documents ### Prerequisites -- Be logged into your Oracle Cloud Account. +- Be logged into your Oracle Cloud Account and have access to the SQL Worksheet in Database Actions. -## Task 1: Open Database Actions -1. Log in to the Oracle Cloud. -2. If you are using a Free Trial or Always Free account, and you want to use Always Free Resources, you need to be in a region where Always Free Resources are available. You can see your current default Region in the top, right-hand corner of the page. -3. Click the navigation menu in the upper left to show top-level navigation choices. -4. Click on Oracle Database and choose Autonomous Transaction Processing. -5. If using FreeTier, your compartment should be the root compartment for your tenancy. -Note: Avoid the use of the ManagedCompartmentforPaaS compartment as this is an Oracle default used for Oracle Platform Services. -6. You should see your database XMLDB listed in the center. Click on the database name "XMLDB". -7. On the database page, choose Database Actions. -8. You are now in Database Actions. -Database Actions allows you to connect to your Autonomous Database through various browser-based tools. We will just be using the SQL workshop tool. -9. You should be in the Database Actions panel. Click on the SQL card +## Task 1: Generate Relational Data from XML data -## Task 2: Relational Data from XML Data -The XMLTable function is to extract data from XML documents in a relational form. We can create a view and then query on the view. +The XMLTable function is to extract data from XML documents in a relational form. We can then create a relational view on top of the query, Subdequently, non-xml aware tools and application can directly work on these relational views without knowing the xml content. -1. Generate Relational Data from XML data - To decompose the result of an XQuery expression’s evaluation into the relational rows and columns of a new, virtual table, we will use XMLTable. We can insert this data into a relational table, or we can query it using SQL depending on the use cases. +If we want to show the information from the Purchaseorder documents in a relational format, we can use XMLTable function. - This query will show a lot of information from Purchaseorder documents in a relational format. +``` + +SELECT + M.* +FROM + PURCHASEORDER P, + XMLTABLE ('$p/PurchaseOrder' + PASSING P.DOC AS "p" + COLUMNS + REFERENCE PATH 'Reference/text()', + REQUESTOR PATH 'Requestor/text()', + USERID PATH 'User/text()', + COSTCENTER PATH 'CostCenter/text()', + NAME PATH 'ShippingInstructions/name/text()', + STREET PATH 'ShippingInstructions/Address/street/text()', + CITY PATH 'ShippingInstructions/Address/city/text()', + STATE PATH 'ShippingInstructions/Address/state/text()', + ZIP PATH 'ShippingInstructions/Address/zipCode/text()', + COUNTRY PATH 'ShippingInstructions/Address/country/text()', + PHONE PATH 'ShippingInstructions/telephone/text()', + INSTRUCTIONS PATH 'SpecialInstructions/text()' + ) M; + +``` - ``` - - SELECT - M.* - FROM - PURCHASEORDER P, - XMLTABLE ( '$p/PurchaseOrder' - PASSING P.DOC AS "p" - COLUMNS - REFERENCE PATH 'Reference/text()', - REQUESTOR PATH 'Requestor/text()', - USERID PATH 'User/text()', - COSTCENTER PATH 'CostCenter/text()', - NAME PATH 'ShippingInstructions/name/text()', - STREET PATH 'ShippingInstructions/Address/street/text()', - CITY PATH 'ShippingInstructions/Address/city/text()', - STATE PATH 'ShippingInstructions/Address/state/text()', - ZIP PATH 'ShippingInstructions/Address/zipCode/text()', - COUNTRY PATH 'ShippingInstructions/Address/country/text()', - PHONE PATH 'ShippingInstructions/telephone/text()', - INSTRUCTIONS PATH 'SpecialInstructions/text()' - ) M; - - ``` +In SQL Worksheet, copy the above statement into the worksheet area and press "Run Statement". You'll see a relational result set being generated at runtime from your XML documents. - Copy the above statement into the worksheet area and press "Run Statement". +![Relational data from XML content](./images/img-1.png) - ![Relational data from XML content](./images/img-1.png) +## Task 2: Create Relational Views -2. Create Relational Views - - 2.1. Create a purchaseorder relational view +1. Create a relational view V_PURCHASEORDER - Here we will create a view from elements that occur at most once per document. + The previous task generated a relational result set at runtime, based on our XML documents. A relational view can be created on top of the query from previous example, creating a view from elements that occur at most once per each document stored in Purchaseorder table. ``` @@ -94,7 +79,6 @@ The XMLTable function is to extract data from XML documents in a relational form PHONE PATH 'ShippingInstructions/telephone/text()', INSTRUCTIONS PATH 'SpecialInstructions/text()' ) M; - ``` @@ -102,10 +86,15 @@ The XMLTable function is to extract data from XML documents in a relational form ![Purchaseorder relational view](./images/img-2.png) + You will see the scalar values of our XML documents as relational columns in our view. + + ![Purchaseorder relational view](./images/result-2.png) - 2.2. Create a LineItem relational view +2. Create a relational view V_LINEITEM using chained XMLTable - The purchaseorder relational view contains all the elements except LineItem because LineItem can occur more than once per document. Let's now create a LineItem view with LineItem information. + The purchaseorder relational view contains all the elements except LineItems/LineItem because LineItem element can occur more than once per document. So let's mapp these elements to an XMLType column which is passed to the second XMLTable function. By chaining to XMLTABLE function calls, we are unnesting the elements in the lineitem fragments. + + Let's now create a LineItem view with the reference column and the LineItem information. ``` @@ -115,18 +104,18 @@ The XMLTable function is to extract data from XML documents in a relational form L.* FROM PURCHASEORDER P, - XMLTABLE ( '$p/PurchaseOrder' + XMLTABLE ('$p/PurchaseOrder' PASSING P.DOC AS "p" COLUMNS REFERENCE PATH 'Reference/text()', LINEITEMS XMLTYPE PATH 'LineItems/LineItem' ) M, - XMLTABLE ( '$l/LineItem' + XMLTABLE ('$l/LineItem' PASSING M.LINEITEMS AS "l" COLUMNS ITEMNO PATH '@ItemNumber', - DESCRIPTION PATH 'Part/@Description', - PARTNO PATH 'Part/text()', + DESCRIPTION PATH 'Description', + PARTNO PATH 'Part/@Id', QUANTITY PATH 'Quantity', UNITPRICE PATH 'Part/@UnitPrice' ) L; @@ -137,16 +126,17 @@ The XMLTable function is to extract data from XML documents in a relational form ![LineItem relational view](./images/img-3.png) - + You will see the reference column and all lineitem values of our XML documents as relational columns in our view. -3. Query over the views + ![LineItem relational view](./images/result-3.png) + +## Task 3: Query over the views - Once we are done creating the views, let’s query them. +Once we have created our relational views on top of XML Content using XMLTable functions, we can use them in any relational SQL queries. - 3.1. Join the views +1. Join our two relational views - After creating some views, you can join them just like the relational tables. - Sometimes you may need to write a very complex XQuery to get the expected results. To write clean and concise code, you can create views from XML content and then do SQL join on them. It will not only increase the code readability but also give you a modular data model. + After creating our two views V\_PURCHASEORDER and V\_LINEITEM, we can join them just like the relational tables. ``` @@ -163,9 +153,9 @@ The XMLTable function is to extract data from XML documents in a relational form V_LINEITEM D WHERE M.REFERENCE = D.REFERENCE - AND M.REQUESTOR = 'H. Roy 3' + AND M.REQUESTOR = 'Cindy Jones' AND D.QUANTITY > 0 - AND D.UNITPRICE > 17.00; + AND D.UNITPRICE > 50.00; ``` @@ -173,16 +163,11 @@ The XMLTable function is to extract data from XML documents in a relational form ![Joing the views](./images/img-4.png) - - - On top of that, having relational views created, you will be able to use SQL language capabilities. For example, you can easily leverage Group by and SQL Analytics functionalities. + Having relational views created, you will be able to use SQL as you would do with normal relational tables (or views). For example, you can easily leverage Group by and SQL Analytics functionalities, which we will do in the next two steps. - 3.2. Group by query +2. Apply an aggregation using GROUP BY - We will show a simple group by query on the purchaseorder view that we created. - Note- XQuery 1.0 did not support the concept of group by. By creating a view from XML content, you can easily utilize group by whenever needed. - - For example, we can find how many purchase orders are for each cost center using this query. + Let us find out how many purchase orders are for each cost center using this query. ``` @@ -191,8 +176,6 @@ The XMLTable function is to extract data from XML documents in a relational form COUNT(*) FROM V_PURCHASEORDER - WHERE - ROWNUM <= 5 GROUP BY COSTCENTER ORDER BY @@ -204,13 +187,10 @@ The XMLTable function is to extract data from XML documents in a relational form ![Group by query](./images/img-5.png) - - - 3.3. SQL analytics functionalities +3. Use SQL analytics functionalities We will show a simple query using Group by extension ROLLUP function to apply SQL analytics on XML data. - Note- SQL Analytics functionalities are not provided by XQuery. - + In the following query, the Group by extension ROLLUP function enables a SELECT statement to calculate multiple levels of subtotals across a specified group of dimensions, as well as a grand total. ``` @@ -222,7 +202,7 @@ The XMLTable function is to extract data from XML documents in a relational form FROM V_LINEITEM WHERE - PARTNO = '1' + PARTNO = '91982117354' GROUP BY ROLLUP(PARTNO, QUANTITY); @@ -232,9 +212,6 @@ The XMLTable function is to extract data from XML documents in a relational form ![Group by rollup query](./images/img-6.png) - - - Here is another example of SQL Analytics. In the following query, the analytic function LAG provides access to more than one row of a table at the same time without a self-join. Given a series of rows returned from a query and a position of the cursor, LAG provides access to a row at a given physical offset prior to that position. ``` @@ -268,18 +245,13 @@ The XMLTable function is to extract data from XML documents in a relational form You may now **proceed to the next lab**. ## Learn More -- [Database 19c - JSON] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=638) -- [Developing with JSON and SODA in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=831) -- [JSON without Limits] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=836) -- [Using the Database API for MongoDB] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3152) -- [Database API for MongoDB - The Basics] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3221) -- [Full-Text Search in Oracle Database] (https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3286) -- [Autonomous Database Dedicated](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=677) -- [Manage and Monitor Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=553) -- [Scaling and Performance in the Autonomous Database](https://apexapps.oracle.com/pls/apex/dbpm/r/livelabs/view-workshop?wid=608) + +* [Get started with Oracle Autonomous Database Serverless ](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/videos.html) +- [XML DB Developer's Guide](https://docs.oracle.com/en/database/oracle/oracle-database/23/adxdb/index.html) +- [Oracle XML DB](https://www.oracle.com/database/technologies/appdev/xmldb.html) ## Acknowledgements * **Author** - Harichandan Roy, Principal Member of Technical Staff, Oracle Document DB * **Contributors** - XDB Team -* **Last Updated By/Date** - Harichandan Roy, February 2023 +- **Last Updated By/Date** - Ernesto Alvarez, April 2024