├── README.md ├── apex_automation.md ├── apex_calcs.md ├── apex_expandable_pageitem.md ├── apex_link_cssHide.md ├── apexversion.md ├── assets ├── 2023-03-13-10-43-58.png ├── 2023-03-13-10-55-44.png ├── 2023-08-30-08-56-18.png ├── 2023-08-30-09-04-10.png ├── 2023-08-30-09-07-34.png ├── 2023-08-30-09-11-50.png ├── 2023-08-30-09-12-28.png ├── 2023-08-30-09-17-47.png ├── 2023-08-30-09-18-51.png ├── 2023-08-30-09-19-18.png ├── 2023-09-22-14-03-16.png ├── 2023-09-22-14-09-56.png ├── 2023-09-22-14-28-05.png ├── 2023-09-22-14-28-58.png ├── 2023-09-22-14-30-33.png ├── 2023-09-22-14-31-59.png ├── 2023-09-22-14-33-31.png ├── 2023-09-22-14-34-52.png ├── 2023-09-22-14-35-12.png ├── 2023-09-22-14-37-28.png ├── 2023-09-22-14-38-31.png ├── 2023-09-22-14-40-51.png ├── 2023-09-22-14-42-56.png ├── 2023-09-22-14-43-31.png ├── 2023-09-22-14-44-24.png ├── 2023-09-22-14-46-03.png ├── 2023-09-22-14-47-25.png ├── 2023-09-22-14-48-04.png ├── 2023-09-22-14-49-29.png ├── 2023-09-22-14-52-36.png ├── 2023-09-22-14-56-55.png ├── 2023-09-22-14-58-17.png ├── 2023-09-22-14-58-47.png ├── 2023-09-22-15-01-29.png ├── 2023-09-22-15-04-09.png ├── 2023-09-22-15-05-34.png ├── 2023-09-22-15-13-00.png ├── 2023-09-22-15-14-30.png ├── 2023-09-22-15-15-06.png ├── 2023-09-22-15-15-54.png ├── 2023-09-22-15-17-38.png ├── 2023-09-22-15-18-44.png ├── 2023-09-22-15-19-11.png ├── 2023-09-22-15-21-29.png ├── 2023-09-28-10-34-39.png ├── 2023-09-28-10-35-32.png ├── 2023-09-28-10-36-08.png ├── 2023-09-28-10-36-41.png ├── 2023-09-28-10-37-58.png ├── 2023-10-10-09-32-46.png ├── 2024-01-24-08-56-40.png ├── 2024-01-24-08-59-14.png ├── 2024-01-24-09-01-39.png ├── 2024-01-24-09-03-04.png ├── 2024-01-24-09-04-50.png ├── 2024-01-24-10-37-35.png ├── 2024-01-24-10-39-31.png ├── 2024-01-24-10-42-53.png ├── 2024-01-24-10-44-10.png ├── 2024-01-24-10-45-07.png ├── 2024-01-24-10-49-31.png ├── 2024-01-24-10-54-08.png ├── 2024-01-24-10-56-33.png ├── 2024-01-24-11-01-07.png ├── 2024-01-24-11-04-03.png ├── 2024-01-24-11-06-56.png ├── 2024-01-24-11-11-34.png ├── 2024-01-24-11-59-26.png ├── 2024-01-24-12-03-32.png ├── 2024-01-24-12-09-54.png ├── 2024-01-24-12-10-16.png ├── 2024-03-01-09-44-12.png ├── 2024-03-01-09-46-14.png ├── 2024-03-01-09-48-11.png ├── 2024-03-01-09-48-32.png ├── 2024-06-12-13-58-56.png ├── classic_cell_formatting-0a0b23bf.png ├── classic_cell_formatting-64643eb8.png ├── classic_cell_formatting-790aeeff.png ├── indexedDocsCheck-0673052d.png ├── indexedDocsCheck-1efbcd19.png ├── indexedDocsCheck-7fabc7a3.png ├── ords_resume_upload-05a3d666.png ├── ords_resume_upload-0763aa23.png ├── ords_resume_upload-1081d676.png ├── ords_resume_upload-1f5b0a99.png ├── ords_resume_upload-1fa933c9.png ├── ords_resume_upload-25b94ab9.png ├── ords_resume_upload-2f08d38e.png ├── ords_resume_upload-3081382b.png ├── ords_resume_upload-357587ec.png ├── ords_resume_upload-3c45fe4f.png ├── ords_resume_upload-4103a4bf.png ├── ords_resume_upload-4c778540.png ├── ords_resume_upload-5651e28c.png ├── ords_resume_upload-5709830e.png ├── ords_resume_upload-5828af96.png ├── ords_resume_upload-6a66c162.png ├── ords_resume_upload-755bbff4.png ├── ords_resume_upload-79ac84e5.png ├── ords_resume_upload-7e7ca268.png ├── ords_resume_upload-7f80f8c5.png ├── ords_resume_upload-9371e009.png ├── ords_resume_upload-a04e43a0.png ├── ords_resume_upload-a122c046.png ├── ords_resume_upload-b15fea9f.png ├── ords_resume_upload-b6dd6627.png ├── ords_resume_upload-b7f7c368.png ├── ords_resume_upload-c9bac9b1.png ├── ords_resume_upload-cbddcc58.png ├── ords_resume_upload-ce29aad3.png ├── ords_resume_upload-d29eb3ae.png ├── ords_resume_upload-e679437a.png ├── ords_resume_upload-ea0babf0.png ├── ords_resume_upload-eee346be.png ├── ords_resume_upload-fccf2e85.png ├── ords_resume_upload-fd713152.png ├── po_xml.xml ├── teamstats.csv ├── teamstats.xlsx ├── xml_ORDS_ingestion-147e05fe.png ├── xml_ORDS_ingestion-472aa6d7.png ├── xml_ORDS_ingestion-47475732.png ├── xml_ORDS_ingestion-64290b32.png ├── xml_ORDS_ingestion-8919434f.png ├── xml_ORDS_ingestion-9fa40b81.png ├── xml_ORDS_ingestion-a6449a5f.png ├── xml_ORDS_ingestion-afb53eb3.png ├── xml_ORDS_ingestion-c13cab02.png ├── xml_ORDS_ingestion-c5e54fd3.png ├── xml_ORDS_ingestion-d2feee39.png ├── xml_ORDS_ingestion-e5f9992f.png ├── xml_queries-3de3d3cf.png └── xml_trigger-400f78ba.png ├── ci_sr_add.md ├── classic_cell_formatting.md ├── clientisdeValidations.md ├── comments.md ├── dataload_manipulation.md ├── dynamicQuery.sql ├── example_data.csv ├── indexedDocsCheck.md ├── introGenAI.md ├── javscriptSessionState.md ├── json ├── mlb_player1.json ├── mlb_player2.json └── mlb_player3.json ├── json_db.md ├── order1.xml ├── order2.xml ├── ords_resume_upload.md ├── printAClob.md ├── resumeAdmin.sql ├── shellconsole_export_to_objstore.md ├── shellconsole_to_atp.md ├── sqlWebExamples_.sql ├── updateImageOnSelectList.md ├── xml_ORDS_ingestion.md └── xmltojson.md /README.md: -------------------------------------------------------------------------------- 1 | # Oracle APEX Text Demonstration 2 | This script will outline the steps required to leverage Oracle Text inside and Autonomous Database. Oracle APEX will be reference and leveraged for the creation of a front end application to upload and interact with the core code. 3 | 4 | ## Video References 5 | To save time it may be beneficial to watch the following video's related to this content. 6 | - [How to enable full text search on a docx or pdf](https://youtu.be/hDnb3KFXY8Q) 7 | - [How to extract text from inside a PDF](https://youtu.be/AfudCHhAHK4) 8 | - [How to print a CLOB in a Modal Dialog](https://youtu.be/pSw_jFyt5zw) 9 | - [3 ways to deploy a package in 3 min.](https://youtu.be/U6v6XjJ68X0) 10 | - [How to Create a REST API to Upload a BLOB into an APEX Schema](https://youtu.be/rnqGQrhvhLA) 11 | 12 | 13 | ## Create a new workspace in Oracle APEX 14 | - In this example a workspace with the name **searchdemo** was created. As a part of this creation a database user named search demo was also created. 15 | 16 | - Login to your new APEX workshop and create a new user. In this example the workspace user is named **cbaber**. 17 | 18 | - Login to your workspace as your new user. 19 | 20 | ## Add grants for Oracle Text to the schema. 21 | 22 | - Navigate to SQL Web Developer and open a session as admin. 23 | 24 | - Grant the following to **searchdemo** 25 | 26 | ``` 27 | grant ctxapp to searchdemo; 28 | ``` 29 | 30 | - Query to check and see if the priv is granted. This must be executed from SQL workshop that is part of ATP as admin. 31 | 32 | ``` 33 | SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTEE = 'searchdemo'; 34 | ``` 35 | 36 | ## Create your table to store the resume. 37 | 38 | - this was done with APEX wizard code below 39 | 40 | ``` 41 | CREATE table "RESUME" ( 42 | "DOC_ID" NUMBER NOT NULL, 43 | "TITLE" VARCHAR2(500), 44 | "SUBMITTED_BY" VARCHAR2(300), 45 | "RESUME" BLOB, 46 | "MIMETYPE" VARCHAR2(250), 47 | "CREATED_DATE" DATE, 48 | "FILENAME" VARCHAR2(200), 49 | constraint "RESUME_PK" primary key ("DOC_ID") 50 | ) 51 | / 52 | 53 | CREATE sequence "RESUME_SEQ" 54 | / 55 | 56 | CREATE trigger "BI_RESUME" 57 | before insert on "RESUME" 58 | for each row 59 | begin 60 | if :NEW."DOC_ID" is null then 61 | select "RESUME_SEQ".nextval into :NEW."DOC_ID" from sys.dual; 62 | end if; 63 | end; 64 | / 65 | ``` 66 | 67 | ## Create a form to upload a document to the table. 68 | - In APEX create a form to upload a resume to the table. If you need more specifics watch [https://youtu.be/f8hYQtAJ-WY](https://youtu.be/f8hYQtAJ-WY) 69 | 70 | - Upload 1 document. 71 | 72 | ## Build index's on the table for Oracle Text. 73 | 74 | - Go to SQL Workshop, SQL commands set to pl/sql and execute the following to create a index. The CTXSYS.AUTO_FILTER must be used for structured docs like PDF and MSword. 75 | 76 | ``` 77 | CREATE INDEX searchMyDocs ON resume(resume) INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS 78 | ('DATASTORE CTXSYS.DEFAULT_DATASTORE FILTER CTXSYS.AUTO_FILTER FORMAT COLUMN MIMETYPE'); 79 | ``` 80 | - Syntax to sync index every minute 81 | ``` 82 | CREATE INDEX searchMyDocs ON resume(resume) INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS 83 | ('DATASTORE CTXSYS.DEFAULT_DATASTORE FILTER CTXSYS.AUTO_FILTER FORMAT COLUMN MIMETYPE sync (every "freq=secondly;interval=60")') 84 | ``` 85 | 86 | ## Basic queries of the indexed documentation. 87 | 88 | - Core query inside the document to see if contains a keyword. In this first example we are looking for all candidates who have the word java inside there resume. The greater than zero means a score is detected, the information is in the document. 89 | 90 | ``` 91 | SELECT SCORE(1), doc_id, title, submitted_by FROM resume WHERE CONTAINS(resume, 'Java', 1) > 0; 92 | ``` 93 | 94 | - Find all the documents that have the word java with a score >11 and contain the word nascar. 95 | ``` 96 | SELECT SCORE(1), doc_id, title, submitted_by FROM resume WHERE CONTAINS(resume, '(java > 10) and nascar', 1) > 0; 97 | ``` 98 | 99 | - Proximity search look for the word **Eloqua** near word **code** (Requires Chip resume) 100 | 101 | ``` 102 | SELECT SCORE(1), doc_id, title, submitted_by FROM resume WHERE CONTAINS(resume, 'Eloqua ; code', 1) > 0; 103 | ``` 104 | 105 | - Second example of proximity search with near operator. Looking for development near creativity within 5 words 106 | 107 | ``` 108 | SELECT SCORE(1), doc_id, title, submitted_by FROM resume 109 | WHERE CONTAINS(resume, 'near((development, creativity), 5)', 1) > 0; 110 | ``` 111 | 112 | - Fuzzy Search on term. 113 | ``` 114 | SELECT SCORE(1), doc_id, title, submitted_by FROM resume WHERE CONTAINS(resume, '?jav', 1) > 0; 115 | ``` 116 | 117 | - Sounds like word - Soundex search 118 | ``` 119 | SELECT SCORE(1), doc_id, title, submitted_by FROM resume WHERE CONTAINS(resume, '!ava', 1) > 0; 120 | ``` 121 | 122 | 123 | - Stem search on a term. In this example we are looking for the documents that stem of the word work example would return words like workflow, 124 | 125 | ``` 126 | SELECT SCORE(1), doc_id, title, submitted_by FROM resume WHERE CONTAINS(resume, '$work', 1) > 0; 127 | ``` 128 | 129 | - Accumulation Search - Best to read this to understand [Accum docs](https://docs.oracle.com/cd/E11882_01/text.112/e24436/cqoper.htm#i997062) 130 | 131 | ``` 132 | SELECT SCORE(1), doc_id, title, submitted_by FROM resume WHERE CONTAINS(resume, 'java ACCUM present', 1) > 0; 133 | ``` 134 | ``` 135 | SELECT SCORE(1), doc_id, title, submitted_by FROM resume WHERE CONTAINS(resume, 'java ACCUM present*3', 1) > 0; 136 | ``` 137 | 138 | 139 | - Add More Docs in the apex app. To sync the index execute in this case with 5M of memory 140 | 141 | ``` 142 | begin 143 | CTX_DDL.SYNC_INDEX('searchMyDocs', '5M'); 144 | end; 145 | ``` 146 | 147 | ## Construct Thematic Search Constructs 148 | 149 | - Build themes on docs. To do this you first need to create a table to hold your themes. 150 | 151 | ``` 152 | create table themes (query_id number, theme varchar2(2000), weight number); 153 | ``` 154 | 155 | - Create all the themes on the docs in the table. Run this in pl/sql mode in SQL Workshop. This procedure will loop through the resume table and create themes for all the docs currently in the table. 156 | 157 | ``` 158 | begin 159 | for x in (select doc_id from resume) loop 160 | ctx_doc.themes ('searchMyDocs', x.doc_id, 'themes', x.doc_id, full_themes => false); 161 | end loop; 162 | end; 163 | ``` 164 | 165 | - Query the themes. Show all themes with a weight over 25 per resume. 166 | ``` 167 | select r.title, r.filename, t.theme, t.weight from resume r, themes t 168 | where r.doc_id = t.query_id and weight > 25 169 | order by doc_id asc; 170 | ``` 171 | 172 | - If you need to add more documents you need to rebuild the themes. Make sure to truncate the table before rebuilding. 173 | ``` 174 | declare 175 | pragma autonomous_transaction; 176 | killThemes varchar2(100) := 'truncate table themes'; 177 | 178 | begin 179 | execute immediate killThemes; 180 | for x in (select doc_id from resume) loop 181 | ctx_doc.themes ('searchMyDocs', x.doc_id, 'themes', x.doc_id, full_themes => false); 182 | end loop; 183 | end; 184 | ``` 185 | 186 | ## Construct Gists Search Constructs 187 | 188 | - Create the gists table 189 | 190 | ``` 191 | create table gists (query_id number, pov varchar2(80), gist CLOB); 192 | ``` 193 | 194 | - Build out gists index. 195 | ``` 196 | begin 197 | for x in (select doc_id from resume) loop 198 | ctx_doc.gist('searchMyDocs', x.doc_id, 'gists',x.doc_id,'P', pov =>'GENERIC'); 199 | end loop; 200 | end; 201 | ``` 202 | 203 | - Query a gist for a document. 204 | ``` 205 | select * from gists; 206 | ``` 207 | 208 | - Rebuild the gists index 209 | ``` 210 | declare 211 | pragma autonomous_transaction; 212 | killGists varchar2(100) := 'truncate table gists'; 213 | 214 | begin 215 | execute immediate killGists; 216 | for x in (select doc_id from resume) loop 217 | ctx_doc.gist('searchMyDocs', x.doc_id, 'gists',x.doc_id,'P', pov =>'GENERIC'); 218 | end loop; 219 | end; 220 | ``` 221 | 222 | ## Create a filtered doc 223 | 224 | - Create a Table for markup. 225 | 226 | ``` 227 | create table filtered_docs(QUERY_ID number, DOCUMENT clob); 228 | ``` 229 | 230 | - Build out filtered docs index's. 231 | ``` 232 | begin 233 | for x in (select doc_id from resume) loop 234 | ctx_doc.filter ('searchMyDocs', x.doc_id, 'filtered_docs', x.doc_id, plaintext => true); 235 | end loop; 236 | end; 237 | ``` 238 | 239 | - Query the filtered doc. Showing the title and the filtered text. 240 | 241 | ``` 242 | select r.title, f.document as "Plain Text Resume" from resume r, filtered_docs f 243 | where r.doc_id = f.query_id 244 | ``` 245 | 246 | ## Create Full Themes Indexing 247 | 248 | - Create the table for full themes. A full theme has both the theme and any relations to other themes. 249 | 250 | ``` 251 | create table full_themes( QUERY_ID number, THEME varchar2(2000), WEIGHT NUMBER); 252 | ``` 253 | 254 | - Create indexs for full themes. 255 | 256 | ``` 257 | begin 258 | for x in (select doc_id from resume) loop 259 | ctx_doc.themes ('searchMyDocs', x.doc_id, 'full_themes', x.doc_id, full_themes => true); 260 | end loop; 261 | end; 262 | ``` 263 | 264 | - Query the full themes. Truth is you need a bit of a tool to visualize thematic connections. So this one works but is tough to convey to users. 265 | 266 | ``` 267 | select r.title, r.filename, t.theme, t.weight from resume r, full_themes t 268 | where r.doc_id = t.query_id 269 | order by doc_id asc; 270 | ``` 271 | 272 | ## Scripted Rebuilds 273 | 274 | - If you need to rebuild themes, gists ... after loading more documents execute the code in resumeAdmin.sql with the procedures you require. Then call the procedures. Example below. 275 | 276 | ``` 277 | begin 278 | CTX_DDL.SYNC_INDEX('searchMyDocs', '5M'); 279 | resumeAdmin.Batch_Create_Themes(); 280 | resumeAdmin.Batch_Create_Full_Themes(); 281 | resumeAdmin.Batch_Create_Gists(); 282 | resumeAdmin.Batch_Create_Filtered_Docs(); 283 | end; 284 | ``` 285 | -------------------------------------------------------------------------------- /apex_automation.md: -------------------------------------------------------------------------------- 1 | ## Short Demo to Show Example of APEX Automation for PL/SQL Script 2 | In this example we will showcase how to setup a procedure to perform repetitive tasks inside an APEX Application. 3 | 4 | - Create a log table and sequence 5 | 6 | ``` 7 | CREATE table "LOGGER" ( 8 | "LOG_ID" NUMBER, 9 | "LOG" VARCHAR2(1500), 10 | "LOG_TIME" TIMESTAMP, 11 | constraint "LOGGER_PK" primary key ("LOG_ID") 12 | ) 13 | / 14 | 15 | CREATE sequence "LOGGER_SEQ" 16 | / 17 | 18 | CREATE trigger "BI_LOGGER" 19 | before insert on "LOGGER" 20 | for each row 21 | begin 22 | if :NEW."LOG_ID" is null then 23 | select "LOGGER_SEQ".nextval into :NEW."LOG_ID" from sys.dual; 24 | end if; 25 | end; 26 | / 27 | ``` 28 | 29 | -- Create procedure 30 | 31 | ``` 32 | create or replace procedure testProc is 33 | 34 | 35 | begin 36 | -- Begin procedure 37 | insert into logger (LOG, LOG_TIME) values('Procedure testProc Initiating',CURRENT_TIMESTAMP); 38 | -- add logic 39 | 40 | -- end logic 41 | insert into logger (LOG, LOG_TIME) values('Procedure testProc Completed',CURRENT_TIMESTAMP); 42 | commit; 43 | end; 44 | ``` -------------------------------------------------------------------------------- /apex_calcs.md: -------------------------------------------------------------------------------- 1 | ## Three Approaches to Developing Excel Calculations in APEX 2 | 3 | In this brief tutorial we will take a look at three approaches for replicating excel calculations inside Oracle APEX. The first will focus on end users, enabling access to data online and providing out of the box functionality to create calculations. The second is a bit more advanced and will leverage SQL Worksheet to create virtual columns on the core table with equations that calculate on query. The third is the most advanced and showcases how to create a function for a calculation. Functions will enable you to pull information from other tables (tabs in excel) and easily calculate results. 4 | 5 | ### Example 1: Oracle APEX: Replicate an Excel Calculation inside an Interactive Report 6 | We will begin by taking a look at a sample excel spreadsheet called Fall_Stats.xlsx. We will make a copy as a .csv, remove the calculation columns and upload into Oracle APEX. Once uploaded we will create a new page in a sample application with a interactive report. Inside the interactive report we will show you how a end user can easily replicate a calculation in excel inside Oracle APEX. We will also showcase how one can save calculations in personal versions of the interactive report for future use. 7 | 8 | If you would like to follow along in this tutorial please access the sample excel here [https://github.com/chipbaber/apex_textdemo/blob/main/assets/teamstats.xlsx](https://github.com/chipbaber/apex_textdemo/blob/main/assets/teamstats.xlsx). 9 | 10 | Please watch this tutorial video. [https://youtu.be/bB6Yxb5uNRY](https://youtu.be/bB6Yxb5uNRY) 11 | 12 | ### Example 2: Oracle APEX: Replicating Excel Calculation with Virtual Columns 13 | In our example we could use this table in many parts of a application. Lets take a look at how an Oracle APEX developer can replicate excel calculations at the table level inside Oracle virtual columns. We wil start by repeating our simple batting average calculation from Example 1. Then add two slightly more advanced calculations for on base percentage (OBP) and slugging (SLG). Last but not least we will touch on a limitation of this approach. You are not able to leverage virtual columns inside other virtual column calculations. For example the baseball stat OPS is a combination of both OBP and SLG. Trying to calculate this as a virtual column will generate a ORA-54012. Don't worry though, part three of this series shows how to build for scenarios like this leveraging Oracle functions. 14 | 15 | Please watch the following video for more guidance. [https://youtu.be/4pj9-q-3dG0](https://youtu.be/4pj9-q-3dG0) 16 | 17 | ``` 18 | select * from teamstats 19 | select name, round(H/AB,3) avg from teamstats 20 | ``` 21 | 22 | ``` 23 | ALTER TABLE teamstats 24 | ADD (avg AS (round(H/AB,3))); 25 | ``` 26 | 27 | - test the virtual column 28 | ``` 29 | select name, avg from teamstats 30 | ``` 31 | 32 | - Test Query for OBP and slg 33 | ``` 34 | select name, ROUND((H+BB+HBP)/(AB+BB+HBP+SAC),3) obp, ROUND(TB/AB,3) slg from teamstats 35 | ``` 36 | 37 | - Add two more virtual columns 38 | ``` 39 | ALTER TABLE teamstats 40 | ADD (obp AS (ROUND((H+BB+HBP)/(AB+BB+HBP+SAC),3)), 41 | slg AS (ROUND(TB/AB,3))); 42 | ``` 43 | 44 | - Test the columns 45 | ``` 46 | select name, avg, obp, slg from teamstats 47 | ``` 48 | 49 | - Example to fix formatting 50 | ``` 51 | select a.name, to_char(a.slg,'FM99999.000') from teamstats a 52 | ``` 53 | 54 | - So what happens when you try to leverage virtual columns in calculations, queries work but ... 55 | ``` 56 | select name, ROUND(OBP+SLG,3) OPS from teamstats 57 | ``` 58 | 59 | - Virtual columns on virtual columns won't work. You will get a ORA-54012: virtual column is referenced in a column expression 60 | ``` 61 | ALTER TABLE teamstats 62 | ADD (OPS AS (ROUND(OBP+SLG,3))); 63 | ``` 64 | 65 | ### Example 3: Replicating Excel Calculations with Functions in Oracle APEX 66 | In part 3 of this series we are going to leverage functions to create calculations commonly performed in excel. Functions are programmatic in nature and provide a means for quering other tables, pulling in that data and then working with variables to really perform almost any formula provided in excel. The end result of a function is a single output, just like a cell in Excel. Our example today will begin by calculating OPS based off 2 virtual columns created in video 2 above. We will then showcase how you can call the function in a query. After that we will construct a slighlty more advanced function where we will calculate the team batting average, then compare to a players batting average and output the points above or below the team average the player is. Finally we will demonstrate how to create a view to hide the complexity of the virtual columns and functions for easy consumption and development inside Oracle APEX. 67 | 68 | - Creating a function for the OPS calculation. 69 | 70 | ``` 71 | CREATE OR REPLACE Function ops ( slg IN number, ops IN number ) RETURN number 72 | IS 73 | v_ops number; 74 | BEGIN 75 | v_ops := slg + ops; 76 | RETURN v_ops; 77 | EXCEPTION 78 | WHEN OTHERS THEN 79 | raise_application_error(-20001,'An error was encountered calculating OPS - '||SQLCODE||' -ERROR- '||SQLERRM); 80 | END; 81 | ``` 82 | 83 | - Test your OPS function 84 | ``` 85 | select a.name, ops(a.slg, a.obp) OPS from teamstats a 86 | ``` 87 | 88 | - Add formatting around your OPS function 89 | ``` 90 | select a.name, to_char(ops(a.slg, a.obp),'FM9.000') OPS from teamstats a 91 | ``` 92 | 93 | - Create a view including your new function 94 | ``` 95 | create or replace view v_teamstats as select a.name, avg, slg, obp, ops(a.slg, a.obp) ops from teamstats a 96 | ``` 97 | 98 | - Query View 99 | ``` 100 | select * from v_teamstats 101 | ``` 102 | 103 | - Now for something a little more complex. Get the team batting avg, show players performance above or below team avg. 104 | 105 | ``` 106 | CREATE OR REPLACE Function avgRating(v_avg in number) RETURN number 107 | IS 108 | v_rating number; 109 | v_teamavg number; 110 | BEGIN 111 | --get the team avg from the table 112 | select round(sum(h)/sum(ab),3) into v_teamavg from teamstats; 113 | 114 | --see how much player is above or below the team avg 115 | v_rating := v_avg - v_teamavg; 116 | RETURN v_rating; 117 | EXCEPTION 118 | WHEN OTHERS THEN 119 | raise_application_error(-20001,'An error was encountered player performance above team avg - '||SQLCODE||' -ERROR- '||SQLERRM); 120 | END; 121 | ``` 122 | 123 | - Test function 124 | ``` 125 | select a.name, a.avg, avgRating(a.avg) Batting_Ranking from teamstats a 126 | ``` 127 | 128 | - Update view 129 | ``` 130 | create or replace view v_teamstats as select a.name, avg, slg, obp, ops(a.slg, a.obp) ops, avgRating(a.avg) Team_Avg_Rating from teamstats a 131 | ``` 132 | 133 | - Query View 134 | ``` 135 | select * from v_teamstats 136 | ``` -------------------------------------------------------------------------------- /apex_expandable_pageitem.md: -------------------------------------------------------------------------------- 1 | ### Oracle APEX Expandable Page Item Text 2 | In this video we will illustrate one way to create expand/collapsible text inside a display only page item in Oracle APEX. This is very useful if a developed is working with long varchar2 or CLOB values and wants to keep a clean UI when displaying information on a custom page. The demonstration was developed on Oracle Autonomous Transaction Processing leveraging Oracle APEX 23.2.1 on Oracle Cloud Infrastructure. This tutorial assumes some basic APEX knowledge is present. That a user has a workspace, the ability to create an application and page inside the application. 3 | 4 | ## Step 1: Watch Youtube Demonstration 5 | To start we reccomend watching the following youtube video before following the instructions below. 6 | [https://youtu.be/VXih0-R3m8I](https://youtu.be/VXih0-R3m8I) 7 | 8 | ## Step 2: Follow Steps to Create Expand/Collapsable page Item 9 | 10 | - Access or create a new application and page in APEX. (Assumed knowledge.) 11 | 12 | - Create a new region on your page. 13 | 14 | ![](assets/2024-01-24-08-56-40.png) 15 | 16 | - Add a Display Only page item. 17 | 18 | ![](assets/2024-01-24-08-59-14.png) 19 | ![](assets/2024-01-24-09-01-39.png) 20 | 21 | - Rename your Region to Article. 22 | 23 | ![](assets/2024-01-24-09-03-04.png) 24 | 25 | - Rename your page item to P7_Article, remove the Label text and set format to HTML. 26 | 27 | ![](assets/2024-01-24-09-04-50.png) 28 | 29 | - Click on the lightning bolt and create a new Page Load dynamic action to seed the default value of the text in the page item. 30 | 31 | ![](assets/2024-01-24-10-37-35.png) 32 | 33 | Name your dynamic action. 34 | 35 | ![](assets/2024-01-24-10-39-31.png) 36 | 37 | - Name the true action "seedArticle" and set the action to set value. 38 | 39 | ![](assets/2024-01-24-10-42-53.png) 40 | 41 | - Set the page item to your text field and make sure your Fire on Inialization is set to true. 42 | 43 | ![](assets/2024-01-24-10-44-10.png) 44 | 45 | - Set the Type to SQL query. We will now create a query to get the first 100 characters of our varchar2 or clob we wish to display. To keep it simple we will select text from dual. But this could be a column in your table. 46 | 47 | ![](assets/2024-01-24-10-45-07.png) 48 | 49 | 50 | Paste in this query. 51 | 52 | ``` 53 | select SUBSTR('The Sluggers 2023 fall season was the teams'' seventh together and by far the teams most successful.The 13u Sluggers team began the season by acquiring two new players PW and CJ. The additional OF and IF depth helped early on as the team faced many injuries, and as the team adjusted to the 60-90 field dimensions. The team played in three tournaments along with a full NVTBL season. In tournament play, the team finish with a 8-4 record placing second in both the Zombie Apocalypse and Winchester Field of Screams tournamentsl. For the season the team batted .327 across 26 games scoring a record 220 runs averaging 8.4 per game. The team improved considerable pitching with a team ERA of 4.16 allowing 4.9 runs per game while pitching seven players ten or more innings in the season. The season ended with a 18-8 record setting the stage for a great spring 2024 season.',0,100)||'... '||'Read More' as "Article" from dual 54 | ``` 55 | Pleae note that this query includes HTML like below that will on-click spawn a Jquery event that will return the full article. We will build this event in a moment. 56 | 57 | ``` 58 | Read More 59 | ``` 60 | 61 | - Run your page in the APEX application. You should see the following. 62 | 63 | ![](assets/2024-01-24-10-49-31.png) 64 | 65 | - Now we will create a new custom action to modify the the page item to display the entire article. Navigate back to your APEX development screen right click on events and create a new Dynamic Action. 66 | 67 | ![](assets/2024-01-24-10-54-08.png) 68 | 69 | 70 | - Now we will name the dynamic action "showAllText". Under the When dropdown set the Event type to "Custom", name the custom event "showFullText". Set the Selection Type to "Javascript Expression" and type in the word "document" in the expression field. Please note that the word document apply the Jquery function to the entire document itself when triggers. 71 | 72 | ![](assets/2024-01-24-10-56-33.png) 73 | 74 | The Custom Event name, in this example showFullText is the name we will trigger in our html link. 75 | ``` 76 | $.event.trigger('showFullText'); 77 | ``` 78 | 79 | - Click on your true event. Modify the following fields. 80 | Set the Name to "showAllText". 81 | Set Action to "Set Value". 82 | Make sure the Escape Special Characters is set to false. 83 | Set the Item(s) to be set to your text field, in this example P7_article. 84 | Make sure Fire on Initialization is set to false. 85 | 86 | ![](assets/2024-01-24-11-04-03.png) 87 | 88 | Last but not least paste in the query below. This will query your article and return all the text with a read less link at the bottom to return to the shorter article. 89 | 90 | ``` 91 | select 'The Sluggers 2023 fall season was the teams'' seventh together and by far the teams most successful.The 13u Sluggers 92 | team began the season by acquiring two new players PW and CJ. The additional OF and IF depth helped early on as the team faced 93 | many injuries, and as the team adjusted to the 60-90 field dimensions. The team played in three tournaments along with a full 94 | NVTBL season. In tournament play, the team finish with a 8-4 record placing second in both the Zombie Apocalypse and Winchester 95 | Field of Screams tournamentsl. For the season the team batted .327 across 26 games scoring a record 220 runs averaging 8.4 per game. 96 | The team improved considerable pitching with a team ERA of 4.16 allowing 4.9 runs per game while pitching seven players ten or more innings 97 | in the season. The season ended with a 18-8 record setting the stage for a great spring 2024 season.' 98 | ||'
Read Less' as "Article" from dual 99 | ``` 100 | 101 | - Run your page, click on the read more button. You should see the full article appear. Next we will wire our Read Less button to return to the prior state. 102 | 103 | ![](assets/2024-01-24-11-11-34.png) 104 | 105 | - Create another dynamic action. 106 | 107 | ![](assets/2024-01-24-10-54-08.png) 108 | 109 | - Set the name to "showLessText". Set the event type to "custom". Set the Custom Event name to "showLessText". Set the selection type to Javascript Expression and the Javascript Expression field to document. 110 | 111 | ![](assets/2024-01-24-11-59-26.png) 112 | 113 | - Navigate to the true action. Much like before we name it "showLessText". Set the action as set Value. Set both Escape special characters and fire on initialization to false. Set the Item to set to P7_Article. 114 | 115 | ![](assets/2024-01-24-12-03-32.png) 116 | 117 | Last but not least set our query to the one below. Please notice this query matches our intial one on page load, only it fires on-click as opposed to page load. 118 | 119 | ``` 120 | select SUBSTR('The Sluggers 2023 fall season was the teams'' seventh together and by far the teams most successful. 121 | The 13u Sluggers team began the season by acquiring two new players PW and CJ. The additional OF and IF depth helped early 122 | on as the team faced many injuries, and as the team adjusted to the 60-90 field dimensions. The team played in three 123 | tournaments along with a full NVTBL season. In tournament play, the team finish with a 8-4 record placing second in both 124 | the Zombie Apocalypse and Winchester Field of Screams tournamentsl. For the season the team batted .327 across 26 games 125 | scoring a record 220 runs averaging 8.4 per game. The team improved considerable pitching with a team ERA of 4.16 allowing 126 | 4.9 runs per game while pitching seven players ten or more innings in the season. The season ended with a 18-8 record 127 | setting the stage for a great spring 2024 season.',0,100)||'... '|| 128 | 'Read More' 129 | as "Article" from dual 130 | ``` 131 | 132 | - Run your page again. Click Read more, then read less. You should see your page item dynamically refresh. 133 | 134 | ![](assets/2024-01-24-12-09-54.png) 135 | 136 | ![](assets/2024-01-24-12-10-16.png) 137 | 138 | -------------------------------------------------------------------------------- /apex_link_cssHide.md: -------------------------------------------------------------------------------- 1 | ## How to Leverage CSS selectors to Hide null Links in APEX Reports 2 | 3 | In this example we will show you how to leverage CSS selectors inside APEX classic reports to hide null values. We will start with a classic report that has a url inside one of the columns but has a number of null values. 4 | 5 | We reccomend watching this video as the guide for the steps below. [How to Remove Null Links Inside APEX Reports with CSS Selectors](https://youtu.be/vyxFeww1XyM) 6 | 7 | ![](assets/2023-08-30-08-56-18.png) 8 | 9 | Next we will convert this column to a link and leverage the APEX icon catalog to transform the url into a clickable image. 10 | ![](assets/2023-08-30-09-07-34.png) 11 | 12 | The APEX icon library can be found here. 13 | 14 | [APEX Video Icon](https://apex.oracle.com/pls/apex/r/apex_pm/ut/icons) 15 | 16 | ![](assets/2023-08-30-09-04-10.png) 17 | 18 | Code for span tag leveraged in video 19 | 20 | ``` 21 | 22 | 23 | target="_new" 24 | ``` 25 | ![](assets/2023-08-30-09-11-50.png) 26 | 27 | Your report at this point will display icons for all the rows even if the value is null. 28 | 29 | ![](assets/2023-08-30-09-12-28.png) 30 | 31 | Now we will take a look at how to quickly create a CSS selector that will remove the icon if the value of the href is not a url. There are many ways to create a selector, in this example we will leverage the premise that a properly formed url will contain at least one period in the url. Additional CSS Selectors could also be applied if further checks were necessary. 32 | 33 | - Example CSS Selector text. 34 | 35 | ``` 36 | .hideNulls:not([href*="."]) {display:none;} 37 | ``` 38 | 39 | CSS is added to the page level. 40 | ![](assets/2023-08-30-09-18-51.png) 41 | 42 | 43 | CSS is then applied to the link in the report. 44 | ![](assets/2023-08-30-09-19-18.png) 45 | 46 | 47 | Final report 48 | ![](assets/2023-08-30-09-17-47.png) 49 | 50 | 51 | Some other CSS Selector code that may be of interest to hide null href. 52 | A[href=""], A[href="#"] {display: none;} -------------------------------------------------------------------------------- /apexversion.md: -------------------------------------------------------------------------------- 1 | ## Query to Get APEX Version, Patchset and ORDS Version 2 | 3 | - Query run on ATP free tier instance 4 | 5 | ``` 6 | select 'APEX' as product, version_no, api_compatibility, case when patch_applied = 'APPLIED' 7 | then (select listagg('Patch ' || to_char(patch_number) || ' (' || patch_version || ') installed on ' || installed_on, ', ') 8 | within group (order by installed_on) as patches from apex_patches) end as applied_patches from apex_release 9 | union all select 'ORDS' as product, ords.installed_version as version_no, null as api_compatibility, null as applied_patches from dual; 10 | ``` 11 | -------------------------------------------------------------------------------- /assets/2023-03-13-10-43-58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-03-13-10-43-58.png -------------------------------------------------------------------------------- /assets/2023-03-13-10-55-44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-03-13-10-55-44.png -------------------------------------------------------------------------------- /assets/2023-08-30-08-56-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-08-30-08-56-18.png -------------------------------------------------------------------------------- /assets/2023-08-30-09-04-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-08-30-09-04-10.png -------------------------------------------------------------------------------- /assets/2023-08-30-09-07-34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-08-30-09-07-34.png -------------------------------------------------------------------------------- /assets/2023-08-30-09-11-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-08-30-09-11-50.png -------------------------------------------------------------------------------- /assets/2023-08-30-09-12-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-08-30-09-12-28.png -------------------------------------------------------------------------------- /assets/2023-08-30-09-17-47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-08-30-09-17-47.png -------------------------------------------------------------------------------- /assets/2023-08-30-09-18-51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-08-30-09-18-51.png -------------------------------------------------------------------------------- /assets/2023-08-30-09-19-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-08-30-09-19-18.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-03-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-03-16.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-09-56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-09-56.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-28-05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-28-05.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-28-58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-28-58.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-30-33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-30-33.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-31-59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-31-59.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-33-31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-33-31.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-34-52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-34-52.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-35-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-35-12.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-37-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-37-28.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-38-31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-38-31.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-40-51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-40-51.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-42-56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-42-56.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-43-31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-43-31.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-44-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-44-24.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-46-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-46-03.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-47-25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-47-25.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-48-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-48-04.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-49-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-49-29.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-52-36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-52-36.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-56-55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-56-55.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-58-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-58-17.png -------------------------------------------------------------------------------- /assets/2023-09-22-14-58-47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-14-58-47.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-01-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-01-29.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-04-09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-04-09.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-05-34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-05-34.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-13-00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-13-00.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-14-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-14-30.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-15-06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-15-06.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-15-54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-15-54.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-17-38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-17-38.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-18-44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-18-44.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-19-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-19-11.png -------------------------------------------------------------------------------- /assets/2023-09-22-15-21-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-22-15-21-29.png -------------------------------------------------------------------------------- /assets/2023-09-28-10-34-39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-28-10-34-39.png -------------------------------------------------------------------------------- /assets/2023-09-28-10-35-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-28-10-35-32.png -------------------------------------------------------------------------------- /assets/2023-09-28-10-36-08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-28-10-36-08.png -------------------------------------------------------------------------------- /assets/2023-09-28-10-36-41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-28-10-36-41.png -------------------------------------------------------------------------------- /assets/2023-09-28-10-37-58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-09-28-10-37-58.png -------------------------------------------------------------------------------- /assets/2023-10-10-09-32-46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2023-10-10-09-32-46.png -------------------------------------------------------------------------------- /assets/2024-01-24-08-56-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-08-56-40.png -------------------------------------------------------------------------------- /assets/2024-01-24-08-59-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-08-59-14.png -------------------------------------------------------------------------------- /assets/2024-01-24-09-01-39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-09-01-39.png -------------------------------------------------------------------------------- /assets/2024-01-24-09-03-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-09-03-04.png -------------------------------------------------------------------------------- /assets/2024-01-24-09-04-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-09-04-50.png -------------------------------------------------------------------------------- /assets/2024-01-24-10-37-35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-10-37-35.png -------------------------------------------------------------------------------- /assets/2024-01-24-10-39-31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-10-39-31.png -------------------------------------------------------------------------------- /assets/2024-01-24-10-42-53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-10-42-53.png -------------------------------------------------------------------------------- /assets/2024-01-24-10-44-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-10-44-10.png -------------------------------------------------------------------------------- /assets/2024-01-24-10-45-07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-10-45-07.png -------------------------------------------------------------------------------- /assets/2024-01-24-10-49-31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-10-49-31.png -------------------------------------------------------------------------------- /assets/2024-01-24-10-54-08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-10-54-08.png -------------------------------------------------------------------------------- /assets/2024-01-24-10-56-33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-10-56-33.png -------------------------------------------------------------------------------- /assets/2024-01-24-11-01-07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-11-01-07.png -------------------------------------------------------------------------------- /assets/2024-01-24-11-04-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-11-04-03.png -------------------------------------------------------------------------------- /assets/2024-01-24-11-06-56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-11-06-56.png -------------------------------------------------------------------------------- /assets/2024-01-24-11-11-34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-11-11-34.png -------------------------------------------------------------------------------- /assets/2024-01-24-11-59-26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-11-59-26.png -------------------------------------------------------------------------------- /assets/2024-01-24-12-03-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-12-03-32.png -------------------------------------------------------------------------------- /assets/2024-01-24-12-09-54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-12-09-54.png -------------------------------------------------------------------------------- /assets/2024-01-24-12-10-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-01-24-12-10-16.png -------------------------------------------------------------------------------- /assets/2024-03-01-09-44-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-03-01-09-44-12.png -------------------------------------------------------------------------------- /assets/2024-03-01-09-46-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-03-01-09-46-14.png -------------------------------------------------------------------------------- /assets/2024-03-01-09-48-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-03-01-09-48-11.png -------------------------------------------------------------------------------- /assets/2024-03-01-09-48-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-03-01-09-48-32.png -------------------------------------------------------------------------------- /assets/2024-06-12-13-58-56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/2024-06-12-13-58-56.png -------------------------------------------------------------------------------- /assets/classic_cell_formatting-0a0b23bf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/classic_cell_formatting-0a0b23bf.png -------------------------------------------------------------------------------- /assets/classic_cell_formatting-64643eb8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/classic_cell_formatting-64643eb8.png -------------------------------------------------------------------------------- /assets/classic_cell_formatting-790aeeff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/classic_cell_formatting-790aeeff.png -------------------------------------------------------------------------------- /assets/indexedDocsCheck-0673052d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/indexedDocsCheck-0673052d.png -------------------------------------------------------------------------------- /assets/indexedDocsCheck-1efbcd19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/indexedDocsCheck-1efbcd19.png -------------------------------------------------------------------------------- /assets/indexedDocsCheck-7fabc7a3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/indexedDocsCheck-7fabc7a3.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-05a3d666.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-05a3d666.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-0763aa23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-0763aa23.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-1081d676.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-1081d676.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-1f5b0a99.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-1f5b0a99.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-1fa933c9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-1fa933c9.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-25b94ab9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-25b94ab9.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-2f08d38e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-2f08d38e.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-3081382b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-3081382b.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-357587ec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-357587ec.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-3c45fe4f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-3c45fe4f.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-4103a4bf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-4103a4bf.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-4c778540.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-4c778540.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-5651e28c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-5651e28c.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-5709830e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-5709830e.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-5828af96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-5828af96.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-6a66c162.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-6a66c162.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-755bbff4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-755bbff4.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-79ac84e5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-79ac84e5.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-7e7ca268.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-7e7ca268.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-7f80f8c5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-7f80f8c5.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-9371e009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-9371e009.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-a04e43a0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-a04e43a0.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-a122c046.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-a122c046.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-b15fea9f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-b15fea9f.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-b6dd6627.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-b6dd6627.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-b7f7c368.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-b7f7c368.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-c9bac9b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-c9bac9b1.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-cbddcc58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-cbddcc58.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-ce29aad3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-ce29aad3.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-d29eb3ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-d29eb3ae.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-e679437a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-e679437a.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-ea0babf0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-ea0babf0.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-eee346be.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-eee346be.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-fccf2e85.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-fccf2e85.png -------------------------------------------------------------------------------- /assets/ords_resume_upload-fd713152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/ords_resume_upload-fd713152.png -------------------------------------------------------------------------------- /assets/po_xml.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | Ellen Adams 5 | 123 Maple Street 6 | Mill Valley 7 | CA 8 | 10999 9 | USA 10 |
11 |
12 | Tai Yee 13 | 8 Oak Avenue 14 | Old Town 15 | PA 16 | 95819 17 | USA 18 |
19 | Please leave packages in shed by driveway. 20 | 21 | 22 | Lawnmower 23 | 1 24 | 148.95 25 | Confirm this is electric 26 | 27 | 28 | Baby Monitor 29 | 2 30 | 39.98 31 | 1999-05-21 32 | 33 | 34 |
35 | -------------------------------------------------------------------------------- /assets/teamstats.csv: -------------------------------------------------------------------------------- 1 | ID,JERSEY,NAME,GP,PA,AB,H,C1B,C2B,C3B,HR,RBI,R,BB,SO,K_L,HBP,SAC,SF,ROE,FC,SB,QAB,QAB_,LOB,XBH,TB,PS,VIDEO 2 | 1,4,Nathaniel,20,58,49,19,9,6,2,2,11,21,5,11,3,2,1,1,5,1,11,27,46.55,15,10,35,198, 3 | 2,7,Jack,14,34,24,5,4,1,0,0,1,9,10,6,3,0,0,0,0,0,3,21,61.76,23,1,6,159, 4 | 3,8,Brodie,20,62,53,26,15,4,3,4,22,30,5,4,0,3,0,1,5,1,22,35,56.45,16,11,48,225, 5 | 4,9,Kellan,20,61,49,19,9,9,0,1,11,20,11,5,1,1,0,0,4,0,9,28,45.9,24,10,31,231, 6 | 5,11,Tank,18,54,47,18,8,7,1,2,27,15,4,4,1,3,0,0,2,2,8,25,46.3,19,10,33,178,https://youtu.be/kz1E99o0KEU 7 | 6,17,Ben,14,28,25,8,7,1,0,0,6,7,3,4,1,0,0,0,2,1,0,10,35.71,14,1,9,113, 8 | 7,21,Noah,20,45,35,8,7,1,0,0,3,7,9,9,2,0,0,1,1,1,1,23,51.11,22,1,9,180, 9 | 8,22,Kaleb,20,58,46,14,9,3,0,2,12,10,9,8,3,1,1,1,0,0,6,25,43.1,23,5,23,187, 10 | 9,23,Chase,20,50,38,11,8,3,0,0,8,11,10,10,5,1,0,0,0,2,1,22,44,29,3,14,205, 11 | 10,27,Connor,19,42,32,6,5,1,0,0,5,7,10,10,4,0,0,0,0,1,3,19,45.24,31,1,7,189, 12 | 11,28,Matthew,18,44,36,12,9,3,0,0,8,9,8,6,1,0,0,0,3,2,1,20,45.45,17,3,15,155, 13 | 12,99,Charles,20,52,37,9,8,1,0,0,5,9,13,4,1,2,0,0,3,2,3,24,46.15,18,1,10,194, 14 | -------------------------------------------------------------------------------- /assets/teamstats.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/teamstats.xlsx -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-147e05fe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-147e05fe.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-472aa6d7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-472aa6d7.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-47475732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-47475732.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-64290b32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-64290b32.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-8919434f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-8919434f.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-9fa40b81.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-9fa40b81.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-a6449a5f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-a6449a5f.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-afb53eb3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-afb53eb3.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-c13cab02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-c13cab02.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-c5e54fd3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-c5e54fd3.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-d2feee39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-d2feee39.png -------------------------------------------------------------------------------- /assets/xml_ORDS_ingestion-e5f9992f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_ORDS_ingestion-e5f9992f.png -------------------------------------------------------------------------------- /assets/xml_queries-3de3d3cf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_queries-3de3d3cf.png -------------------------------------------------------------------------------- /assets/xml_trigger-400f78ba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipbaber/apex_textdemo/e30552d5c1417aadf2765fbfac69ad98fd2b242e/assets/xml_trigger-400f78ba.png -------------------------------------------------------------------------------- /ci_sr_add.md: -------------------------------------------------------------------------------- 1 | ``` 2 | declare 3 | v_eventdate ci_sessions.EVENT_DATE%type; 4 | v_oppt ci_sessions.OPPT_%type; 5 | v_id ci_sessions.ID%type; 6 | v_count number(4) :=0; 7 | v_countErr number(4) :=0; 8 | --dynamic sql variables 9 | sql_stmt VARCHAR2(700); 10 | sql_update VARCHAR2(700); 11 | v_sr ci_sr_hours.sr_number%TYPE; 12 | v_expFilter varchar2(32000); 13 | 14 | 15 | --Script to add in or update SR number to weekly stats 16 | --cursor to get all current values is step 1 17 | CURSOR sessions IS 18 | select event_date, oppt_, id from ci_sessions where service_request is null; 19 | 20 | begin 21 | dbms_output.put_line('Starting procedure'); 22 | v_expFilter := '"DV - SE Team"."Opportunity"."Opportunity ID" in ('; 23 | --begin loop 24 | OPEN sessions; 25 | LOOP 26 | FETCH sessions INTO v_eventdate, v_oppt, v_id; 27 | EXIT WHEN sessions%notfound; 28 | --Look for SR with dynamic sql 29 | sql_stmt := 'select sr_number from ci_sr_hours where :v_oppt = opportunity_id and :v_eventdate between first_effort and last_effort'; 30 | 31 | --Putting Dynamic SQL in error block to check if oddity with SR number so program can proceed. 32 | begin 33 | EXECUTE IMMEDIATE sql_stmt INTO v_sr USING v_oppt, v_eventdate; 34 | dbms_output.put_line('Query Executed results for ID: '||v_id|| chr(10)||' Event Date: '||v_eventdate||' - Oppt ID: '||v_oppt||' - SR: '||v_sr); 35 | 36 | begin 37 | -- update row into DB. 38 | sql_update := 'update ci_sessions set service_request = :v_sr where id = :v_id '; 39 | 40 | EXECUTE IMMEDIATE sql_update USING v_sr, v_id; 41 | EXCEPTION 42 | WHEN OTHERS THEN 43 | dbms_output.put_line('Error on insert for id: '||v_id); 44 | end; 45 | 46 | v_count := v_count+1; 47 | EXCEPTION 48 | WHEN OTHERS THEN 49 | v_countErr := v_countErr+1; 50 | --dbms_output.put_line('Error processing row ID: '||v_id||' in ci_sessions table. Query below.'); 51 | --v_expFilter := v_expFilter||' ''' ||v_oppt||''','; 52 | --dbms_output.put_line('select * from ci_sessions where id = '||v_id); 53 | --dbms_output.put_line('select sr_number from ci_sr_hours where '''||v_oppt||''' = opportunity_id and '''||v_eventdate||''' between first_effort and last_effort'); 54 | end; 55 | 56 | 57 | END LOOP; 58 | CLOSE sessions; 59 | -- v_expFilter := substr(v_expFilter, 1, length(v_expFilter)-1) || ')'; 60 | 61 | commit; 62 | dbms_output.put_line('Rows Updated:' || v_count); 63 | dbms_output.put_line('Rows not Processed:' || v_countErr); 64 | EXCEPTION 65 | WHEN OTHERS THEN 66 | dbms_output.put_line('Other Error occurred: '); 67 | end; 68 | 69 | ``` -------------------------------------------------------------------------------- /classic_cell_formatting.md: -------------------------------------------------------------------------------- 1 | # Example Jquery for customizing a single cell inside a Classic Report 2 | 3 | Please reference this youtube video for a more detailed explanation of the sample code below. [https://youtu.be/Auw5SoW9TXA](https://youtu.be/Auw5SoW9TXA) 4 | 5 | - Create a dynamic action on the classic report. Set the following attributes 6 | 7 | ![](assets/classic_cell_formatting-64643eb8.png) 8 | 9 | - Create a true action of type Execute Javascript Code 10 | 11 | ![](assets/classic_cell_formatting-0a0b23bf.png) 12 | 13 | - Set the flag to fire on initialization. 14 | 15 | ![](assets/classic_cell_formatting-790aeeff.png) 16 | 17 | - Lets look at the Javascript to format and extract value for evaluation. First here is the sample Jquery to output the data in the cell to the console log. This will loop through each row. 18 | 19 | ``` 20 | console.log("Changing Color of Cells"); 21 | 22 | $('td[headers="LOG_ID"]').each(function() { 23 | console.log($(this).text()); 24 | }); 25 | ``` 26 | - Next we will add in some Styling Logic. First create a CSS class on the page. 27 | ``` 28 | .lowTargets{ 29 | background-color: #284e3f; 30 | font-weight: 600; 31 | text-align: center; 32 | color: white; 33 | border:2px solid #cecece; 34 | } 35 | 36 | .midTargets{ 37 | background-color: #16505b; 38 | font-weight: 800; 39 | text-align: center; 40 | color: white; 41 | border:2px solid #cecece; 42 | } 43 | 44 | ``` 45 | - Save page and add logic to apply to certain cells in Jquery. 46 | ``` 47 | console.log("Formatting Cells"); 48 | 49 | $('td[headers="LOG_ID"]').each(function() { 50 | //add your formatting logic 51 | if ($(this).text() < '1350') { 52 | $(this).addClass("lowTargets"); 53 | } 54 | }); 55 | ``` 56 | 57 | -- 58 | ``` 59 | console.log("Formatting Cells"); 60 | 61 | $('td[headers="LOG_ID"]').each(function() { 62 | // console.log($(this).text()); 63 | //add your formatting logic 64 | if ($(this).text() < '1375') { 65 | $(this).addClass("lowTargets"); 66 | } 67 | if ( $(this).text() >= '1350' && $(this).text() < '1400') { 68 | $(this).addClass("midTargets"); 69 | } 70 | 71 | }); 72 | ``` 73 | -------------------------------------------------------------------------------- /clientisdeValidations.md: -------------------------------------------------------------------------------- 1 | # Sample Code Referenced in How to Develop Client Side Validations without Page Submit 2 | This markdown contains sameple code for the video below. 3 | 4 | - It is reccomended to watch this video first. [https://youtu.be/7-y9f7zEWSE?si=dtAu9viAXFOi7e-i](https://youtu.be/7-y9f7zEWSE?si=dtAu9viAXFOi7e-i) 5 | 6 | - Code shown at 00:56 highlighting the core javscript on the page level to be called. 7 | ``` 8 | 57 | ``` 58 | 59 | - Code shown at 2:14 dynamic action javascript validation 60 | ``` 61 | console.log("P2_Q2_GATE Validations Firing"); 62 | let v_tempVar = toCN($v("P2_Q2_GATE")); 63 | 64 | //Make sure numeric 65 | if(hasLetters(v_tempVar)){ 66 | apex.message.alert("Your Q2 Gate contains non-numeric characters. Please try again."); 67 | $s("P2_Q2_GATE",""); 68 | } 69 | 70 | //Make sure positive number 71 | if (isNegative(v_tempVar)){ 72 | apex.message.alert("Your Q2 Gate must be a positive number. Please try again."); 73 | $s("P2_Q2_GATE",""); 74 | } 75 | 76 | //Has to be greater than Q1_Gate 77 | if (v_tempVar < toCN($v("P2_Q1_GATE"))){ 78 | apex.message.alert("Your Q2 Gate must be > than your q1 gate. Please try again."); 79 | $s("P2_Q2_GATE",""); 80 | } 81 | 82 | //Has to be less than Q4_Gate 83 | if (v_tempVar > toCN($v("P2_Q4_GATE"))){ 84 | apex.message.alert("Your Q2 Gate must be < than your q4 gate. Please try again."); 85 | $s("P2_Q2_GATE",""); 86 | } 87 | 88 | ``` -------------------------------------------------------------------------------- /comments.md: -------------------------------------------------------------------------------- 1 | ## Intro to Oracle APEX Comments Theme Component - 101 2 | Please watch the following video first before proceeding with the code below. 3 | [Intro to the APEX Comments Theme Component Video](https://youtu.be/4Dl6_2wX-oE) 4 | 5 | -- Below is a static query used in the video above for the comments 6 | ``` 7 | select 13 id, 8 | (sysdate-2) comment_date, 9 | lower(APEX_CUSTOM_AUTH.GET_USERNAME) user_name, 10 | 'He really barrelled up this pitch. ' comment_text, 11 | 'https://youtu.be/FbBq5-oaWU4' attribute_1, 12 | 'https://ayxzx2tnd0tqzed-sluggersapex.adb.us-ashburn-1.oraclecloudapps.com/ords/r/searchdemo/105/files/static/v7/baseballcards/tank.png' attribute_2 13 | from dual 14 | union all 15 | select 14 id, 16 | (sysdate) comment_date, 17 | 'Coach Bill' user_name, 18 | 'Excellent timing on the pitch, with good eye hand contact.' comment_text, 19 | ' ' attribute_1, 20 | ' ' attribute_2 21 | from dual 22 | ``` 23 | 24 | - Example HTML Code for the attributes section of the comments section. 25 | ``` 26 | 27 | 28 |   29 | &ATTRIBUTE_1. 30 | ``` 31 | 32 | ## Building Row Level Comments on a Report with the Oracle APEX Comments Theme Component 33 | 34 | Please watch the following video before proceeding through the sample Code below. [How to Add Row Level Comments to a APEX Report](https://youtu.be/5iqmxavQD08) The following steps were performed in an Oracle Autonomous Database on a free tier account leveraging APEX 23.1.2 at the time of the recording. 35 | 36 | - Navigate to SQL Worshop -> SQL Commands and execute the following to create a new table to hold our comments. Please note this is a sample table with the basics for the comments theme component. Highlight each command and click run or copy and paste one at a time. We will also create a teamstats table as illustrated in the video above. 37 | 38 | ![](assets/2023-09-22-14-03-16.png) 39 | 40 | ``` 41 | CREATE TABLE "COMMENTS" 42 | ( "C_ID" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE, 43 | "PLAYER_ID" NUMBER NOT NULL ENABLE, 44 | "COMMENTER" VARCHAR2(150) COLLATE "USING_NLS_COMP", 45 | "COMMENT_DATE" TIMESTAMP (6), 46 | "COMMENT_TEXT" VARCHAR2(6000) COLLATE "USING_NLS_COMP", 47 | "ACTIONS" VARCHAR2(250) COLLATE "USING_NLS_COMP", 48 | "ATTRIBUTE_1" VARCHAR2(6000) COLLATE "USING_NLS_COMP", 49 | "ATTRIBUTE_2" VARCHAR2(6000) COLLATE "USING_NLS_COMP", 50 | "ATTRIBUTE_3" VARCHAR2(6000) COLLATE "USING_NLS_COMP", 51 | "ATTRIBUTE_4" VARCHAR2(6000) COLLATE "USING_NLS_COMP", 52 | CONSTRAINT "COMMENTS_PK" PRIMARY KEY ("C_ID") 53 | USING INDEX ENABLE) DEFAULT COLLATION "USING_NLS_COMP" ; 54 | 55 | COMMENT ON COLUMN "COMMENTS"."C_ID" IS 'primary key for each comment'; 56 | COMMENT ON COLUMN "COMMENTS"."PLAYER_ID" IS 'foreign key connecting to the player id'; 57 | COMMENT ON COLUMN "COMMENTS"."COMMENTER" IS 'name of person making comment'; 58 | COMMENT ON COLUMN "COMMENTS"."COMMENT_DATE" IS 'date of comment'; 59 | COMMENT ON COLUMN "COMMENTS"."COMMENT_TEXT" IS 'text of comment'; 60 | COMMENT ON COLUMN "COMMENTS"."ACTIONS" IS 'freeform actions field'; 61 | COMMENT ON COLUMN "COMMENTS"."ATTRIBUTE_1" IS 'freeform attribute field'; 62 | COMMENT ON COLUMN "COMMENTS"."ATTRIBUTE_2" IS 'freeform attribute field'; 63 | COMMENT ON COLUMN "COMMENTS"."ATTRIBUTE_3" IS 'freeform attribute field'; 64 | COMMENT ON COLUMN "COMMENTS"."ATTRIBUTE_4" IS 'freeform attribute field'; 65 | COMMENT ON TABLE "COMMENTS" IS 'example table for comments'; 66 | 67 | CREATE TABLE "TEAMSTATS" 68 | ( "ID" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE, "JERSEY" NUMBER, "NAME" VARCHAR2(100) COLLATE "USING_NLS_COMP", 69 | "GP" NUMBER, "PA" NUMBER, "AB" NUMBER, "H" NUMBER, "C1B" NUMBER, "C2B" NUMBER, 70 | "C3B" NUMBER, "HR" NUMBER, "RBI" NUMBER, "R" NUMBER, "BB" NUMBER, "SO" NUMBER, 71 | "K_L" NUMBER, "HBP" NUMBER, "SAC" NUMBER, "SF" NUMBER, "ROE" NUMBER, "FC" NUMBER, 72 | "SB" NUMBER, "QAB" NUMBER, "QAB_" NUMBER, "LOB" NUMBER, "XBH" NUMBER, "TB" NUMBER, 73 | "PS" NUMBER, 74 | "AVG" NUMBER GENERATED ALWAYS AS (ROUND("H"/"AB",3)) VIRTUAL , 75 | "OBP" NUMBER GENERATED ALWAYS AS (ROUND(("H"+"BB"+"HBP")/("AB"+"BB"+"HBP"+"SAC"),3)) VIRTUAL , 76 | "SLG" NUMBER GENERATED ALWAYS AS (ROUND("TB"/"AB",3)) VIRTUAL , 77 | "VIDEO" VARCHAR2(2500) COLLATE "USING_NLS_COMP", 78 | PRIMARY KEY ("ID") 79 | USING INDEX ENABLE 80 | ) DEFAULT COLLATION "USING_NLS_COMP" ; 81 | 82 | alter table "SEARCHDEMO"."COMMENTS" add constraint 83 | "COMMENTS_CON" foreign key ( "PLAYER_ID" ) references "TEAMSTATS" ( "ID" ); 84 | / 85 | 86 | 87 | ``` 88 | 89 | - To simplify the logic needed in our app later on we will create a trigger that on insert or update saves the APEX_USER performing the action and a timestamp of when the database action was performed. Copy and run this in SQL Commands. 90 | 91 | ![](assets/2023-09-22-14-09-56.png) 92 | 93 | ``` 94 | create or replace trigger commentsTrigger 95 | before insert or update 96 | on comments 97 | for each row 98 | begin 99 | if inserting then 100 | :new.comment_date := systimestamp; 101 | :new.commenter := coalesce(sys_context('APEX$SESSION','APP_USER'),user); 102 | end if; 103 | :new.comment_date := systimestamp; 104 | :new.commenter := coalesce(sys_context('APEX$SESSION','APP_USER'),user); 105 | end commentsTrigger; 106 | / 107 | ``` 108 | 109 | - Lets load some sample data into the teamstats table for later use in the report. Download the sample .csv [https://github.com/chipbaber/apex_textdemo/blob/main/assets/teamstats.csv](https://github.com/chipbaber/apex_textdemo/blob/main/assets/teamstats.csv) 110 | 111 | ![](assets/2023-09-28-10-34-39.png) 112 | 113 | - Open the Object Browser in the SQL Worksheet. And select the teamstats table. 114 | ![](assets/2023-09-28-10-35-32.png) 115 | ![](assets/2023-09-28-10-36-08.png) 116 | 117 | - Click the Data Tab then load data sub tab. 118 | ![](assets/2023-09-28-10-36-41.png) 119 | 120 | - Select the CSV file when prompted. Then click load data. 121 | 122 | ![](assets/2023-09-28-10-37-58.png) 123 | 124 | - The next part of this tutorial assumes the user has the knowledge to create an application, a page and a report. The tutorial starts with that in place. If you are not familiar it may be good to reference this tutorial. [https://youtu.be/bB6Yxb5uNRY](https://youtu.be/bB6Yxb5uNRY) For this example we will leverage a classic report but the same could apply to a interactive report as well. 125 | 126 | 127 | - Open your application and create a new page. 128 | ![](assets/2023-09-22-14-28-05.png) 129 | 130 | - Select the form option. 131 | ![](assets/2023-09-22-14-28-58.png) 132 | 133 | - Name the form, set it to be a Modal Dialog then select the comments table you created earlier. Make sure to remember the assigned page number. 134 | ![](assets/2023-09-22-14-30-33.png) 135 | 136 | - In the next prompt leave the primary key as the field c_id and create the page. 137 | ![](assets/2023-09-22-14-31-59.png) 138 | 139 | - Select the fields highlighted in green below and set there type as hidden. We are going to start with the most basic comment form we can. These fields could be leveraged at future dates for more complex comments designs. We reccomend you watch [Intro to the APEX Comments Theme Component Video](https://youtu.be/4Dl6_2wX-oE) if you need an example. 140 | 141 | ![](assets/2023-09-22-14-34-52.png) 142 | 143 | ![](assets/2023-09-22-14-35-12.png) 144 | 145 | - Right click on the Content Body and create a region. 146 | ![](assets/2023-09-22-14-37-28.png) 147 | 148 | - Name the region, then set the type to comments. 149 | ![](assets/2023-09-22-14-38-31.png) 150 | 151 | - Set the source table and the where clause. In our example each row in the table will represent a player ID. The where clause will filter to just the comments on that player. Please note the P5 variable passing in could change based on your page number for your modular form. 152 | ![](assets/2023-09-22-14-40-51.png) 153 | 154 | - Click on the attributes tab. Then set the comment text, user name and date fields. 155 | ![](assets/2023-09-22-14-42-56.png) 156 | ![](assets/2023-09-22-14-43-31.png) 157 | 158 | - Save your page. 159 | ![](assets/2023-09-22-14-44-24.png) 160 | 161 | - In your comment region right click on actions and create a new action. We will use this to edit our comments. 162 | ![](assets/2023-09-22-14-46-03.png) 163 | 164 | - For the new action set the values illustrated below. 165 | ![](assets/2023-09-22-14-47-25.png) 166 | 167 | - Click on No link defined. Then set the following parameters. You page number should be the modal form page number you recorded earlier. We will set the comment id, to the row we want to edit, clear the cache and return to the page. 168 | ![](assets/2023-09-22-14-48-04.png) 169 | ![](assets/2023-09-22-14-49-29.png) 170 | 171 | Please note the &CI_ID. variable is pulled from the comments theme component. 172 | ![](assets/2023-10-10-09-32-46.png) 173 | 174 | - Next we want to set a server side condition that only displays the edit action when the logged in user was the commentor. Basically we only want to be able to edit our own comments not others. Save your page after setting this variable. 175 | ![](assets/2023-09-22-14-52-36.png) 176 | 177 | - Now we are ready to link your report to your comments page and form. To do this navigate in APEX to the page where your report exists. Right click on the columns drop down and create a new virtual column. 178 | ![](assets/2023-09-22-14-56-55.png) 179 | 180 | - Name the header of the virtual column "Comments". 181 | ![](assets/2023-09-22-14-58-17.png) 182 | 183 | - Select No Link Defined, and set it to route the page number of our midal form. Set the player_id to the #JERSEY# number, in our example the unique identifier for our comments. 184 | ![](assets/2023-09-22-14-58-47.png) 185 | 186 | ![](assets/2023-09-22-15-01-29.png) 187 | 188 | - Paste in the HTML below to create a icon for the virtual column, enabling a user to click on it. 189 | ``` 190 | 191 | ``` 192 | ![](assets/2023-09-22-15-05-34.png) 193 | 194 | - Save and run your page. You should see the comments icon and when clicked it will open your form to comment on the player. 195 | 196 | ![](assets/2023-09-22-15-13-00.png) 197 | 198 | ![](assets/2023-09-22-15-14-30.png) 199 | 200 | - Enter a comment, press create. Then re-open the comment window. 201 | ![](assets/2023-09-22-15-15-06.png) 202 | 203 | - You should see your new comment. 204 | ![](assets/2023-09-22-15-15-54.png) 205 | 206 | - Press the edit link and modify your comment. Notice the form updates and you can now edit the text. 207 | ![](assets/2023-09-22-15-17-38.png) 208 | 209 | - Make a change and press apply. 210 | ![](assets/2023-09-22-15-18-44.png) 211 | 212 | - Reopen to see the comment has updated. 213 | ![](assets/2023-09-22-15-19-11.png) 214 | 215 | - If you log in as another user you can see that the edit button only appears for your comments. 216 | ![](assets/2023-09-22-15-21-29.png) 217 | 218 | - Run the code below to clean up your tables created in this example. 219 | 220 | ``` 221 | drop trigger commentsTrigger; 222 | drop table comments; 223 | drop table teamstats; 224 | ``` 225 | -------------------------------------------------------------------------------- /dataload_manipulation.md: -------------------------------------------------------------------------------- 1 | ## Rapid Data Load and Manipulation in APEX 2 | 3 | In this example we will take look at a very common scenario in which a business user provides a member of IT a spreadsheet list of data. The list is intended to guide IT on a new report or application action. IT needs to consume the spreadsheet then programmatically generate code that can be leveraged in an application. In this example the core need is for a Oracle Analytics Cloud Data Visualizer Calculation to filter all the rows with certain global id's. 4 | 5 | - Please what this video for details on how to execute the example below. [How to Rapidly Load Data and Generate Code Blocks in APEX](https://youtu.be/CmT2d_UdlC0) 6 | 7 | - For this example we will leverage the [example_data.csv](https://github.com/chipbaber/apex_textdemo/blob/main/example_data.csv) as our input file. 8 | 9 | - Our desired output filter will look like, only it will include : 10 | 11 | ``` 12 | CASE WHEN "DV - SE Team"."Customer"."Oracle Global Ultimate ID" IN ('1259193') THEN 'P1' 13 | WHEN "DV - SE Team"."Customer"."Oracle Global Ultimate ID" IN ('1257516') THEN 'P2' 14 | WHEN "DV - SE Team"."Customer"."Oracle Global Ultimate ID" IN ('3687527') THEN 'P3' 15 | WHEN "DV - SE Team"."Customer"."Oracle Global Ultimate ID" IN ('11724079') THEN 'P4' 16 | WHEN "DV - SE Team"."Customer"."Oracle Global Ultimate ID" IN ('4511969') THEN 'P5' 17 | ELSE '-' END 18 | ``` 19 | 20 | -- Example Query to gauge the number of records that should be a part of the query. 21 | 22 | ``` 23 | select count(*) from ACCOUNT_PRIORITY where PGM_ACCT_PRIORITY is not null 24 | ``` 25 | 26 | -- Get number of IDs by priority accounts 27 | ``` 28 | select PGM_ACCT_PRIORITY, count(*) 29 | from ACCOUNT_PRIORITY where PGM_ACCT_PRIORITY is not null group by PGM_ACCT_PRIORITY order by PGM_ACCT_PRIORITY 30 | ``` 31 | 32 | -- Example Code to Generate Desired filter output. 33 | 34 | ``` 35 | declare 36 | -- core CLOB to hold the needed transformation 37 | v_calc clob; 38 | v_guid account_priority.END_USER_ORCL_GLB_ULT_REG_ID%type; 39 | 40 | CURSOR P1 IS select ''''|| END_USER_ORCL_GLB_ULT_REG_ID ||'''' from ACCOUNT_PRIORITY where PGM_ACCT_PRIORITY = 1; 41 | 42 | CURSOR P2 IS select ''''|| END_USER_ORCL_GLB_ULT_REG_ID ||'''' from ACCOUNT_PRIORITY where PGM_ACCT_PRIORITY = 2; 43 | 44 | CURSOR P3 IS select ''''|| END_USER_ORCL_GLB_ULT_REG_ID ||'''' from ACCOUNT_PRIORITY where PGM_ACCT_PRIORITY = 3; 45 | 46 | CURSOR P4 IS select ''''|| END_USER_ORCL_GLB_ULT_REG_ID ||'''' from ACCOUNT_PRIORITY where PGM_ACCT_PRIORITY = 4; 47 | 48 | CURSOR P5 IS select ''''|| END_USER_ORCL_GLB_ULT_REG_ID ||'''' from ACCOUNT_PRIORITY where PGM_ACCT_PRIORITY = 5; 49 | 50 | begin 51 | -- Start CLOB variable construction 52 | v_calc := 'CASE WHEN "DV - SE Team"."Customer"."Oracle Global Ultimate ID" IN ( '; 53 | 54 | OPEN P1; 55 | LOOP 56 | FETCH P1 into v_guid; 57 | EXIT WHEN P1%notfound; 58 | v_calc := v_calc||v_guid||', '; 59 | END LOOP; 60 | CLOSE P1; 61 | 62 | -- Trim last x2 characters from clob, then close first evaluation in block 63 | v_calc := substr(v_calc, 1, length(v_calc)-2) || ') THEN ''P1'' WHEN "DV - SE Team"."Customer"."Oracle Global Ultimate ID" IN ( '; 64 | 65 | -- Add P2 Accounts 66 | OPEN P2; 67 | LOOP 68 | FETCH P2 into v_guid; 69 | EXIT WHEN P2%notfound; 70 | v_calc := v_calc||v_guid||', '; 71 | END LOOP; 72 | CLOSE P2; 73 | 74 | -- Trim last x2 characters from clob, then close first evaluation in block 75 | v_calc := substr(v_calc, 1, length(v_calc)-2) || ') THEN ''P2'' WHEN "DV - SE Team"."Customer"."Oracle Global Ultimate ID" IN ( '; 76 | 77 | -- Add P3 Accounts 78 | OPEN P3; 79 | LOOP 80 | FETCH P3 into v_guid; 81 | EXIT WHEN P3%notfound; 82 | v_calc := v_calc||v_guid||', '; 83 | END LOOP; 84 | CLOSE P3; 85 | 86 | -- Trim last x2 characters from clob, then close first evaluation in block 87 | v_calc := substr(v_calc, 1, length(v_calc)-2) || ') THEN ''P3'' WHEN "DV - SE Team"."Customer"."Oracle Global Ultimate ID" IN ( '; 88 | 89 | -- Add P4 Accounts 90 | OPEN P4; 91 | LOOP 92 | FETCH P4 into v_guid; 93 | EXIT WHEN P4%notfound; 94 | v_calc := v_calc||v_guid||', '; 95 | END LOOP; 96 | CLOSE P4; 97 | -- Trim last x2 characters from clob, then close first evaluation in block 98 | v_calc := substr(v_calc, 1, length(v_calc)-2) || ') THEN ''P4'' WHEN "DV - SE Team"."Customer"."Oracle Global Ultimate ID" IN ( '; 99 | 100 | -- Add P5 Accounts 101 | OPEN P5; 102 | LOOP 103 | FETCH P5 into v_guid; 104 | EXIT WHEN P5%notfound; 105 | v_calc := v_calc||v_guid||', '; 106 | END LOOP; 107 | CLOSE P5; 108 | -- Trim last x2 characters from clob, then close first evaluation in block 109 | v_calc := substr(v_calc, 1, length(v_calc)-2) || ') THEN ''P5'' ELSE ''-'' END '; 110 | 111 | dbms_output.put_line(v_calc); 112 | end; 113 | ``` -------------------------------------------------------------------------------- /dynamicQuery.sql: -------------------------------------------------------------------------------- 1 | /* This is an example dynamic sql query that is used in a APEX report. 2 | PLease reference this video for more details. 3 | */ 4 | declare 5 | v_sql varchar2(32000); 6 | begin 7 | 8 | --If all the terms are null, display all resumes in the report. 9 | if (:P1_DOC_QUERY is null) AND (:P1_FIRSTWORD is null) AND (:P1_SECONDWORD is null) then 10 | --Return all resumes 11 | v_sql := q'~ 12 | select ROWID as "ROWID", 13 | DOC_ID as "ID", 14 | TITLE as "Title", 15 | SUBMITTED_BY as "Submitted By:", 16 | sys.dbms_lob.getlength(RESUME) as "Resume", 17 | MIMETYPE as "file Type", 18 | CREATED_DATE as "Created On", 19 | FILENAME as "File Name" 20 | from RESUME 21 | ~'; 22 | --Do a Full text query. 23 | elsif (:P1_FIRSTWORD is null) AND (:P1_SECONDWORD is null) then 24 | v_sql := q'~ 25 | select ROWID as "ROWID", 26 | DOC_ID as "ID", TITLE as "Title", SUBMITTED_BY as "Submitted By:", 27 | sys.dbms_lob.getlength(RESUME) as "Resume", MIMETYPE as "file Type", CREATED_DATE as "Created On", 28 | FILENAME as "File Name" 29 | from RESUME WHERE CONTAINS(resume, '~' 30 | ||:P1_DOC_QUERY|| 31 | q'~', 1) > 0 32 | ~'; 33 | else 34 | v_sql := q'~ 35 | select ROWID as "ROWID", 36 | DOC_ID as "ID", TITLE as "Title", SUBMITTED_BY as "Submitted By:", 37 | sys.dbms_lob.getlength(RESUME) as "Resume", MIMETYPE as "file Type", CREATED_DATE as "Created On", 38 | FILENAME as "File Name" 39 | from RESUME WHERE CONTAINS(resume,'near((~'||:P1_FIRSTWORD||q'~,~'||:P1_SECONDWORD||q'~),~'||:P1_PROXIMITY||q'~)',1) > 0 40 | ~'; 41 | end if; 42 | -- APEX_DEBUG.ENABLE(apex_debug.c_log_level_info); 43 | -- apex_debug.message(p_message => 'Chip enabled Debug. SQL below:'); 44 | -- apex_debug.message(p_message => v_sql); 45 | return v_sql; 46 | end; 47 | -------------------------------------------------------------------------------- /example_data.csv: -------------------------------------------------------------------------------- 1 | PGM_ACCT_PRIORITY, END_USER_ORCL_GLB_ULT_REG_ID,END_USER_ORCL_GLB_ULT_REG_ID 2 | 1,3720838,3720838 3 | 1,13706931,4386995 4 | 3,3578682,3552681 5 | 3,1260548,3601657 6 | 1,4400640,3598206 7 | 4,3687117,11724079 8 | ,12615884,12615884 9 | ,12069053,A4SWN4K 10 | ,1250087,1250087 11 | 1,4446442,1259193 12 | 3,A4NBVZK,A4NBVZK 13 | 1,3945841,3945841 14 | 4,4422781,3569777 15 | 2,3620735,3480017 16 | 3,A4RSBR6,A4RSBR6 17 | 3,4058675,4054912 18 | 1,3828100,12337565 19 | 3,30618121,3645181 20 | ,3806988,3806988 21 | ,3440198,3440198 22 | ,11660831,11660831 23 | 4,3722978,3722978 24 | 4,4406417,13457031 25 | 2,1258875,1258875 26 | 2,1257516,1257516 27 | 3,3583033,3583033 28 | 2,12000987,12000987 29 | 3,3701924,3701924 30 | 3,A4G6PRG,A4G6PRG 31 | 3,3684866,3684866 32 | 1,1258305,1258305 33 | 3,3448051,3895003 34 | 3,4188720,4188720 35 | 2,1262164,1262164 36 | 2,1248879,1248879 37 | 1,26984836,26984836 38 | ,3697224,4046819 39 | ,4292957,4476825 40 | 5,3592803,3592803 41 | 1,1256841,1256841 42 | ,A4YWV7H,A4YWV7H 43 | ,A4YWV7H,A4YWV7H 44 | 2,12546600,12546600 45 | 3,4038798,3847511 46 | 4,11720781,4477153 47 | 4,12172504,12172504 48 | 2,3491341,3491341 49 | 1,3601657,3601657 50 | 3,30600033,30600033 51 | 2,3916210,3916210 52 | 3,A3MJ6KW,12072614 53 | ,13205814,1249105 54 | 1,3426502,12659916 55 | 2,1257675,12067733 56 | 3,1259164,12377310 57 | 2,3544626,3544626 58 | 1,3682266,4181707 59 | 1,3682266,4181707 60 | 3,3687097,4136186 61 | ,3935502,3935502 62 | 1,12008332,12008332 63 | 3,1249217,1249217 64 | 1,1257339,1257339 65 | 2,12519754,3447264 66 | 2,3451622,3447264 67 | 2,1258689,1258689 68 | 1,12566425,1250178 69 | 2,4433362,4433362 70 | 4,A4SSDNB,A4SSDNB 71 | 1,3530850,1264132 72 | ,1264132,1264132 73 | ,3533173,3573292 74 | 1,3920775,3920775 75 | 2,A4MKHSJ,A4MKHSJ 76 | ,11661336,11661336 77 | 2,4385625,4385625 78 | 1,3391590,3391590 79 | 4,3884517,4163433 80 | 3,1256855,1256855 81 | ,4413121,4413121 82 | 2,3628270,3915995 83 | 3,11628260,11628260 84 | 2,30566092,30566092 85 | 3,12258046,12258046 86 | 1,1259092,1259092 87 | ,3808716,3808716 88 | 2,4007288,3624153 89 | 4,3890326,3890326 90 | ,3668698,3668698 91 | ,3707285,3707285 92 | 1,4359710,3484483 93 | 3,3787583,3606757 94 | 5,1259404,1259404 95 | 3,3600296,3600296 96 | 3,3624153,3624153 97 | 5,3882604,1258665 98 | 1,1259307,3684418 99 | 2,3699978,12070240 100 | 1,1259912,12660165 101 | 2,4155438,4155438 102 | 3,3638443,3638443 103 | 2,12071436,3993320 104 | 1,3705039,3705039 105 | 1,12286468,12286468 106 | 1,1248555,1248555 107 | 2,1259131,11628260 108 | 1,4259522,4330328 109 | 1,1260100,1260100 110 | 5,3977241,3977241 111 | 1,A4XF2JW,A4XF2JW 112 | 5,A3NTZQ6,A3NTZQ6 113 | 3,3874395,3874395 114 | 1,12172862,12172862 115 | 3,4277379,4277379 116 | 1,3721546,3721546 117 | 1,3544616,3686238 118 | ,4020986,3702316 119 | 1,3702316,3702316 120 | ,11628346,11628346 121 | ,11628346,11628346 122 | 1,3492066,3690997 123 | 1,1260240,12546600 124 | 1,A4YLYGJ,A4YLYGJ 125 | ,12907726,12907726 126 | 4,A4G4QS5,A4G4QS5 127 | 1,12194429,12194429 128 | 2,A4K5BTV,A4K5BTV 129 | 2,4451998,4451998 130 | 4,3684215,3684215 131 | 2,12376713,1249248 132 | 3,A3LZY8W,A3LZY8W 133 | 2,1257955,3988047 134 | 1,3994745,1256285 135 | 5,3808410,12070240 136 | 1,1258591,1258591 137 | 3,A4RVGG5,A4RVGG5 138 | 5,4149019,4149019 139 | 3,3708211,4442216 140 | 2,3737777,3638443 141 | ,3514741,3514741 142 | ,1258503,3901133 143 | 1,A3TTV2J,A3TTV2J 144 | 5,A4G6PGV,A4G6PGV 145 | 1,4005333,4005333 146 | 1,4544195,3444455 147 | ,3481113,3444455 148 | 1,3444455,3444455 149 | ,3360684,3559051 150 | ,A3P2HPX,3559051 151 | 2,1248844,1248844 152 | 2,1258665,1258665 153 | 3,4364853,4364853 154 | 4,3753825,3493601 155 | 1,1257719,4482745 156 | 3,4200241,4200241 157 | ,3789993,4287282 158 | 1,3415816,13741461 159 | 2,4128205,A3MKNF9 160 | 5,4268653,4268653 161 | ,3813041,1258119 162 | 3,1259862,1259862 163 | 4,3697971,3697971 164 | 1,12988130,4413910 165 | 2,4128198,4128198 166 | 4,1256512,11920659 167 | ,3614854,1259193 168 | 1,3662337,3662337 169 | 1,4017291,4017291 170 | 2,1248884,3477688 171 | 2,1258859,4098251 172 | 1,3686145,3686145 173 | 4,12487867,3977230 174 | 2,A3MVTH7,3562899 175 | 3,3405365,3405365 176 | ,3397297,3397297 177 | 3,3528253,3872293 178 | 1,11636839,11636839 179 | 1,1248082,3498656 180 | 1,13011223,3620332 181 | 3,4070145,3661263 182 | 1,1260207,3545498 183 | 1,1260207,3545498 184 | ,1260354,4052457 185 | 2,12543647,12377095 186 | 1,12070300,12070300 187 | 1,1248194,1248194 188 | ,4444545,4444545 189 | 1,A49W2JV,4287282 190 | ,A3V664M,A3V664M 191 | 1,1259353,3710923 192 | 3,12686309,12686309 193 | 3,16580533,12686309 194 | ,12378139,12378139 195 | 4,3834499,3834499 196 | 1,1260462,4120315 197 | 1,3459345,3459345 198 | 2,1260572,4390855 199 | 2,1260572,4390855 200 | ,1261028,1261028 201 | ,3422815,3422815 202 | 4,1256303,1256303 203 | 1,4052963,4052963 204 | 5,3857926,3857926 205 | 1,3831679,1260379 206 | 1,3831679,1260379 207 | 2,3638758,3638758 208 | 3,4238879,4238879 209 | 2,12008352,12546149 210 | 1,3576432,3576432 211 | 1,3889656,3889656 212 | 3,1271250,4163433 213 | 1,1259732,1259732 214 | 2,3371815,3371815 215 | 2,4054912,4054912 216 | 3,12371319,12371319 217 | 3,31661481,31661481 218 | 1,3882882,3882882 219 | 2,1249064,3882882 220 | 3,4476502,3844318 221 | ,A3MRSB6,A3MRSB6 222 | 2,1262552,4475847 223 | ,3621395,3621395 224 | 1,A4X7M3J,A4X7M3J 225 | 1,3609964,3754899 226 | ,1256603,3754899 227 | 2,1259312,1259312 228 | 1,3583575,3583575 229 | 4,3543378,3543378 230 | 3,4296910,1248928 231 | 3,A3MKNMB,A3MKNMB 232 | 3,3624524,3624524 233 | 1,1249388,1249388 234 | 1,4352904,4523273 235 | 1,4352904,4523273 236 | 1,3710679,3512008 237 | 3,12193505,12193505 238 | 3,3994479,3994479 239 | 2,A3MRDWZ,A3MRDWZ 240 | 2,3429213,3429213 241 | 2,4161805,4161805 242 | 1,1257944,1257944 243 | 1,3731688,A3TTVBT 244 | 3,3481495,1254312 245 | 3,3446716,3446716 246 | 3,3641557,A49BTD7 247 | 2,11667128,11667128 248 | 2,3994839,3994839 249 | 3,3572819,3572819 250 | 2,1259983,1259983 251 | 3,1257489,1257489 252 | 2,11636436,11636436 253 | 3,3673722,4125051 254 | 2,3558175,3558175 255 | 3,3851917,3851917 256 | 2,1261686,1260586 257 | 3,1258219,A49BTD7 258 | 3,3531161,3531161 259 | 2,1256760,4364261 260 | ,3581425,3948965 261 | ,3604446,3581642 262 | ,3440825,4154300 263 | 4,4192914,4192914 264 | 2,11972119,3934837 265 | 3,3954900,3954900 266 | 3,4250223,3868387 267 | 2,3778403,12070240 268 | ,3833424,12070240 269 | 1,A53TLD8,A53TLD8 270 | 2,3681772,3681772 271 | 1,4044506,4044506 272 | 2,4253224,3675729 273 | 3,A48DNP7,A53KQG9 274 | 2,13715723,13715723 275 | 2,3922569,3922569 276 | 5,3758781,4122530 277 | 5,3481188,4122530 278 | 4,3986936,4098600 279 | 3,3800764,11628752 280 | 2,12337870,12337870 281 | 1,4187552,3385259 282 | 2,12579326,12579326 283 | 2,3411813,3775687 284 | 2,16569411,4245951 285 | 1,1248272,1248272 286 | 1,3924166,3924166 287 | 1,3742747,3924166 288 | 3,4244764,4244764 289 | 5,4047237,4047237 290 | 3,3569354,3567015 291 | 3,3841191,3989452 292 | 1,1260961,3623185 293 | 1,3808528,13010755 294 | 3,3581329,3581329 295 | ,943190,3769140 296 | 3,3485824,3485824 297 | 2,1258702,1258702 298 | 3,3755712,4292366 299 | ,A4X7DQM,A4X7DX7 300 | 1,A4QT7P5,A4QT7P5 301 | 1,3526439,3653100 302 | ,3758965,4207631 303 | 2,A4DNCWK,A4P73QC 304 | 3,4181318,11940378 305 | 1,12555615,12555615 306 | 1,A4Y9H6R,A4Y9H6R 307 | 2,12549946,12549946 308 | 2,1259079,1259079 309 | 3,3604306,3604306 310 | 4,3505760,3606757 311 | ,12485468,3661578 312 | 5,3575869,3575869 313 | 3,3578553,3578553 314 | 1,11707695,11707695 315 | ,3848815,3848815 316 | 2,3540868,3540868 317 | 2,3365190,A4D9P8D 318 | 2,16566024,3558180 319 | ,4512795,12901123 320 | 4,12072627,3682786 321 | 1,3743058,3743058 322 | 3,1248604,3564489 323 | 5,3468086,3468086 324 | ,3610442,3610442 325 | 3,12141931,3385259 326 | ,1260397,3446276 327 | 1,1268950,12426925 328 | ,12510074,12510074 329 | 1,1258776,1258776 330 | ,3396803,3396803 331 | ,3847511,3847511 332 | 2,1248881,3765495 333 | 1,3680876,3680876 334 | 3,4094011,4094011 335 | ,3613565,3613565 336 | ,12761427,12738576 337 | 3,3416626,12738576 338 | 2,3514780,3514780 339 | 1,1261231,1261231 340 | 1,3443533,3443533 341 | 1,12528359,13496662 342 | 1,1262702,3606757 343 | 2,3997917,A48VH2S 344 | 2,3948775,11628818 345 | 4,12476723,4041322 346 | 1,3495764,3495764 347 | 4,3584688,3511426 348 | 2,4085128,4085128 349 | 2,4358473,4358473 350 | 1,1256287,4017503 351 | ,3579084,3579084 352 | 3,12071529,12071529 353 | ,3559517,3911358 354 | 2,4308329,4308329 355 | 2,3650671,3404795 356 | 2,3630382,3630382 357 | ,1258394,1258394 358 | 2,12546639,12546639 359 | 2,3757436,3757436 360 | 3,3739651,3739651 361 | 1,1248276,1259094 362 | ,3645479,3586497 363 | 5,4093661,4093661 364 | 1,A4KK3T6,3856634 365 | 2,12067995,12067995 366 | 5,3852545,3852545 367 | 3,4353729,3869176 368 | 5,3634869,3374231 369 | ,A4RX3MP,A4RX3MP 370 | 4,12002881,12002881 371 | 2,A4RXHRM,A4RXHRM 372 | 2,12484263,12484263 373 | 1,4413444,4413444 374 | 4,3541582,3512997 375 | ,3411981,3411981 376 | 3,3562368,3562368 377 | 2,4511035,3666657 378 | 3,4294503,1258515 379 | 2,3580922,3580922 380 | 2,3879995,11662084 381 | 2,3591539,4154300 382 | 3,12579713,12579713 383 | 2,3471580,3395243 384 | 2,3471580,3395243 385 | 2,1259063,4392421 386 | 3,1259288,1259288 387 | 1,3557861,3557861 388 | ,13245502,1256874 389 | 5,4022771,4022771 390 | 4,3554685,3554685 391 | 4,1256638,1256638 392 | 1,1259391,1259391 393 | 3,3704579,3704579 394 | ,3741363,12371283 395 | 1,12371283,12371283 396 | ,1258585,1257228 397 | 1,4137647,1259261 398 | 3,A4W34XG,A4W34XG 399 | 3,1248885,1248885 400 | 4,4045761,4511969 401 | 1,1259285,1259285 402 | 3,3607062,3607062 403 | 1,A4YXLGS,A4YXLGS 404 | 2,1260300,3676669 405 | 1,1259328,1259328 406 | 5,A4XG4JV,A4XG4JV 407 | 5,A4XG4JV,A4XG4JV 408 | ,A4V27RR,A4V27RR 409 | 1,4418566,4418566 410 | 2,4481620,A3XHNKT 411 | 2,12369120,12369120 412 | 5,A4WVFS5,4351902 413 | 2,4276639,4276639 414 | ,4464404,4464404 415 | 1,1249036,1249036 416 | 1,4230159,3373211 417 | 1,4022842,4022842 418 | 2,A4M9B8Y,A4M9B8Y 419 | ,4043420,12660013 420 | 2,3697865,3398974 421 | ,1257589,A4DVYGZ 422 | 1,1248240,12546600 423 | 4,1258551,1256260 424 | 2,1248962,1248962 425 | 2,1248239,1248239 426 | 5,11781701,11781701 427 | 2,4510127,12070240 428 | 2,A4Z99P6,A4Z99PC 429 | 5,12729947,1249350 430 | 2,1259138,1259138 431 | 2,12977779,12977779 432 | 2,3620487,3417974 433 | 3,4093354,4093354 434 | 1,1262393,1259599 435 | ,3817999,A49GSZ3 436 | 2,A55NV5T,A55NV5T 437 | 3,3657422,3657422 438 | 2,1259446,1259446 439 | 4,3635879,3635879 440 | 2,3402635,3402635 441 | 4,11730695,11730695 442 | 3,3865194,3446222 443 | 1,4535261,4535261 444 | 1,3960587,3960587 445 | ,1259088,3960587 446 | 3,3788196,3788196 447 | 2,12337713,4322560 448 | 2,12337713,4322560 449 | 3,4432495,4432495 450 | 3,4433101,4433101 451 | 1,4210955,3508219 452 | 4,A3NTZKN,A3NTZKN 453 | 1,1248603,1248603 454 | 4,3909708,3909708 455 | 5,13218876,13218876 456 | 3,3504351,A4JVHXZ 457 | 2,4059373,4059373 458 | 2,3377090,3714545 459 | 2,3530178,1257606 460 | 2,12579746,A3Z2RJG 461 | 2,4197657,4197657 462 | ,3823414,A3MQV7B 463 | ,12999262,4123303 464 | 3,3953435,4373476 465 | 3,3600145,3600145 466 | 3,3390286,4157417 467 | 2,4166424,4515297 468 | 2,A4S2DR8,A4S2DR8 469 | 1,3553608,12529080 470 | ,12071945,1258714 471 | 3,1259091,1259091 472 | 2,11642573,11642573 473 | 3,1258833,1258833 474 | 3,1257423,1257423 475 | 3,1257390,1257390 476 | 2,3363582,4125051 477 | 1,1248630,1248630 478 | 1,1248315,1248315 479 | 1,1258813,3427601 480 | ,4253807,4253807 481 | 2,3546825,3917222 482 | 4,A3MKN9Q,A3MKN9Q 483 | 3,3684501,3684501 484 | 2,3815054,4243092 485 | 3,3824808,4409535 486 | 3,12362709,4326956 487 | 3,1256306,1256306 488 | 1,1263990,1263990 489 | 1,4243093,4243093 490 | 2,13481193,1257961 491 | 4,3639214,4054912 492 | 1,4186756,3490819 493 | ,1259582,28355199 494 | 3,3529499,4157417 495 | 3,3486555,3951458 496 | 1,1257837,4447268 497 | 4,4409204,3847511 498 | ,A3TTTS9,A3TTTS9 499 | 3,3616647,4453616 500 | ,3976154,3976154 501 | 2,A3M9LL5,11699245 502 | 5,3491008,3951583 503 | ,1257872,1257872 504 | 3,3620924,3620924 505 | 2,1249105,1249105 506 | 1,11920153,11920153 507 | 2,3684931,4132074 508 | 3,3421480,3421480 509 | 1,1259763,1259763 510 | 1,4523273,4523273 511 | 2,1258860,1258860 512 | ,3923020,4280642 513 | 3,4180965,4180965 514 | 2,3642737,4076482 515 | 1,4211297,3674414 516 | 2,3654923,3654923 517 | 1,4054554,3903738 518 | 1,1248737,1248737 519 | 1,1257842,1257842 520 | 1,1261218,1258541 521 | 1,1259917,1259917 522 | 1,1259917,1259917 523 | ,3701126,3701126 524 | ,3449061,3449061 525 | 2,12532020,12532020 526 | 1,4170451,4357606 527 | 4,3965059,4125051 528 | 1,1256946,1248198 529 | 1,1261467,1248198 530 | 1,3365700,3365700 531 | 1,1256948,4456731 532 | 1,1256948,4456731 533 | ,4261271,4261271 534 | ,11632368,4170879 535 | 1,4289591,4289591 536 | 2,3470266,3470266 537 | 1,A4YNSPG,A4YNSPG 538 | 3,1258327,1258327 539 | 5,A4F8YX2,A4F8YX2 540 | 3,3447349,3447349 541 | 1,16585454,1256285 542 | 5,1257168,12085557 543 | 1,3688894,3688894 544 | 1,12047523,12047523 545 | 5,3921097,3921097 546 | 3,3708638,3708638 547 | ,3571990,3571990 548 | 3,3920783,3920783 549 | 2,3790087,3790087 550 | 1,12085557,12085557 551 | 1,1259216,1259216 552 | 4,11920735,11920735 553 | 4,3407645,3407645 554 | 3,4186314,4186314 555 | 2,A4PJN2B,A4PJN2B 556 | 3,12153717,12153717 557 | 2,4234710,4163433 558 | 2,1269819,3773389 559 | 1,1257598,1258812 560 | 3,3710791,1249015 561 | ,4508137,12370911 562 | 4,1254839,3606757 563 | 2,3775687,3775687 564 | 1,3889048,3889048 565 | ,A3Y4L8Z,4159880 566 | 1,3650249,3650249 567 | 3,A4HVGY4,A4HVGY4 568 | 1,A4QPPSQ,A4QPPSQ 569 | 3,3438150,3454682 570 | ,3651064,3524611 571 | 1,3493416,3620607 572 | 1,4130799,4042583 573 | 3,11660859,A4C52S3 574 | 1,12431548,1259193 575 | 3,3949372,3949372 576 | 1,1257566,1257566 577 | 1,4389162,3910532 578 | 2,3749852,3749852 579 | 4,3574242,3574242 580 | 1,1259413,4230435 581 | 4,12071885,4283820 582 | 1,3893515,3927375 583 | 1,12059487,12059487 584 | 3,4213207,4213207 585 | 2,3471070,4157417 586 | 1,1258128,1258128 587 | 4,3572843,4478539 588 | ,3773448,3773448 589 | 3,3544163,3538179 590 | 3,1259101,1259101 591 | 3,3748422,3748422 592 | 2,3517842,4457101 593 | 1,3780204,3882070 594 | 1,3487465,3487465 595 | 3,3419781,3819292 596 | 3,1269662,1269662 597 | ,4213288,1258041 598 | 1,1261203,1261203 599 | -------------------------------------------------------------------------------- /indexedDocsCheck.md: -------------------------------------------------------------------------------- 1 | ## This file contains some sample code on how to quickly tell how many documents have been indexed by Oracle Text, if any are still in the pending state. 2 | 3 | - First we will query to see the tables with existing Oracle Text indexes. Notice the column IDX_DOCID_COUNT represents the number of documents currently indexed. See Oracle Text views for full spec. [https://docs.oracle.com/en/database/oracle/oracle-database/21/ccref/oracle-text-views.html](https://docs.oracle.com/en/database/oracle/oracle-database/21/ccref/oracle-text-views.html) 4 | ![](assets/indexedDocsCheck-0673052d.png) 5 | 6 | ``` 7 | select * from CTX_USER_INDEXES where idx_name = 'SEARCHMYDOCS'; 8 | ``` 9 | 10 | - Next we will query out table to find out the number of documents. 11 | ![](assets/indexedDocsCheck-1efbcd19.png) 12 | ``` 13 | select count(*) from resume; 14 | ``` 15 | 16 | - To index the documents we need to run the following command. 17 | ``` 18 | alter index SEARCHMYDOCS rebuild online noparallel; 19 | ``` 20 | or 21 | ``` 22 | CTX_DDL.SYNC_INDEX('searchMyDocs', '5M'); 23 | ``` 24 | 25 | - Requery the CTX_USER_INDEXES view to see the number of indexed docs. 26 | ![](assets/indexedDocsCheck-7fabc7a3.png) 27 | ``` 28 | select * from CTX_USER_INDEXES where idx_name = 'SEARCHMYDOCS'; 29 | ``` 30 | 31 | - To figure out the number of documents that need to be indexed issue the following query. 32 | ``` 33 | select (select count(*) from resume where resume is not null) - IDX_DOCID_COUNT "Documents to be Indexed" from CTX_USER_INDEXES where idx_name = 'SEARCHMYDOCS'; 34 | ``` 35 | 36 | - To see number of deletes from index 37 | ``` 38 | select count(*) from DR$SEARCHMYDOCS$N 39 | ``` 40 | -------------------------------------------------------------------------------- /introGenAI.md: -------------------------------------------------------------------------------- 1 | ## Enhancing Oracle APEX Applications with Dynamic Action Gen AI Calls 2 | This demo is a intro to embedding the OCI GenAI service into Oracle APEX for developers. The video begins with a simple form that on LOV change dynamically showcases a new image based on the LOV selection. We will enhance this application with GenAI so that information about the players career batting average is returned along with the image. The demo will showcase how to gather the required OCIDs to create a APEX web credintial to connect to the GenAI service. Once collected we will add a step to the existing dynamic action that calls a pl/sql code block. Inside the code block we will form a REST POST payload passing in the player selected information along with the model we wish to call and parameters to limit the size of the response. The code block includes specific debug commands that will highlight the post payload, the REST response payload and the dynamic formation of a query leveraging the pl/sql JSON_TABLE functionality to easily query the response payload and extract just the required GenAI text. We will then iterate through the result and update the APEX page item with the text. The example video will also showcase how easy it is to swap models and quickly adjust your json_table query to receive the desired text given varations in the REST response payload format. 3 | 4 | I encourage you to watch the following video(s) and reference this blog before attempting to follow the technical hands on path below. 5 | [Enhancing Oracle APEX Applications with Dynamic Action Gen AI Calls](https://youtu.be/tltLxGa5AtU) 6 | 7 | [How to Dynamically Show a Image on Select List Change without Page Submit in Oracle APEX](https://www.youtube.com/watch?v=MpxrqEbpgc8&list=PLsnBif_-5JnA8Hzvp8e1bQ3fo6VEvYEB0&index=16&pp=gAQBiAQB) 8 | 9 | [APEX Meets Gen AI Blog](https://blogs.oracle.com/apex/post/building-innovative-qa-experiences-oracle-apex-meets-oci-generative-ai) 10 | 11 | At the time of this recording the genAI service was only available in the chicago region. The solution shown leveraged ATP free tier in Ashburn along with genAI in chicago in another tennancy. There are other potential ways this could be accomplished, Select AI for example. We chose to leverage the genAI service through a Web Credential and enhance a APEX application as it feels like most organizations in time will want to choose and fine tune the LLM model that best fits there needs in time. Not everything will be documented in this particular markdown page, given the length of the video. However I will include enough sample code to enable you to follow along if you have an existing APEX workspace, application and developer priviledges. You will also need access to the OCI Gen AI service. 12 | 13 | -- The table leveraged to generate the select list in this example is, you can enter any baseball player name and image url to test: 14 | ``` 15 | CREATE TABLE "PLAYERS" 16 | ( "ID" NUMBER, 17 | "PLAYERNAME" VARCHAR2(200), 18 | "CARD_URL" VARCHAR2(600), 19 | CONSTRAINT "PLAYERS_PK" PRIMARY KEY ("ID") 20 | USING INDEX ENABLE 21 | ) ; 22 | 23 | CREATE OR REPLACE EDITIONABLE TRIGGER "BI_PLAYERS" 24 | before insert on "PLAYERS" 25 | for each row 26 | begin 27 | if :NEW."ID" is null then 28 | select "PLAYERS_SEQ".nextval into :NEW."ID" from sys.dual; 29 | end if; 30 | end; 31 | 32 | / 33 | ALTER TRIGGER "BI_PLAYERS" ENABLE; 34 | ``` 35 | 36 | -- The query for the select list page item is: 37 | ``` 38 | select id || ' '|| playername, card_url from players 39 | ``` 40 | 41 | -- The static content base64 content for the blank image of 1 pixels is: 42 | ``` 43 | data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg== 44 | ``` 45 | 46 | -- The dynamic action javascript is below, you will need to change your variable names: 47 | ``` 48 | let holder = apex.item("P8_PLAYER").getValue(); 49 | console.log("Holder is "+holder); 50 | $("#P8_CARD").attr("src", holder); 51 | ``` 52 | 53 | -- Gather core tennancy information for creation of a web credential. 54 | ``` 55 | Compartment ID: 56 | OCI User ID: 57 | OCI Tennancy ID: 58 | OCI Public Key Fingerprint: 59 | OCI Private Key: 60 | ``` 61 | 62 | --Create a new Web Credential and record the web credintial static id. 63 | ![](assets/2024-03-01-09-46-14.png) 64 | 65 | ``` 66 | Web Credential Static ID: 67 | ``` 68 | 69 | -- Add a new Display Only Item to your page. Provide the Label "AI Generated About Player" 70 | ![](assets/2024-03-01-09-44-12.png) 71 | 72 | -- Add a second action under the action that sets the image to the player selected in the select list. 73 | ![](assets/2024-03-01-09-48-32.png) 74 | 75 | ![](assets/2024-03-01-09-48-11.png) 76 | 77 | 78 | -- Insert the Code Below into the action. You will need to swap in your web credential, compartment id and update your variable names. Once you understand the code block below and it works for you it may be good comment out the apex.debug lines. 79 | ``` 80 | DECLARE 81 | v_genai_endpoint VARCHAR2(4000) := 'https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/generateText'; 82 | v_webcred CONSTANT VARCHAR2(50) := ''; 83 | v_input varchar2(4000); 84 | v_genai_response CLOB; 85 | v_text varchar2(4000); 86 | v_genAI_post_payload varchar2(3000); 87 | 88 | CURSOR genai_response IS SELECT jt.* FROM JSON_TABLE(v_genai_response, '$' COLUMNS (text VARCHAR2(4000) PATH '$.inferenceResponse[0].generatedTexts[0].text' )) jt; 89 | 90 | BEGIN 91 | select 'What is '||playername||'s career batting average?' into v_input from players where card_url = :P1_PLAYER; 92 | 93 | v_genAI_post_payload := '{ 94 | "inferenceRequest": { 95 | "runtimeType": "COHERE", 96 | "prompt": "'||v_input||'", 97 | "maxTokens": 200, 98 | "temperature": 0.3, 99 | "numGenerations": 1, 100 | "returnLikelihoods": "GENERATION", 101 | "isStream": false 102 | }, 103 | "servingMode": { 104 | "servingType": "ON_DEMAND", 105 | "modelId": "cohere.command-light" 106 | }, 107 | "compartmentId": "" 108 | }'; 109 | 110 | -- Comment out debug later. For learning lets take a look at what is happening. 111 | apex_debug.message(p_message => 'Example GenAI call. Lets Check our input variables:',p_force => TRUE); 112 | apex_debug.message(p_message => 'REST Post Payload set in variable v_genAI_post_payload: '||CHR(13) || v_genAI_post_payload, p_force => TRUE); 113 | 114 | if v_input is not null then 115 | --set headers to return payload as json 116 | apex_web_service.g_request_headers.DELETE; 117 | apex_web_service.g_request_headers(1).name := 'Content-Type'; 118 | apex_web_service.g_request_headers(1).value := 'application/json'; 119 | 120 | v_genai_response := apex_web_service.make_rest_request 121 | (p_url => v_genai_endpoint, 122 | p_http_method => 'POST', 123 | p_body => v_genAI_post_payload, 124 | p_credential_static_id => v_webcred); 125 | 126 | --View full response payload 127 | apex_debug.message(p_message => 'REST Response Payload set in variable v_genai_response: ' ||CHR(13)|| v_genai_response, p_force => TRUE); 128 | 129 | --Output and Test your cursor query. Please note to run the query addition '' are required around the response payload. 130 | apex_debug.message(p_message => 'SQL Query generated for :'||CHR(13)||'SELECT jt.* FROM JSON_TABLE('''||v_genai_response||''', ''$'' COLUMNS(text VARCHAR2(4000) PATH ''$.inferenceResponse[0].generatedTexts[0].text'' )) jt', p_force => TRUE); 131 | 132 | for line in genai_response Loop 133 | v_text := v_text || line.text; 134 | end loop; 135 | :P1_PLAYERSTATS := v_text; 136 | 137 | end if; 138 | 139 | EXCEPTION 140 | WHEN OTHERS THEN 141 | apex_debug.message(p_message => 'Error caught in exception block of process calling genAI', p_force => TRUE); 142 | 143 | END; 144 | ``` 145 | 146 | - View the debug and analyze json_table query. In SQL Workshop. 147 | ``` 148 | SELECT jt.* 149 | FROM JSON_TABLE('{"modelId":"cohere.command-light","modelVersion":"15.6","inferenceResponse":{"runtimeType":"COHERE","generatedTexts":[{"id":"059468e0-02f7-49f9-a86c-c3c4c13291f5","text":" Henderson''s career batting average was .294. \n\nWould you like me to provide more details about Ricky Henderson''s career statistics or explain why his batting average was relatively low or high? ","likelihood":-0.3422786295413971,"tokenLikelihoods":[{"token":" Henderson","likelihood":-0.8517012},{"token":"''s","likelihood":-0.17626235},{"token":" career","likelihood":-0.51479936},{"token":" batting","likelihood":-0.0072648134},{"token":" average","likelihood":-0.0020083846},{"token":" was","likelihood":-0.036331233},{"token":" .","likelihood":-0.00265637},{"token":"294","likelihood":-1.5848691},{"token":".","likelihood":-0.2716945},{"token":" \n","likelihood":-1.6289217},{"token":"\n","likelihood":-0.0029089635},{"token":"Would","likelihood":-0.56252754},{"token":" you","likelihood":-1.0796247E-4},{"token":" like","likelihood":-0.0074417647},{"token":" me","likelihood":-0.6445085},{"token":" to","likelihood":-0.0044347243},{"token":" provide","likelihood":-0.042083845},{"token":" more","likelihood":-0.020632144},{"token":" details","likelihood":-0.6007463},{"token":" about","likelihood":-0.31430078},{"token":" Ricky","likelihood":-0.03574606},{"token":" Henderson","likelihood":-0.0022912815},{"token":"''s","likelihood":-0.030059556},{"token":" career","likelihood":-0.22591756},{"token":" statistics","likelihood":-1.1783049},{"token":" or","likelihood":-0.051513657},{"token":" explain","likelihood":-1.4136363},{"token":" why","likelihood":-0.29935718},{"token":" his","likelihood":-0.26685745},{"token":" batting","likelihood":-0.003990047},{"token":" average","likelihood":-0.002725757},{"token":" was","likelihood":-0.6094633},{"token":" relatively","likelihood":-1.1301836},{"token":" low","likelihood":-0.31454527},{"token":" or","likelihood":-0.042613275},{"token":" high","likelihood":-0.0015791744},{"token":"?","likelihood":-0.1208109},{"token":" ","likelihood":-7.9217425E-4}]}],"timeCreated":"2024-03-15T13:39:54.203Z"}}', 150 | '$' COLUMNS(text VARCHAR2(4000) PATH '$.inferenceResponse[0].generatedTexts[0].text' )) jt 151 | ``` 152 | 153 | - Show how to extract other values from the JSON. Grab Model ID 154 | ``` 155 | model_id VARCHAR2(4000) PATH '$.inferenceResponse[0].generatedTexts[0].id' 156 | ``` 157 | 158 | - Now we will update the model to use the llama model. Llama API link is below for your reference. 159 | [https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-inference/20231130/datatypes/LlamaLlmInferenceRequest](https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-inference/20231130/datatypes/LlamaLlmInferenceRequest) 160 | 161 | - Alter the v_genAI_post_payload variable in the script above to include the following post parameters to call the llama model. 162 | ``` 163 | v_genAI_post_payload := '{ 164 | "inferenceRequest": { 165 | "runtimeType": "LLAMA", 166 | "prompt": "'||v_input||'", 167 | "maxTokens": 200, 168 | "numGenerations": 1, 169 | "isEcho": false, 170 | "isStream": false 171 | }, 172 | "servingMode": { 173 | "servingType": "ON_DEMAND", 174 | "modelId": "meta.llama-2-70b-chat" 175 | }, 176 | "compartmentId": "" 177 | }'; 178 | ``` 179 | 180 | - Alter the json query path to read the llama output. 181 | ``` 182 | PATH '$.inferenceResponse[0].choices[0].text' 183 | ``` 184 | 185 | - Below are links to other videos that could be of help as you work with longer text blocks and genAI. 186 | 187 | [Oracle APEX: Develop Expandable Text Blocks on Page Items](https://www.youtube.com/watch?v=VXih0-R3m8I&list=PLsnBif_-5JnA8Hzvp8e1bQ3fo6VEvYEB0&index=3&t=10s&pp=gAQBiAQB) 188 | 189 | [How to Print a CLOB inside a Modal Dialog Window in Oracle APEX](https://www.youtube.com/watch?v=pSw_jFyt5zw&list=PLsnBif_-5JnA8Hzvp8e1bQ3fo6VEvYEB0&index=32&pp=gAQBiAQB) -------------------------------------------------------------------------------- /javscriptSessionState.md: -------------------------------------------------------------------------------- 1 | # How to Set Session State in APEX via Javascript API 2 | 3 | - This Code references this video [https://youtu.be/Lq7pvL8ff4g](https://youtu.be/Lq7pvL8ff4g) please watch for more details. 4 | 5 | - Sample Javscript for performing processing inside a dynamic action, then submitting the page and altering page items on submit. 6 | ``` 7 | let queryTerm =$v("P1_DOC_QUERY"); 8 | let queryType; 9 | 10 | if (queryTerm.charAt(0) == '$') { 11 | queryType="Stem Search on "; 12 | } 13 | else if (queryTerm.charAt(0) == '!') { 14 | queryType="Soundex Search on "; 15 | } 16 | else if (queryTerm.charAt(0) == '?') { 17 | queryType="Fuzzy Search on "; 18 | } 19 | else { 20 | queryType="Full Text Search on "; 21 | } 22 | 23 | apex.submit({ 24 | set:{"P1_FIRSTWORD":null, 25 | "P1_SECONDWORD":null, 26 | "P1_PROXIMITY": null, 27 | "P1_DOC_QUERY":queryTerm, 28 | "P1_SEARCH_TYPE":queryType}, 29 | showWait: true, 30 | validate: true} 31 | ); 32 | ``` 33 | -------------------------------------------------------------------------------- /json/mlb_player1.json: -------------------------------------------------------------------------------- 1 | { 2 | "player_info": { 3 | "copyRight": " NOTICE: This file is no longer actively supported. Please use the MLB Stats API (http://statsapi.mlb.com/docs/) as an alternative. Copyright 2023 MLB Advanced Media, L.P. Use of any content on this page acknowledges agreement to the terms posted here http://gdx.mlb.com/components/copyright.txt ", 4 | "queryResults": { 5 | "totalSize": "1", 6 | "created": "2023-03-07T05:30:26", 7 | "row": { 8 | "team_code": "nyn", 9 | "high_school": "", 10 | "height_feet": "5", 11 | "player_id": "493316", 12 | "jersey_number": "52", 13 | "team_abbrev": "NYM", 14 | "active_sw": "N", 15 | "name_first": "Yoenis", 16 | "height_inches": "11", 17 | "primary_stat_type": "hitting", 18 | "name_display_first_last_html": "Yoenis Cespedes", 19 | "college": "", 20 | "death_date": "", 21 | "status_date": "2020-10-28T00:00:00", 22 | "name_middle": "", 23 | "birth_date": "1985-10-18T00:00:00", 24 | "name_last": "Cespedes", 25 | "name_prefix": "", 26 | "death_city": "", 27 | "name_nick": "La Potencia", 28 | "name_title": "", 29 | "name_display_roster_html": "Cespedes", 30 | "primary_sport_code": "", 31 | "status_code": "FA", 32 | "name_display_roster": "Cespedes", 33 | "primary_position_txt": "LF", 34 | "death_state": "", 35 | "gender": "M", 36 | "team_name": "New York Mets", 37 | "birth_state": "", 38 | "name_full": "Cespedes, Yoenis", 39 | "name_display_first_last": "Yoenis Cespedes", 40 | "name_display_last_first_html": "Cespedes, Yoenis", 41 | "age": "37", 42 | "file_code": "nym", 43 | "death_country": "", 44 | "team_id": "121", 45 | "weight": "225", 46 | "birth_country": "Cuba", 47 | "name_matrilineal": "Milanes", 48 | "bats": "R", 49 | "birth_city": "Granma", 50 | "primary_position": "7", 51 | "throws": "R", 52 | "start_date": "2016-11-30T00:00:00", 53 | "twitter_id": "@ynscspds", 54 | "end_date": "2020-10-29T00:00:00", 55 | "status": "Free agent", 56 | "name_use": "Yoenis", 57 | "name_display_last_first": "Cespedes, Yoenis", 58 | "pro_debut_date": "2012-03-28T00:00:00" 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /json/mlb_player2.json: -------------------------------------------------------------------------------- 1 | { 2 | "player_info": { 3 | "copyRight": " NOTICE: This file is no longer actively supported. Please use the MLB Stats API (http://statsapi.mlb.com/docs/) as an alternative. Copyright 2023 MLB Advanced Media, L.P. Use of any content on this page acknowledges agreement to the terms posted here http://gdx.mlb.com/components/copyright.txt ", 4 | "queryResults": { 5 | "totalSize": "1", 6 | "created": "2023-03-07T15:46:44", 7 | "row": { 8 | "team_code": "", 9 | "high_school": "", 10 | "height_feet": "6", 11 | "player_id": "493310", 12 | "jersey_number": "", 13 | "team_abbrev": "", 14 | "active_sw": "N", 15 | "name_first": "Alberto", 16 | "height_inches": "0", 17 | "primary_stat_type": "pitching", 18 | "name_display_first_last_html": "Alberto Bisset", 19 | "college": "", 20 | "death_date": "", 21 | "status_date": "", 22 | "name_middle": "", 23 | "birth_date": "1983-09-09T00:00:00", 24 | "name_last": "Bisset", 25 | "name_prefix": "", 26 | "death_city": "", 27 | "name_nick": "", 28 | "name_title": "", 29 | "name_display_roster_html": "Bisset", 30 | "primary_sport_code": "", 31 | "status_code": "", 32 | "name_display_roster": "Bisset", 33 | "primary_position_txt": "P", 34 | "death_state": "", 35 | "gender": "M", 36 | "team_name": "", 37 | "birth_state": "", 38 | "name_full": "Bisset, Alberto", 39 | "name_display_first_last": "Alberto Bisset", 40 | "name_display_last_first_html": "Bisset, Alberto", 41 | "age": "39", 42 | "file_code": "", 43 | "death_country": "", 44 | "team_id": "", 45 | "weight": "205", 46 | "birth_country": "Cuba", 47 | "name_matrilineal": "", 48 | "bats": "R", 49 | "birth_city": "", 50 | "primary_position": "1", 51 | "throws": "R", 52 | "start_date": "", 53 | "twitter_id": "", 54 | "end_date": "", 55 | "status": "", 56 | "name_use": "Alberto", 57 | "name_display_last_first": "Bisset, Alberto", 58 | "pro_debut_date": "" 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /json/mlb_player3.json: -------------------------------------------------------------------------------- 1 | { 2 | "player_info": { 3 | "copyRight": " NOTICE: This file is no longer actively supported. Please use the MLB Stats API (http://statsapi.mlb.com/docs/) as an alternative. Copyright 2023 MLB Advanced Media, L.P. Use of any content on this page acknowledges agreement to the terms posted here http://gdx.mlb.com/components/copyright.txt ", 4 | "queryResults": { 5 | "totalSize": "1", 6 | "created": "2023-03-15T13:57:55", 7 | "row": { 8 | "team_code": "", 9 | "high_school": "", 10 | "height_feet": "6", 11 | "player_id": "493324", 12 | "jersey_number": "", 13 | "team_abbrev": "", 14 | "active_sw": "N", 15 | "name_first": "Valeri", 16 | "height_inches": "3", 17 | "primary_stat_type": "pitching", 18 | "name_display_first_last_html": "Valeri Garcia", 19 | "college": "", 20 | "death_date": "", 21 | "status_date": "", 22 | "name_middle": "", 23 | "birth_date": "1982-07-04T00:00:00", 24 | "name_last": "Garcia", 25 | "name_prefix": "", 26 | "death_city": "", 27 | "name_nick": "", 28 | "name_title": "", 29 | "name_display_roster_html": "Garcia", 30 | "primary_sport_code": "", 31 | "status_code": "", 32 | "name_display_roster": "Garcia", 33 | "primary_position_txt": "P", 34 | "death_state": "", 35 | "gender": "M", 36 | "team_name": "", 37 | "birth_state": "", 38 | "name_full": "Garcia, Valeri", 39 | "name_display_first_last": "Valeri Garcia", 40 | "name_display_last_first_html": "Garcia, Valeri", 41 | "age": "40", 42 | "file_code": "", 43 | "death_country": "", 44 | "team_id": "", 45 | "weight": "225", 46 | "birth_country": "Cuba", 47 | "name_matrilineal": "", 48 | "bats": "R", 49 | "birth_city": "", 50 | "primary_position": "1", 51 | "throws": "R", 52 | "start_date": "", 53 | "twitter_id": "", 54 | "end_date": "", 55 | "status": "", 56 | "name_use": "Valeri", 57 | "name_display_last_first": "Garcia, Valeri", 58 | "pro_debut_date": "" 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /json_db.md: -------------------------------------------------------------------------------- 1 | ## Intro to SODA Collections (JSON) in SQL Worksheet 2 | 3 | In this short tutorial we will showcase how Oracle APEX (free tier) can quickly consume and leverage json documents in a matter of minutes. This 101 tutorial will begin with the creation of a SODA collection in SQL Workshop including a Data Load. We will then show how to easily: 4 | 5 | - Append more documents to the collection in SQL workshop and Database Actions 6 | - Query the raw json 7 | - Update Nested JSON elements through JSON_TRANSFORM and JSON_MERGEPATCH 8 | - Understand and query the default soda collection view in SQL. 9 | - Query the collection using javascript syntax in SQL Workshop. 10 | - Create a custom view in SQL Worksheet. 11 | 12 | We reccomend you watch this video before proceeding through the steps below. [Intro to SODA Collections (JSON) in SQL Worksheet on Oracle APEX](https://youtu.be/kGTdOywjnuo) 13 | 14 | - To perform these steps the APEX schema user needs to be granted SODA collection from admin. Execute the query below as your user once logged into SQL*Worksheet. If the priviledge does not exist then you will need to have your Autonomous Admin user grant it to you. 15 | ``` 16 | SELECT * FROM USER_ROLE_PRIVS; 17 | 18 | grant SODA_APP to SEARCHDEMO; 19 | ``` 20 | 21 | 22 | - Get Example to get json player data, download files (mlb_player1.json, mlb_player2.json, mlb_player3.json) from the repo. 23 | [https://github.com/chipbaber/apex_textdemo/tree/main/json](https://github.com/chipbaber/apex_textdemo/tree/main/json) 24 | 25 | 26 | 27 | - See the video above to learn how to create a SODA collection in SQL Worksheet. Once created query the base table. 28 | ``` 29 | select * from MLB_PLAYERS 30 | ``` 31 | 32 | - Query the default SODA Collection View in APEX, copy an id for a document record 33 | ``` 34 | select * from MLB_PLAYERS_VIEW 35 | ``` 36 | 37 | - Query through common javascript syntax in SQL. Please note if you are leveraging Oracle 23ai+ for this demo you will need to swap the column name "json_document" for "data" as the default column name updated. 38 | ``` 39 | Ex. versions < 23ai 40 | SELECT p.json_document.player_info.queryResults."row".name_display_first_last "Player Name", 41 | p.json_document.player_info.queryResults."row".jersey_number "Jersey", 42 | p.json_document.player_info.queryResults."row".name_nick "Nick Name" 43 | FROM MLB_PLAYERS p; 44 | 45 | Ex. versions > 23ai 46 | SELECT p.data.player_info.queryResults."row".name_display_first_last "Player Name", 47 | p.data.player_info.queryResults."row".jersey_number "Jersey", 48 | p.data.player_info.queryResults."row".name_nick "Nick Name" 49 | FROM MLB_PLAYERS p; 50 | 51 | SELECT p.json_document.player_info.queryResults."row".name_display_first_last "Player Name", 52 | p.json_document.player_info.queryResults."row".jersey_number "Jersey", 53 | p.json_document.player_info.queryResults."row".name_nick "Nick Name" 54 | FROM MLB_PLAYERS p where p.id = ''; 55 | 56 | SELECT p.json_document.player_info.queryResults."row".name_display_first_last "Player Name", 57 | p.json_document.player_info.queryResults."row".jersey_number "Jersey", 58 | p.json_document.player_info.queryResults."row".name_nick "Nick Name" 59 | FROM MLB_PLAYERS p where p.json_document.player_info.queryResults."row".jersey_number like '"97"'; 60 | ``` 61 | 62 | - Handling keyword row in json collection in SQL Worksheet 63 | ``` 64 | SELECT ltrim(rtrim(p.json_document.player_info.queryResults."row".twitter_id,'"'),'"') "Twitter Handle" FROM MLB_PLAYERS p; 65 | ``` 66 | 67 | - Example SQL Query to get the raw JSON, notes the copyright text for the next segment. 68 | ``` 69 | SELECT json_serialize(json_document) "RAW_JSON" FROM MLB_PLAYERS; 70 | ``` 71 | 72 | - Query and remove a segment of JSON from Result. In this example we will leverage the json_transform function remove the copyRight data from all, insert a element of homeruns as a JSON number. Please note the text RETURNING CLOB PRETTY makes this a little eaiser to see on video but is not required. 73 | 74 | ``` 75 | SELECT json_transform(JSON_DOCUMENT, REMOVE '$.player_info.copyRight' RETURNING CLOB PRETTY) FROM MLB_PLAYERS; 76 | 77 | SELECT json_transform(JSON_DOCUMENT, INSERT '$.player_info.queryResults.row.homeruns' = '20' format JSON RETURNING CLOB PRETTY) "JSON" FROM MLB_PLAYERS p where p.id = ''; 78 | 79 | SELECT json_transform(JSON_DOCUMENT, 80 | SET '$.player_info.queryResults.row.age' = 39, SET '$.player_info.queryResults.row.jersey_number' = '"39"' format JSON RETURNING CLOB PRETTY) "JSON" FROM MLB_PLAYERS p where p.id = ''; 81 | 82 | SELECT p.json_document.player_info.queryResults."row".name_display_first_last "Player Name", 83 | p.json_document.player_info.queryResults."row".age "Age", 84 | p.json_document.player_info.queryResults."row".jersey_number "Jersey Number" 85 | FROM MLB_PLAYERS p where p.id = ''; 86 | 87 | update MLB_PLAYERS p 88 | set p.JSON_DOCUMENT = JSON_Transform(JSON_DOCUMENT, 89 | SET '$.player_info.queryResults.row.age' = 39, 90 | SET '$.player_info.queryResults.row.jersey_number' = '39' 91 | ) where p.id = ''; 92 | ``` 93 | 94 | - When it comes time to update both json_transform and JSON merge can be leveraged to select or update. The example below updates a single record's copyRight text 95 | 96 | ``` 97 | select json_mergepatch(p.json_document.player_info, '{"copyRight": "Much Shorter copyright"}' RETURNING CLOB PRETTY) "JSON" from MLB_PLAYERS p where p.id = '' 98 | 99 | SELECT json_serialize(json_document) "RAW_JSON" FROM MLB_PLAYERS p where p.id = ''; 100 | 101 | UPDATE MLB_PLAYERS p SET json_document = json_mergepatch(p.json_document.player_info, '{"copyRight": "Much Shorter copyright"}') where p.id = ''; 102 | 103 | SELECT json_serialize(json_document) "RAW_JSON" FROM MLB_PLAYERS p where p.id = ''; 104 | ``` 105 | 106 | 107 | - Build out query view 108 | 109 | ``` 110 | SELECT 111 | "RT"."ID", JT."AGE",JT."BATS", JT."STATUS",JT."THROWS",JT."WEIGHT", 112 | JT."COLLEGE",JT."FULLNAME", JT."DOB", JT."FIRSTNAME", JT."LASTNAME",JT."NICKNAME",JT."PLAYERID", 113 | JT."TWITTER_HANDLE" 114 | FROM "MLB_PLAYERS" RT, 115 | JSON_TABLE("JSON_DOCUMENT" FORMAT JSON, '$' COLUMNS 116 | "AGE" varchar2(2) path '$.player_info.queryResults.row.age', 117 | "BATS" varchar2(1) path '$.player_info.queryResults.row.bats', 118 | "STATUS" varchar2(16) path '$.player_info.queryResults.row.status', 119 | "THROWS" varchar2(1) path '$.player_info.queryResults.row.throws', 120 | "WEIGHT" varchar2(4) path '$.player_info.queryResults.row.weight', 121 | "COLLEGE" varchar2(1) path '$.player_info.queryResults.row.college', 122 | "FULLNAME" varchar2(16) path '$.player_info.queryResults.row.name_full', 123 | "FIRSTNAME" varchar2(8) path '$.player_info.queryResults.row.name_first', 124 | "LASTNAME" varchar2(8) path '$.player_info.queryResults.row.name_last', 125 | "NICKNAME" varchar2(16) path '$.player_info.queryResults.row.name_nick', 126 | "PLAYERID" varchar2(8) path '$.player_info.queryResults.row.player_id', 127 | "TEAM" varchar2(16) path '$.player_info.queryResults.row.team_name', 128 | "DOB" varchar2(32) path '$.player_info.queryResults.row.birth_date', 129 | "TWITTER_HANDLE" varchar2(16) path '$.player_info.queryResults.row.twitter_id') JT 130 | ``` 131 | 132 | - Query to see the high level information of your collection. 133 | 134 | ``` 135 | SELECT * FROM USER_SODA_COLLECTIONS WHERE URI_NAME = 'MLB_PLAYERS'; 136 | ``` 137 | 138 | - How to delete your collection 139 | ``` 140 | SELECT DBMS_SODA.drop_collection('MLB_PLAYERS') AS drop_status FROM DUAL; 141 | ``` 142 | 143 | 144 | ## APEX and SODA Collections 201 REST Access 145 | In this section we will show some of the basis to access the default SODA API's created with a SODA colletion in Oracle APEX. We will focus on: 146 | 147 | - Basic Authentication from the command line using curl 148 | - Setting up postman with basic authentication calls 149 | 150 | - Curl command to get the latest collections from a schema 151 | 152 | ``` 153 | curl -X GET -u 'SEARCHDEMO:' https://ayxzx2tnd0tqzed-sluggersapex.adb.us-ashburn-1.oraclecloudapps.com/ords/searchdemo/soda/latest 154 | ``` 155 | 156 | - Curl command to create a collection called ChipsCollection 157 | ``` 158 | curl -X PUT -u 'SEARCHDEMO:' https://ayxzx2tnd0tqzed-sluggersapex.adb.us-ashburn-1.oraclecloudapps.com/ords/searchdemo/soda/latest/ChipsCollection 159 | ``` 160 | 161 | - Curl command to delete a collection called ChipsCollection 162 | ``` 163 | curl -X DELETE -u 'SEARCHDEMO:' https://ayxzx2tnd0tqzed-sluggersapex.adb.us-ashburn-1.oraclecloudapps.com/ords/searchdemo/soda/latest/ChipsCollection 164 | ``` 165 | 166 | - Curl command to insert a document as a binary into a collection 167 | ``` 168 | curl -X POST -u 'SEARCHDEMO:' --data-binary @/C:/temp/json_mlb/valeri.json -H "Content-Type: application/json" https://ayxzx2tnd0tqzed-sluggersapex.adb.us-ashburn-1.oraclecloudapps.com/ords/searchdemo/soda/latest/MLB_PLAYERS 169 | ``` 170 | 171 | - Curl command to get a individual document based on the document id (ex. doc id - F79DA23912B74E369C36C8F020602A34) 172 | ``` 173 | curl -X GET -u 'SEARCHDEMO:' https://ayxzx2tnd0tqzed-sluggersapex.adb.us-ashburn-1.oraclecloudapps.com/ords/searchdemo/soda/latest/MLB_PLAYERS/ 174 | ``` 175 | 176 | - Curl command to delete a individual document 177 | ``` 178 | curl -X DELETE -u 'SEARCHDEMO:' https://ayxzx2tnd0tqzed-sluggersapex.adb.us-ashburn-1.oraclecloudapps.com/ords/searchdemo/soda/latest/MLB_PLAYERS/ 179 | ``` 180 | ## APEX OATUH in ORDS for SODA Collections 202 REST Access 181 | In this section we are going to show how to: 182 | - Create oauth token of type client_credentials for a developer in pl/sql 183 | 184 | 185 | - In SQL Workshop take a look at the user_ords_clients view structure 186 | ``` 187 | desc user_ords_clients; 188 | ``` 189 | 190 | - Query the table to see if any clients are existing. 191 | ``` 192 | select * from user_ords_clients; 193 | ``` 194 | 195 | - Below is example code to create a OAUTH client called player_dev for the developer Chip Baber. Generate a OAuth Token. 196 | ``` 197 | BEGIN 198 | OAUTH.create_client( 199 | p_name => 'player_dev', 200 | p_grant_type => 'client_credentials', 201 | p_owner => 'Chip Baber', 202 | p_description => 'A client for developer cbabers machine to access the SODA API', 203 | p_support_email => 'support@fakecompany.com', 204 | p_privilege_names => 'oracle.soda.privilege.developer', 205 | p_redirect_uri => 'https://fakecompany.com/404', 206 | p_support_uri => 'https://fakecompany.com/support' 207 | ); 208 | 209 | OAUTH.grant_client_role( 210 | p_client_name => 'player_dev', 211 | p_role_name => 'SQL Developer' 212 | ); 213 | 214 | OAUTH.grant_client_role( 215 | p_client_name => 'player_dev', 216 | p_role_name => 'SODA Developer' 217 | ); 218 | COMMIT; 219 | END; 220 | / 221 | ``` 222 | - Query in SQL Worksheet to get the client_id and client_secret. Copy these values. 223 | 224 | ``` 225 | SELECT id, name, client_id, client_secret FROM user_ords_clients; 226 | ``` 227 | 228 | - Collect your Client ID and Client Secret 229 | ![image of query](/assets/2023-03-13-10-43-58.png) 230 | 231 | - Insert the client id and client secret into the curl statement below to get your oauth token. 232 | ``` 233 | curl -i -k --user : --data "grant_type=client_credentials" https://ayxzx2tnd0tqzed-sluggersapex.adb.us-ashburn-1.oraclecloudapps.com/ords/searchdemo/oauth/token 234 | 235 | ``` 236 | ![](/assets/2023-03-13-10-55-44.png) 237 | 238 | - Add Bearer token to Postman, test basic rest endpoints. 239 | ``` 240 | curl -i -H "Authorization: Bearer " -X GET https://ayxzx2tnd0tqzed-sluggersapex.adb.us-ashburn-1.oraclecloudapps.com/ords/searchdemo/soda/latest 241 | ``` 242 | 243 | - Query these additional views to see how the pl/sql above relates inside the database. 244 | ``` 245 | select * from user_ords_client_privileges; 246 | select * from user_ords_client_roles; 247 | select * from user_ords_roles; 248 | select * from user_ords_privileges; 249 | select * from user_ords_privilege_roles; 250 | select * from user_ords_privilege_mappings; 251 | ``` 252 | 253 | 254 | - Delete Client 255 | ``` 256 | BEGIN 257 | OAUTH.revoke_client_role('player_dev','SQL Developer'); 258 | OAUTH.revoke_client_role('player_dev','SODA Developer'); 259 | OAUTH.delete_client('player_dev'); 260 | COMMIT; 261 | END; 262 | / 263 | ``` 264 | 265 | ## Example SODA Commands 266 | - These commands will not execute inside SQL Worksheet but will inside Database Actions. 267 | 268 | ``` 269 | soda create MLB_PLAYERS 270 | ``` 271 | 272 | - Example SODA actions 273 | ``` 274 | soda list 275 | soda count MLB_PLAYERS 276 | soda get MLB_PLAYERS -all 277 | soda get MLB_PLAYERS -k 278 | soda insert MLB_PLAYERS {"name" : "Chip is awesome!"} 279 | soda get MLB_PLAYERS -k 280 | soda remove MLB_PLAYERS -k 281 | soda get MLB_PLAYERS -f {"player_info": {"queryResults": {"row": { "jersey_number": "97" }}}} 282 | ``` 283 | 284 | -------------------------------------------------------------------------------- /order1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GSI 5 | 5.21 6 | 5.21 7 | 8 | Hamilton 9 | OMS 10 | 11 | 12 | PHONA_SFS001 13 | WMS 14 | 15 | OrdersToFulfill 16 | 17 | 328683989 18 | 3286839869 19 | 20 | 2022-07-11T15:02:12+00:00 21 | 22 | 23 | 24 | 641 25 | PHO_NA-SFS004 26 | SHIP_TO_HOME 27 | B2C 28 | 101581161860002 29 | 001731588523502 30 | N 31 | 2022-07-11T14:55:42+00:00 32 | 2022-07-11T17:02:09+00:00 33 | 2022-07-11T00:00:00+00:00 34 | 2022-07-11T00:00:00+00:00 35 | en_US 36 | 37 | 00127abMoqZVDv9KZPxhzuRW4gyXLon 38 | Chip Baber 39 | Chip 40 | Baber 41 | chipbaber@yahoo.com 42 | en_US 43 |
44 | 16441 Hampton Road 45 | Hamilton 46 | VA 47 | US 48 | 20158 49 |
50 | 51 | Home 52 | 7038621187 53 | 7038621187 54 | 55 |
56 | 57 | 00127abMoqZVDv9KZPxhzuRW4gyXLow 58 | Frank Baber 59 | Frank 60 | Baber 61 | en_US 62 |
63 | 16441 Hampton Road 64 | Hamilton 65 | VA 66 | US 67 | 20158 68 |
69 | 70 | Cell 71 | 7038621187 72 | 7038621187 73 | 74 |
75 | 76 | ANY 77 | GND 78 | 79 | 80 | 81 | TotalInvoiceAmount 82 | 75.78 83 | USD 84 | 85 | 86 | 87 | 88 | TotalMerchandiseAmount 89 | 70 90 | USD 91 | 92 | 93 | 94 | 95 | TotalTaxAmount 96 | 5.78 97 | USD 98 | 99 | 100 | 101 | 102 | TotalDiscountAmount 103 | 0 104 | USD 105 | 106 | 107 | 108 | 109 | TotalHFRAmount 110 | 0 111 | USD 112 | 113 | 114 | 115 | 116 | TotalShippingAmount 117 | 0 118 | USD 119 | 120 | 121 | 122 | 123 | TotalPriceTaxAmount 124 | 5.78 125 | USD 126 | 127 | 128 | 129 | 130 | TotalShippingTaxAmount 131 | 0 132 | USD 133 | 134 | 135 | 136 | PAYPAL 137 | PY 138 | 139 | PaymentType 140 | PAYPAL 141 | 142 | 143 | CreditCardType 144 | PY 145 | 146 | 147 | 148 | VATonMerchandise 149 | 0.0 150 | 151 | 152 | VATonFreight 153 | 0.0 154 | 155 | 156 | SubOrderType 157 | N 158 | 159 | 160 | gsi_store_id 161 | HIBUS 162 | 163 | 164 | gsi_client_id 165 | HIBNA 166 | 167 | 168 | CatalogId 169 | 78 170 | 171 | 172 | GSIWMSOrderType 173 | 10 174 | 175 | 176 | ShipNode 177 | HIB_NA-SFS001 178 | 179 | 180 | IsHFREligible 181 | N 182 | 183 | 184 | RDFUID 185 | 511e0953-5441-44d4-a42c-757d0e69f562_1657551318165 186 | 187 | 188 | ORDER_SERVICE_ORDER_ID 189 | 1309348254 190 | 191 |
192 | 193 | 1 194 | 195 | 78 196 | 43245083 197 | 62072956 198 | 7P161 199 | 200 | 201 | 195866362321 202 | G 203 | 204 | 205 | 206 | GlobalGSIItemId 207 | 062072956 208 | 209 | 210 | UnitLength 211 | IN 212 | 1.00 213 | 214 | 215 | UnitWidth 216 | IN 217 | 1.00 218 | 219 | 220 | UnitHeight 221 | IN 222 | 1.00 223 | 224 | 225 | UnitWeight 226 | LBS 227 | 2.31 228 | 229 | 230 | UnitVolume 231 | CIN 232 | 1.00 233 | 234 | 235 | StyleID 236 | 7P161 237 | 238 | 239 | 240 | 241 | 31 242 | Black 243 | 1 244 | 70 245 | 70 246 | USD 247 | 248 | Department 249 | 379 250 | 251 | 252 | 253 | 254 | LineShippingAmount 255 | 0 256 | USD 257 | 258 | 259 | 260 | 261 | ExtendedVendorCost 262 | 0 263 | USD 264 | 265 | 266 | 267 | 268 | LineHandlingAmount 269 | 0 270 | USD 271 | 272 | 273 | 274 | 275 | UnitDiscountAmount 276 | 0 277 | USD 278 | 279 | 280 | 281 | 282 | LineMerchandiseAmount 283 | 70 284 | USD 285 | 286 | 287 | 288 | 289 | LineTotalAmount 290 | 75.78 291 | USD 292 | 293 | 294 | 295 | SELLER_USE 296 | N 297 | DESTINATION 298 | TEXAS 299 | STATE 300 | 35763 301 | Sales and Use Tax 302 | General Sales and Use Tax 303 | 6.25 304 | 70 305 | 4.38 306 | Price 307 | 308 | 309 | SELLER_USE 310 | N 311 | DESTINATION 312 | LA VERNIA 313 | CITY 314 | 38221 315 | Local Sales and Use Tax 316 | General Sales and Use Tax 317 | 1.5 318 | 70 319 | 1.05 320 | Price 321 | 322 | 323 | SELLER_USE 324 | N 325 | DESTINATION 326 | LA VERNIA MUNICIPAL DEVELOPMENT DISTRICT 327 | SPECIAL_PURPOSE_DISTRICT 328 | 87792 329 | Local Sales and Use Tax 330 | General Sales and Use Tax 331 | 0.5 332 | 70 333 | 0.35 334 | Price 335 | 336 | 337 | SELLER_USE 338 | N 339 | DESTINATION 340 | TEXAS 341 | STATE 342 | 35763 343 | Sales and Use Tax 344 | General Sales and Use Tax 345 | 0 346 | 0 347 | 0 348 | Shipping 349 | 350 | 351 | SELLER_USE 352 | N 353 | DESTINATION 354 | LA VERNIA 355 | CITY 356 | 38221 357 | Local Sales and Use Tax 358 | General Sales and Use Tax 359 | 0 360 | 0 361 | 0 362 | Shipping 363 | 364 | 365 | SELLER_USE 366 | N 367 | DESTINATION 368 | LA VERNIA MUNICIPAL DEVELOPMENT DISTRICT 369 | SPECIAL_PURPOSE_DISTRICT 370 | 87792 371 | Local Sales and Use Tax 372 | General Sales and Use Tax 373 | 0 374 | 0 375 | 0 376 | Shipping 377 | 378 | 379 | HiddenLineFlag 380 | N 381 | 382 | 383 | IsHazmat 384 | N 385 | 386 | 387 | ChargePromo 388 | N 389 | 390 | 391 | IsOrderLineReturnable 392 | True 393 | 394 | 395 | narvar_convert_id 396 | 52a1abc6-e77f-48ca-b0a9-9f9ec3b4b87f 397 | 398 | 399 | IMAGEURL 400 | 401 | 402 | 403 | ExtnScheduledMaxDelDate 404 | 2022-07-20T00:00:00Z 405 | 406 | 407 |
408 |
409 | -------------------------------------------------------------------------------- /order2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GSI 5 | 5.21 6 | 5.21 7 | 8 | Hamilton 9 | OMS 10 | 11 | 12 | IADNA_SFS001 13 | WMS 14 | 15 | OrdersToFulfill 16 | 17 | 328683990 18 | 3286839870 19 | 20 | 2022-07-11T15:02:12+00:00 21 | 22 | 23 | 24 | 649 25 | IAD_NA-SFS004 26 | SHIP_TO_HOME 27 | B2C 28 | 101581161860003 29 | 001731588523503 30 | N 31 | 2022-07-11T14:55:42+00:00 32 | 2022-07-11T17:02:09+00:00 33 | 2022-07-11T00:00:00+00:00 34 | 2022-07-11T00:00:00+00:00 35 | en_US 36 | 37 | 00127abMoqZVDv9KZPxhzuRW4gyXLoW 38 | Aroon Chumpmail 39 | Aroon 40 | Chumpmail 41 | Chumpmail@aol.com 42 | en_US 43 |
44 | 148 Dirt Road 45 | Hamilton 46 | VA 47 | US 48 | 20158 49 |
50 | 51 | Home 52 | 7038621187 53 | 7038621187 54 | 55 |
56 | 57 | 00127abMoqZVDv9KZPxhzuRW4gyXLow 58 | Aroon Chumpmail 59 | Chip 60 | Chumpmail 61 | en_US 62 |
63 | 16441 Dirt Road 64 | Hamilton 65 | VA 66 | US 67 | 20158 68 |
69 | 70 | Cell 71 | 7034499777 72 | 7034499777 73 | 74 |
75 | 76 | ANY 77 | GND 78 | 79 | 80 | 81 | TotalInvoiceAmount 82 | 85.78 83 | USD 84 | 85 | 86 | 87 | 88 | TotalMerchandiseAmount 89 | 80 90 | USD 91 | 92 | 93 | 94 | 95 | TotalTaxAmount 96 | 5.78 97 | USD 98 | 99 | 100 | 101 | 102 | TotalDiscountAmount 103 | 0 104 | USD 105 | 106 | 107 | 108 | 109 | TotalHFRAmount 110 | 0 111 | USD 112 | 113 | 114 | 115 | 116 | TotalShippingAmount 117 | 0 118 | USD 119 | 120 | 121 | 122 | 123 | TotalPriceTaxAmount 124 | 5.78 125 | USD 126 | 127 | 128 | 129 | 130 | TotalShippingTaxAmount 131 | 0 132 | USD 133 | 134 | 135 | 136 | PAYPAL 137 | PY 138 | 139 | PaymentType 140 | PAYPAL 141 | 142 | 143 | CreditCardType 144 | PY 145 | 146 | 147 | 148 | VATonMerchandise 149 | 0.0 150 | 151 | 152 | VATonFreight 153 | 0.0 154 | 155 | 156 | SubOrderType 157 | N 158 | 159 | 160 | gsi_store_id 161 | HIBUS 162 | 163 | 164 | gsi_client_id 165 | HIBNA 166 | 167 | 168 | CatalogId 169 | 78 170 | 171 | 172 | GSIWMSOrderType 173 | 10 174 | 175 | 176 | ShipNode 177 | HIB_NA-SFS001 178 | 179 | 180 | IsHFREligible 181 | N 182 | 183 | 184 | RDFUID 185 | 511e0953-5441-44d4-a42c-757d0e69f562_1657551318165 186 | 187 | 188 | ORDER_SERVICE_ORDER_ID 189 | 1309348254 190 | 191 |
192 | 193 | 1 194 | 195 | 78 196 | 43245083 197 | 62072956 198 | 7P161 199 | 200 | 201 | 195866362321 202 | G 203 | 204 | 205 | 206 | GlobalGSIItemId 207 | 062072956 208 | 209 | 210 | UnitLength 211 | IN 212 | 1.00 213 | 214 | 215 | UnitWidth 216 | IN 217 | 1.00 218 | 219 | 220 | UnitHeight 221 | IN 222 | 1.00 223 | 224 | 225 | UnitWeight 226 | LBS 227 | 2.31 228 | 229 | 230 | UnitVolume 231 | CIN 232 | 1.00 233 | 234 | 235 | StyleID 236 | 7P161 237 | 238 | 239 | 240 | 241 | 31 242 | Black 243 | 1 244 | 80 245 | 80 246 | USD 247 | 248 | Department 249 | 379 250 | 251 | 252 | 253 | 254 | LineShippingAmount 255 | 0 256 | USD 257 | 258 | 259 | 260 | 261 | ExtendedVendorCost 262 | 0 263 | USD 264 | 265 | 266 | 267 | 268 | LineHandlingAmount 269 | 0 270 | USD 271 | 272 | 273 | 274 | 275 | UnitDiscountAmount 276 | 0 277 | USD 278 | 279 | 280 | 281 | 282 | LineMerchandiseAmount 283 | 80 284 | USD 285 | 286 | 287 | 288 | 289 | LineTotalAmount 290 | 85.78 291 | USD 292 | 293 | 294 | 295 | SELLER_USE 296 | N 297 | DESTINATION 298 | TEXAS 299 | STATE 300 | 35763 301 | Sales and Use Tax 302 | General Sales and Use Tax 303 | 6.25 304 | 70 305 | 4.38 306 | Price 307 | 308 | 309 | SELLER_USE 310 | N 311 | DESTINATION 312 | LA VERNIA 313 | CITY 314 | 38221 315 | Local Sales and Use Tax 316 | General Sales and Use Tax 317 | 1.5 318 | 80 319 | 1.05 320 | Price 321 | 322 | 323 | SELLER_USE 324 | N 325 | DESTINATION 326 | LA VERNIA MUNICIPAL DEVELOPMENT DISTRICT 327 | SPECIAL_PURPOSE_DISTRICT 328 | 87792 329 | Local Sales and Use Tax 330 | General Sales and Use Tax 331 | 0.5 332 | 80 333 | 0.35 334 | Price 335 | 336 | 337 | SELLER_USE 338 | N 339 | DESTINATION 340 | TEXAS 341 | STATE 342 | 35763 343 | Sales and Use Tax 344 | General Sales and Use Tax 345 | 0 346 | 0 347 | 0 348 | Shipping 349 | 350 | 351 | SELLER_USE 352 | N 353 | DESTINATION 354 | LA VERNIA 355 | CITY 356 | 38221 357 | Local Sales and Use Tax 358 | General Sales and Use Tax 359 | 0 360 | 0 361 | 0 362 | Shipping 363 | 364 | 365 | SELLER_USE 366 | N 367 | DESTINATION 368 | LA VERNIA MUNICIPAL DEVELOPMENT DISTRICT 369 | SPECIAL_PURPOSE_DISTRICT 370 | 87792 371 | Local Sales and Use Tax 372 | General Sales and Use Tax 373 | 0 374 | 0 375 | 0 376 | Shipping 377 | 378 | 379 | HiddenLineFlag 380 | N 381 | 382 | 383 | IsHazmat 384 | N 385 | 386 | 387 | ChargePromo 388 | N 389 | 390 | 391 | IsOrderLineReturnable 392 | True 393 | 394 | 395 | narvar_convert_id 396 | 52a1abc6-e77f-48ca-b0a9-9f9ec3b4b87f 397 | 398 | 399 | IMAGEURL 400 | 401 | 402 | 403 | ExtnScheduledMaxDelDate 404 | 2022-07-20T00:00:00Z 405 | 406 | 407 |
408 |
409 | -------------------------------------------------------------------------------- /ords_resume_upload.md: -------------------------------------------------------------------------------- 1 | ## How to upload a BLOB in ORDS through REST API with parameters. 2 | 3 | This how to came at a request from a viewer of the [How to extract text from inside a PDF or Word Doc](https://www.youtube.com/watch?v=AfudCHhAHK4&list=PLsnBif_-5JnA8Hzvp8e1bQ3fo6VEvYEB0&index=10&t=9s). They wanted to know how to upload documents programmatically to the ATP database. In this tutorial we are leveraging a Oracle Free tier account and Oracle APEX 22.14. You may want to complete the steps to create the table structures in this [https://github.com/chipbaber/apex_textdemo/blob/main/README.md](readme.md) before proceeding below. 4 | 5 | [Watch Online](https://youtu.be/rnqGQrhvhLA) 6 | 7 | - Inside Oracle APEX, navigate to SQL Worksheet. 8 | 9 | ![](assets/ords_resume_upload-79ac84e5.png) 10 | 11 | - Click into Restful Services (ORDS) 12 | 13 | ![](assets/ords_resume_upload-05a3d666.png) 14 | 15 | - Register your schema with ORDS by clicking the button illustrated below. 16 | 17 | ![](assets/ords_resume_upload-cbddcc58.png) 18 | 19 | - Enable the ORDS Schema defaults with these settings. 20 | 21 | ![](assets/ords_resume_upload-357587ec.png) 22 | 23 | - Click on Modules, then create module. 24 | 25 | ![](assets/ords_resume_upload-5651e28c.png) 26 | 27 | ![](assets/ords_resume_upload-2f08d38e.png) 28 | 29 | - Set your defaults and create the module. 30 | 31 | ![](assets/ords_resume_upload-4c778540.png) 32 | 33 | ![](assets/ords_resume_upload-d29eb3ae.png) 34 | 35 | - Create a template by entering the following fields and pressing Create Template. 36 | 37 | ![](assets/ords_resume_upload-3081382b.png) 38 | ![](assets/ords_resume_upload-5828af96.png) 39 | 40 | - Create a Handler to retrieve the resumes via a get call. 41 | 42 | ![](assets/ords_resume_upload-1f5b0a99.png) 43 | 44 | - Enter the following in to create the get rest service. Then press Create Handler. 45 | 46 | ![](assets/ords_resume_upload-fccf2e85.png) 47 | 48 | ``` 49 | select doc_id, title, submitted_by, created_date from resume 50 | ``` 51 | 52 | ![](assets/ords_resume_upload-ea0babf0.png) 53 | 54 | - Click on the template and create a second handler. 55 | 56 | ![](assets/ords_resume_upload-755bbff4.png) 57 | 58 | ![](assets/ords_resume_upload-5709830e.png) 59 | 60 | - Set the method to post. 61 | 62 | ![](assets/ords_resume_upload-3c45fe4f.png) 63 | 64 | - Drop in the following mime types to allow Word and PDF resumes to be uploaded. 65 | ![](assets/ords_resume_upload-1081d676.png) 66 | 67 | ``` 68 | application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document 69 | 70 | ``` 71 | 72 | - Paste in the Code for the pl/sql procedure. 73 | 74 | ``` 75 | DECLARE 76 | /*set the variables*/ 77 | resume_id RESUME.DOC_ID%TYPE; 78 | created_on RESUME.CREATED_DATE%TYPE; 79 | v_title RESUME.TITLE%TYPE; 80 | v_filename RESUME.FILENAME%TYPE; 81 | v_submitted_by RESUME.SUBMITTED_BY%TYPE; 82 | v_mimetype RESUME.MIMETYPE%TYPE; 83 | INVALID_MIMETYPE EXCEPTION; 84 | 85 | BEGIN 86 | v_title := :TITLE; 87 | v_filename := :FILENAME; 88 | v_submitted_by := :SUBMITTED_BY; 89 | v_mimetype := :MIMETYPE; 90 | 91 | IF LTRIM(RTRIM(LOWER(v_mimetype))) NOT IN ('application/pdf','application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.document') 92 | THEN 93 | RAISE INVALID_MIMETYPE; 94 | END IF; 95 | 96 | IF v_title IS NULL OR v_filename IS NULL OR v_submitted_by IS NULL OR v_mimetype IS NULL 97 | THEN 98 | RAISE NO_DATA_FOUND; 99 | ELSE 100 | 101 | /*Get the insert date*/ 102 | select sysdate into created_on from dual; 103 | 104 | /*Insert the BLOB and return the trigger generated doc_id*/ 105 | INSERT INTO resume (TITLE, FILENAME, SUBMITTED_BY, RESUME, MIMETYPE, CREATED_DATE) VALUES (:TITLE, :FILENAME, :SUBMITTED_BY, :BODY, :MIMETYPE, created_on) RETURNING DOC_ID INTO resume_id; 106 | 107 | owa_util.status_line(201, '', false); 108 | owa_util.mime_header('application/json', true); 109 | htp.prn('{"status": "Resume Successfully Inserted","DOC_ID":"'||resume_id||'"}'); 110 | END IF; 111 | 112 | EXCEPTION 113 | WHEN INVALID_MIMETYPE THEN 114 | owa_util.status_line(411, 'Invalid MIME TYPE', false); 115 | owa_util.mime_header('application/json', true); 116 | htp.prn('{"status": "Invalid MIME Type Uploaded","MIME Type not in accepted list for resumes."}'); 117 | 118 | WHEN NO_DATA_FOUND THEN 119 | owa_util.status_line(411, 'Null Parameter Error', false); 120 | owa_util.mime_header('application/json', true); 121 | htp.prn('{"status": "Null Parameter Error","One or more required parameter values is missing. TITLE, FILENAME, SUBMITTED_BY, RESUME and MIMETYPE are all required to complete the post."}'); 122 | WHEN OTHERS 123 | THEN 124 | owa_util.status_line(411, 'Unknown Exception Error', false); 125 | owa_util.mime_header('application/json', true); 126 | htp.prn('{"status": "Unknown Exception Error","Something went wrong in the code, here is the sqlerr response:"'||SQLERRM||'}'); 127 | END; 128 | ``` 129 | 130 | - Create the Handler. 131 | 132 | ![](assets/ords_resume_upload-5709830e.png) 133 | 134 | - To test these API's we will configure postman. [Postman Main Page](https://www.postman.com/). Inside postman create a new collection buy clicking the + sign and entering a name. 135 | 136 | ![](assets/ords_resume_upload-eee346be.png) 137 | 138 | - Inside your collection add a new request and name it getResumeMetadata. 139 | 140 | ![](assets/ords_resume_upload-a122c046.png) 141 | 142 | ![](assets/ords_resume_upload-1fa933c9.png) 143 | 144 | - Go back into ORDS and copy the full url. 145 | 146 | ![](assets/ords_resume_upload-0763aa23.png) 147 | 148 | - Paste the url into postman and press send. 149 | 150 | ![](assets/ords_resume_upload-7e7ca268.png) 151 | 152 | ![](assets/ords_resume_upload-a04e43a0.png) 153 | 154 | - Review the results from the database. 155 | 156 | ![](assets/ords_resume_upload-fd713152.png) 157 | 158 | - Create a new request in postman to upload the document by pressing the + sign, clicking save and naming the new request. 159 | 160 | ![](assets/ords_resume_upload-25b94ab9.png) 161 | 162 | ![](assets/ords_resume_upload-ce29aad3.png) 163 | 164 | ![](assets/ords_resume_upload-6a66c162.png) 165 | 166 | - Set the type to post and paste in the full url from ORDS. 167 | 168 | ![](assets/ords_resume_upload-9371e009.png) 169 | ![](assets/ords_resume_upload-7f80f8c5.png) 170 | 171 | - Look at the values section of your insert statement, the textual items you need to pass in to insert with the BLOB. In our example, Title, Filename, submitted_by and mimetype are required for the insert. 172 | 173 | ![](assets/ords_resume_upload-b7f7c368.png) 174 | 175 | - In postman create a parameter for each of these items and insert default values for your test. 176 | 177 | ![](assets/ords_resume_upload-b15fea9f.png) 178 | 179 | - Click on the body tab and set to binary. Select your resume file. The binary file will map to your pl/sql through the :body bind variable. 180 | 181 | ![](assets/ords_resume_upload-c9bac9b1.png) 182 | 183 | - Save your work in postman and press send. Review the body response in postman. 184 | 185 | ![](assets/ords_resume_upload-e679437a.png) 186 | 187 | - Navigate in APEX to SQL Workshop and run the following query to confirm the file and metadata were inserted. 188 | 189 | ![](assets/ords_resume_upload-b6dd6627.png) 190 | 191 | 192 | - Optional: To troubleshoot sometimes Code to loop through the headers and output the header + value. 193 | 194 | ``` 195 | for i in 1..nvl(owa.num_cgi_vars, 0) loop 196 | htp.p(owa.cgi_var_name(i) || ' : ' || owa.cgi_var_val(i)); 197 | htp.p(' '); 198 | end loop; 199 | ``` 200 | -------------------------------------------------------------------------------- /printAClob.md: -------------------------------------------------------------------------------- 1 | # How to print a Clob in Oracle APEX 21.1.7 2 | - Please watch this video for more context on how to showcase a CLOB inside a APEX page. [https://youtu.be/pSw_jFyt5zw](https://youtu.be/pSw_jFyt5zw) 3 | 4 | - Use the following Code in a dynamic pl/sql region after watching the video. 5 | 6 | ``` 7 | declare 8 | resumeMarkup clob; 9 | amt INTEGER := 8000; -- max bytes to pull per CLOB in APEX 10 | pos INTEGER := 1; 11 | buf VARCHAR2(32767); -- max buffer size per CLOB pull in APEX 12 | len INTEGER; 13 | 14 | 15 | begin 16 | --Get the resume from Oracle Text filtered_docs table. 17 | select document into resumeMarkup from filtered_docs where QUERY_ID = :P4_QUERY_ID; 18 | 19 | --Check for zero length Clob 20 | IF (DBMS_LOB.GETLENGTH(resumeMarkup) = 0) THEN 21 | HTP.P('Indexing for filtered Markup for document not yet completed, please try again later.'); 22 | ELSE 23 | len := DBMS_LOB.GETLENGTH(resumeMarkup); 24 | 25 | /* iterate through the length of the clob*/ 26 | WHILE pos < len 27 | loop 28 | begin 29 | dbms_lob.read(resumeMarkup, amt, pos, buf); 30 | pos := pos + amt; 31 | 32 | -- print to APEX 33 | htp.p(buf); 34 | EXCEPTION 35 | WHEN NO_DATA_FOUND THEN 36 | resumeMarkup := EMPTY_CLOB(); 37 | END; 38 | end loop; 39 | end if; 40 | 41 | EXCEPTION 42 | WHEN NO_DATA_FOUND THEN 43 | resumeMarkup := EMPTY_CLOB(); 44 | END; 45 | ``` 46 | -------------------------------------------------------------------------------- /resumeAdmin.sql: -------------------------------------------------------------------------------- 1 | /* 2 | * Package: resumeAdmin 3 | * This package serves to automate the task of creating indexs for Oracle Text and some of the more advanced queries including 4 | * themes, full themes, gists and filtered_docs. 5 | * 6 | **/ 7 | create or replace package resumeAdmin as 8 | procedure Truncate_Table (p_tname in varchar2); 9 | 10 | procedure Create_Theme (p_doc_id in resume.doc_id%type); 11 | procedure Create_Full_Theme (p_doc_id in resume.doc_id%type); 12 | procedure Create_Gist (p_doc_id in resume.doc_id%type); 13 | procedure Create_Filtered_Doc (p_doc_id in resume.doc_id%type); 14 | 15 | procedure Batch_Create_Themes; 16 | procedure Batch_Create_Full_Themes; 17 | procedure Batch_Create_Gists; 18 | procedure Batch_Create_Filtered_Docs; 19 | 20 | end resumeAdmin; 21 | / 22 | 23 | create or replace package body resumeAdmin as 24 | 25 | /*----------------------- 26 | Procedures to truncate a indexing table before creation of a new action on the table passing in the name of the table to truncate inside a 27 | dynamic sql statement. 28 | -----------------------*/ 29 | procedure Truncate_Table(p_tname in varchar2) is 30 | pragma autonomous_transaction; 31 | p_stmt varchar2(100) := 'truncate table ' || p_tname; 32 | begin 33 | execute immediate p_stmt; 34 | EXCEPTION 35 | WHEN others THEN 36 | DBMS_OUTPUT.PUT_LINE('Error in Truncate_table procedure.'); 37 | end Truncate_Table; 38 | 39 | /*----------------------- 40 | Procedures to perform a thematic indexing action on a single document. 41 | -----------------------*/ 42 | procedure Create_Theme(p_doc_id in resume.doc_id%type) is 43 | begin 44 | ctx_doc.themes('searchMyDocs', p_doc_id, 'themes', p_doc_id, full_themes => false); 45 | EXCEPTION 46 | WHEN others THEN 47 | DBMS_OUTPUT.PUT_LINE('Error in Create_Theme procedure.'); 48 | end Create_Theme; 49 | 50 | /*----------------------- 51 | Procedures to perform a full thematic indexing action on a single document. 52 | -----------------------*/ 53 | procedure Create_Full_Theme(p_doc_id in resume.doc_id%type) is 54 | begin 55 | ctx_doc.themes('searchMyDocs', p_doc_id, 'full_themes', p_doc_id, full_themes => true); 56 | end Create_Full_Theme; 57 | 58 | /*----------------------- 59 | Procedures to perform a gist indexing action on a single document. 60 | -----------------------*/ 61 | procedure Create_Gist(p_doc_id in resume.doc_id%type) is 62 | begin 63 | ctx_doc.gist('searchMyDocs', p_doc_id, 'gists',p_doc_id,'P', pov =>'GENERIC'); 64 | end Create_Gist; 65 | 66 | /*----------------------- 67 | Procedures to extract the text from a blob of types like pdf or docx and place inside a CLOB table column for faster retrieval. 68 | -----------------------*/ 69 | procedure Create_Filtered_Doc(p_doc_id in resume.doc_id%type) is 70 | begin 71 | ctx_doc.filter('searchMyDocs', p_doc_id, 'filtered_docs', p_doc_id, plaintext => true); 72 | end Create_Filtered_Doc; 73 | 74 | /*----------------------- 75 | Procedures to perform a indexing action in a batch fashion on all blobs in a table these procedures are basic loops that 76 | call back to the single document procedure actions above. 77 | -----------------------*/ 78 | 79 | procedure Batch_Create_Themes is 80 | begin 81 | Truncate_Table('themes'); 82 | for x in (select doc_id from resume) loop 83 | Create_Theme(x.doc_id); 84 | end loop; 85 | end Batch_Create_Themes; 86 | 87 | procedure Batch_Create_Full_Themes is 88 | begin 89 | Truncate_Table('full_themes'); 90 | for x in (select doc_id from resume) loop 91 | Create_Full_Theme(x.doc_id); 92 | end loop; 93 | end Batch_Create_Full_Themes; 94 | 95 | procedure Batch_Create_Gists is 96 | begin 97 | Truncate_Table('gists'); 98 | for x in (select doc_id from resume) loop 99 | Create_Gist(x.doc_id); 100 | end loop; 101 | end Batch_Create_Gists; 102 | 103 | procedure Batch_Create_Filtered_Docs is 104 | begin 105 | Truncate_Table('filtered_docs'); 106 | for x in (select doc_id from resume) loop 107 | Create_Filtered_Doc(x.doc_id); 108 | end loop; 109 | end Batch_Create_Filtered_Docs; 110 | 111 | 112 | end resumeAdmin; 113 | / 114 | -------------------------------------------------------------------------------- /shellconsole_export_to_objstore.md: -------------------------------------------------------------------------------- 1 | ### Data Pump 101 for Autonomous Database in OCI Cloud Shell Console 2 | In this video we will show how to quickly export information from your Autonomous database to object storage leveraging Oracle Data Pump and the OCI Shell Console. The video begins by setting up a auth token, a object storage bucket and opening the shell console. From there we connect into SQL*Web Developer and look at how to create a credential in the database to connect to object storage directly, then will construct a simple export statement that saves the .dmp to our object storage location. For learning purposes we will save our export.log file to the built in data pump directory, then show you how to both query the directory and how to move files from the out of the box directory to object storage leveraging the DBMS_CLOUD.PUT_OBJECT API. The code samples inside github include additional examples of import statements, export statements and code samples to delete credentials. 3 | 4 | Reference this video for how to connect your shell console to your autonomous db. [Connect your OCI Shell Console to an Autonomous Database APEX Schema in 3 min.](https://youtu.be/ts76gocXLe8) 5 | 6 | - Please watch this video before proceeding to the sample code below [Data Pump 101 for Autonomous Database in OCI Cloud Shell Console](https://youtu.be/CvyzCjdDvTU). 7 | 8 | - Create or collect your auth token. 9 | 10 | - Open the Cloud Shell console and source your .bash_profile. 11 | ``` 12 | . .bash_profile 13 | ``` 14 | 15 | - Create a new bucket and capture the namespace & name in the fields below. 16 | ``` 17 | Namespace: 18 | Bucket name: 19 | ``` 20 | 21 | - In a new browser tab open up database actions, and connect to SQL*Developer. This will make viewing some of the sample queries easier. 22 | ``` 23 | https:///ords/sql-developer? 24 | Ex. URL 25 | https://ayxzx2tnd0tqzed-sluggersapex.adb.us-ashburn-1.oraclecloudapps.com/ords/sql-developer? 26 | ``` 27 | 28 | - Check to see if you have an existing credintial. 29 | ``` 30 | SELECT credential_name, username, comments FROM all_credentials; 31 | ``` 32 | 33 | - Create a new credential by pasting in your auth token into the password field below. 34 | ``` 35 | BEGIN 36 | DBMS_CLOUD.CREATE_CREDENTIAL( 37 | credential_name => 'CHIPS_CRED2', 38 | username => 'oracleidentitycloudservice/chipbaber@gmail.com', 39 | password => '' 40 | ); 41 | END; 42 | ``` 43 | 44 | - Using the fields above from your bucket create a object storage url to your bucket. 45 | ``` 46 | https://objectstorage.us-ashburn-1.oraclecloud.com/n//b//o/ 47 | 48 | Example: 49 | https://objectstorage.us-ashburn-1.oraclecloud.com/n/id9ju5cntedk/b/apex-backup2024/o/ 50 | ``` 51 | 52 | - Create your data pump export command and execute inside the Cloud Shell and launch a export command. Leverage your object storage url above as the dumpfile location. In this example we export a single table. 53 | ``` 54 | expdp @ credential= dumpfile=export.dmp TABLES=. logfile=.log directory=data_pump_dir parallel=4 55 | 56 | expdp searchdemo@sluggersapex_low credential=CHIPS_CRED2 dumpfile=https://objectstorage.us-ashburn-1.oraclecloud.com/n/id9ju5cntedk/b/apex-backup2024/o/playersbk_8-27.dmp TABLES=searchdemo.players logfile=export8-27.log directory=data_pump_dir parallel=4 57 | ``` 58 | 59 | - Syntax on all export options like schemas, mutliple tables, full database ... can be found here [https://docs.oracle.com/en/database/oracle/oracle-database/23/sutil/oracle-data-pump-overview.html#GUID-17FAE261-0972-4220-A2E4-44D479F519D4](https://docs.oracle.com/en/database/oracle/oracle-database/23/sutil/oracle-data-pump-overview.html#GUID-17FAE261-0972-4220-A2E4-44D479F519D4). 60 | 61 | 62 | - Post export you can query the files in your bucket from SQL*Plus. 63 | ``` 64 | select object_name,bytes from dbms_cloud.list_objects('CHIPS_CRED2','https://objectstorage.us-ashburn-1.oraclecloud.com/n//b//o/'); 65 | 66 | Example: 67 | select object_name,bytes from dbms_cloud.list_objects('CHIPS_CRED2','https://objectstorage.us-ashburn-1.oraclecloud.com/n/id9ju5cntedk/b/apex-backup2024/o/'); 68 | ``` 69 | 70 | - ADB comes with a pre-mapped data pump directory. This is where your log file in this example was saved. You can view all files in the data pump directory. 71 | ``` 72 | SELECT * FROM DBMS_CLOUD.LIST_FILES('DATA_PUMP_DIR'); 73 | ``` 74 | 75 | - You can move the log file from Data Pump Directory to Object Storage. 76 | ``` 77 | begin 78 | DBMS_CLOUD.PUT_OBJECT(credential_name => 'CHIPS_CRED2', 79 | object_uri => 'https://objectstorage.us-ashburn-1.oraclecloud.com/n//b//o/', 80 | directory_name => 'DATA_PUMP_DIR', 81 | file_name => ''); 82 | end; 83 | ``` 84 | 85 | - You can also delete files from the data pump directory with the following command. 86 | ``` 87 | DBMS_CLOUD.DELETE_FILE ('DATA_PUMP_DIR',''); 88 | ``` 89 | 90 | - (Optional) Drop your Cloud Credential 91 | ``` 92 | BEGIN 93 | DBMS_CLOUD.DROP_CREDENTIAL('CHIPS_CRED2'); 94 | END; 95 | ``` 96 | 97 | - Optional, if DBA then you can leverage this query to see all credentials. 98 | ``` 99 | SELECT owner, credential_name FROM dba_credentials; 100 | ``` 101 | 102 | - (Optional) Example Command to export to data pump dir a full schema. 103 | ``` 104 | expdp searchdemo@sluggersapex_low DIRECTORY=data_pump_dir DUMPFILE=searchdemo.dmp SCHEMAS=searchdemo LOGFILE=searchdemo6-14.log 105 | ``` 106 | 107 | - (Optional) Example Import Statement 108 | ``` 109 | impdp searchdemo@sluggersapex_low credential=CHIPS_CRED2 dumpfile=https://objectstorage.us-ashburn-1.oraclecloud.com/n/id9ju5cntedk/b/db-backup2024/o/searchdemo7-10.dmp 110 | ``` 111 | 112 | -------------------------------------------------------------------------------- /shellconsole_to_atp.md: -------------------------------------------------------------------------------- 1 | ## Connect your OCI Shell Console to an Autonomous Database in 3 min. 2 | Are you curious on how to connect to your autonmous database from the OCI shell console? Perhaps you have an APEX schema and want to run SQL*PLus to look at the data inside autonomous? The fastest way to easily connect via SQL*Plus to Oracle Autonmous Database for quick developed access is through the OCI Shell Console. This video is designed for developed to show you how in just 3 minutes you can download your autonomous database wallet, modify the sqlnet.ora and .bash_profile then login via SQL*Plus and begin to query your database. This video assumes your autonomous database is already provisioned. 3 | 4 | Please watch this video before going through the Code Samples below [https://youtu.be/ts76gocXLe8](https://youtu.be/ts76gocXLe8) 5 | 6 | - Create a wallet directory and navigate into the directory folder. 7 | ``` 8 | mkdir wallet 9 | cd wallet 10 | ``` 11 | 12 | - Build our your oci command line statement to download your wallet file by collecting the ocid of the autonmous database and entering your admin password. 13 | 14 | ``` 15 | oci db autonomous-database generate-wallet --autonomous-database-id --file SLUGGERSAPEX.zip --password 'add your password' 16 | ``` 17 | 18 | - unzip the wallet file and get your current location. 19 | ``` 20 | unzip SLUGGERSAPEX.zip 21 | pwd 22 | ``` 23 | ![](assets/2024-06-12-13-58-56.png) 24 | 25 | - alter the sqlnet.ora file so the directory points to your wallet location. In this example it is /home/chipbaber/wallet 26 | ``` 27 | vi sqlnet.ora 28 | ``` 29 | 30 | - Modify your bash profile so it remembers your sqlnet.ora location 31 | ``` 32 | cd .. 33 | vi .bash_profile 34 | ``` 35 | 36 | - add in the lcoation to your wallet and save your changes. 37 | ``` 38 | export TNS_ADMIN=/home/chipbaber/wallet 39 | ``` 40 | 41 | - Refresh your bash_profile. 42 | ``` 43 | . .bash_profile 44 | ``` 45 | 46 | - View the various connect string options by looking at your tnsnames.ora file. In this example we will use the sluggersapex_low connection. 47 | ``` 48 | cd wallet 49 | more tnsnames.ora 50 | ``` 51 | 52 | - connect to your database as the user you desire and test a query. 53 | ``` 54 | sqlplus admin@ 55 | ``` 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /sqlWebExamples_.sql: -------------------------------------------------------------------------------- 1 | --Example 1: Save and edit to device. 2 | 3 | SELECT 4 | "RT"."ID", JT."AGE",JT."BATS", JT."STATUS",JT."THROWS",JT."WEIGHT", 5 | JT."COLLEGE",JT."FULLNAME", JT."DOB", JT."FIRSTNAME", JT."LASTNAME",JT."NICKNAME",JT."PLAYERID", 6 | JT."TWITTER_HANDLE" 7 | FROM "MLB_PLAYERS" RT, 8 | JSON_TABLE("JSON_DOCUMENT" FORMAT JSON, '$' COLUMNS 9 | "AGE" varchar2(2) path '$.player_info.queryResults.row.age', 10 | "BATS" varchar2(1) path '$.player_info.queryResults.row.bats', 11 | "STATUS" varchar2(16) path '$.player_info.queryResults.row.status', 12 | "THROWS" varchar2(1) path '$.player_info.queryResults.row.throws', 13 | "WEIGHT" varchar2(4) path '$.player_info.queryResults.row.weight', 14 | "COLLEGE" varchar2(1) path '$.player_info.queryResults.row.college', 15 | "FULLNAME" varchar2(16) path '$.player_info.queryResults.row.name_full', 16 | "FIRSTNAME" varchar2(8) path '$.player_info.queryResults.row.name_first', 17 | "LASTNAME" varchar2(8) path '$.player_info.queryResults.row.name_last', 18 | "NICKNAME" varchar2(16) path '$.player_info.queryResults.row.name_nick', 19 | "PLAYERID" varchar2(8) path '$.player_info.queryResults.row.player_id', 20 | "TEAM" varchar2(16) path '$.player_info.queryResults.row.team_name', 21 | "DOB" varchar2(32) path '$.player_info.queryResults.row.birth_date', 22 | "TWITTER_HANDLE" varchar2(16) path '$.player_info.queryResults.row.twitter_id') JT 23 | 24 | --- Example Query 2: Visual Auto trace for Queries 25 | SELECT ID, json_object('PONumber' VALUE PurchaseOrder.PONumber, 'OrderDate' VALUE PurchaseOrder.OrderDate, 26 | 'Items' VALUE (select LISTAGG(json_object('PartNumber' VALUE Items.PartNumber, 'Product Name' VALUE Items.ProductName,'Quantity' VALUE Items.Quantity,'Price' VALUE Items.Price,'Notes' VALUE Items.Notes FORMAT JSON)) as ITEMJSONOUTPUT 27 | FROM STAGE_XML, XMLTABLE('/PurchaseOrder/Items/Item' PASSING STAGE_XML.xml_col 28 | COLUMNS 29 | PartNumber VARCHAR2(30) PATH '@PartNumber', 30 | ProductName VARCHAR2(30) PATH 'ProductName', 31 | Quantity number(5) PATH 'Quantity', 32 | Price number(8,2) PATH 'USPrice', 33 | Notes VARCHAR2(30) PATH 'Comment' 34 | ) Items 35 | group by ID) FORMAT JSON) JSONOUTPUT 36 | FROM STAGE_XML, XMLTABLE('/PurchaseOrder' PASSING STAGE_XML.xml_col 37 | COLUMNS 38 | PONumber VARCHAR2(30) PATH '@PurchaseOrderNumber', 39 | OrderDate VARCHAR2(30) PATH '@OrderDate' 40 | ) PurchaseOrder 41 | 42 | --Example 3: SODA Query Support 43 | soda list 44 | soda count MLB_PLAYERS 45 | soda get MLB_PLAYERS -f {"player_info": {"queryResults": {"row": { "jersey_number": "97" }}}} 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /updateImageOnSelectList.md: -------------------------------------------------------------------------------- 1 | ## How to Update a Image Item on Select List Change without Page Refresh 2 | 3 | In this tutorial we will show how to dynamically change a image src on select list change without refreshing the page. 4 | 5 | ``` 6 | CREATE table "PLAYERS" ( 7 | "ID" NUMBER, 8 | "PLAYERNAME" VARCHAR2(200), 9 | "CARD_URL" VARCHAR2(600), 10 | constraint "PLAYERS_PK" primary key ("ID") 11 | ) 12 | / 13 | 14 | CREATE sequence "PLAYERS_SEQ" 15 | / 16 | 17 | CREATE trigger "BI_PLAYERS" 18 | before insert on "PLAYERS" 19 | for each row 20 | begin 21 | if :NEW."ID" is null then 22 | select "PLAYERS_SEQ".nextval into :NEW."ID" from sys.dual; 23 | end if; 24 | end; 25 | / 26 | ``` 27 | -------------------------------------------------------------------------------- /xml_ORDS_ingestion.md: -------------------------------------------------------------------------------- 1 | ## XML Ingestion through ORDS REST API 2 | 3 | In this example we will showcase how Oracle ATP can consume XML files through ORDS and store natively inside the database insde the XML data type. We will also show some basic queries on the information. The ORDS REST service will ingest the .xml file as a binary file and convert row by row to a CLOB form that can be inserted into the XMLtype in the DB. Please watch the following [video](https://youtu.be/JPyVzhQgTV0) before proceeding through this code. 4 | 5 | - Login to APEX and navigate to SQL Workshop. Execute the following SQL to create the stage_xml table. 6 | 7 | 8 | ``` 9 | CREATE TABLE "STAGE_XML" 10 | ( "XML_COL" "SYS"."XMLTYPE" , 11 | "PROCESSED" CHAR(1) COLLATE "USING_NLS_COMP" NOT NULL ENABLE, 12 | "ID" NUMBER NOT NULL ENABLE 13 | ) DEFAULT COLLATION "USING_NLS_COMP" 14 | / 15 | 16 | CREATE SEQUENCE "STAGE_XML_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE 17 | / 18 | 19 | CREATE OR REPLACE EDITIONABLE TRIGGER "xml_stage_pk" 20 | before insert on "STAGE_XML" 21 | for each row 22 | begin 23 | if :NEW."ID" is null then 24 | select "STAGE_XML_SEQ".nextval into :NEW."ID" from sys.dual; 25 | end if; 26 | end; 27 | 28 | / 29 | ALTER TRIGGER "xml_stage_pk" ENABLE 30 | / 31 | ``` 32 | 33 | - Create a new module with the following naming convention. 34 | 35 | ![](assets/xml_ORDS_ingestion-afb53eb3.png) 36 | 37 | - Create a template with the following information. 38 | 39 | ![](assets/xml_ORDS_ingestion-64290b32.png) 40 | 41 | - Create a handler. 42 | 43 | ![](assets/xml_ORDS_ingestion-d2feee39.png) 44 | ![](assets/xml_ORDS_ingestion-c5e54fd3.png) 45 | 46 | 47 | - Add mime types for the XML Ingestion 48 | 49 | ![](assets/xml_trigger-400f78ba.png) 50 | 51 | ``` 52 | application/xml,text/xml 53 | ``` 54 | 55 | Example Comments 56 | ``` 57 | Post method for xml upload via rest with conversion to xml and insertion into ADB as XMLtype. 58 | ``` 59 | ![](assets/xml_ORDS_ingestion-47475732.png) 60 | 61 | - Add the following PL/SQL code to ingest the XML as a binary file and convert to CLOB for insertion into the table as the XML type. 62 | 63 | ``` 64 | declare 65 | t1 timestamp := systimestamp; 66 | t2 timestamp; 67 | v_content BLOB; -- Uploading to ORDS as a BLOB in binary 68 | blob_length INTEGER; 69 | v_xml clob; 70 | pos INTEGER := 1; 71 | buf INTEGER := 32767; -- max buffer size per CLOB pull in APEX 72 | v_temp VARCHAR2(32767); 73 | v_rowid VARCHAR2(100); 74 | 75 | 76 | BEGIN 77 | -- put raw blob into variable 78 | v_content := :body; 79 | blob_length := DBMS_LOB.GETLENGTH(v_content); 80 | --if empty xml file pushed into REST throw error 81 | IF v_content IS NULL 82 | THEN 83 | RAISE NO_DATA_FOUND; 84 | ELSE 85 | --create a temp clob 86 | DBMS_LOB.CREATETEMPORARY(v_xml, TRUE); 87 | 88 | /*Loop through the blob to form the CLOB*/ 89 | WHILE pos < blob_length 90 | LOOP 91 | --if the lenght of the file is shorter than the length of the buffer then swap in buffer length. 92 | if (blob_length < buf) THEN 93 | buf := blob_length; 94 | end if; 95 | -- convert blob raw to varchar and build a CLOB temp variable. 96 | v_temp := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(v_content, buf, pos)); 97 | DBMS_LOB.WRITEAPPEND(v_xml, LENGTH(v_temp), v_temp); 98 | -- move the buffer offset 99 | pos := pos + buf; 100 | END LOOP; 101 | 102 | /*Insert into ADB*/ 103 | insert into stage_xml (XML_COL, PROCESSED) values (xmltype.createxml(v_xml), 'N') RETURNING ROWID INTO v_rowid; 104 | 105 | --return post response 106 | owa_util.status_line(201, '', false); 107 | owa_util.mime_header('application/json', true); 108 | t2 := systimestamp; --get end time 109 | htp.prn('{"status": "XML Inserted","Row ID":"'||v_rowid||'","Blob File Length Received":"'||blob_length||'","Clob File on Convert":"'||DBMS_LOB.GETLENGTH(v_xml)||',"Elapsed Processing Time(Seconds)":"'||TO_CHAR(t2-t1, 'SSSS.FF')||'"}'); 110 | --empty out the Clob 111 | v_xml := EMPTY_CLOB(); 112 | END IF; 113 | 114 | EXCEPTION 115 | WHEN NO_DATA_FOUND THEN 116 | owa_util.status_line(411, 'Null XML File on REST POST Error', false); 117 | owa_util.mime_header('application/json', true); 118 | htp.prn('{"error": "411 - Null XML File on REST POST Error","message":"No xml file found in post request. Please return including the binary data in your post call."}'); 119 | v_xml := EMPTY_CLOB(); 120 | WHEN OTHERS 121 | THEN 122 | owa_util.status_line(412, 'Unknown Exception Error', false); 123 | owa_util.mime_header('application/json', true); 124 | htp.prn('{"error": "412 - Unknown Exception Error","status": "message","Something went wrong in the code, here is the sqlerr response:"'||SQLERRM||'}'); 125 | v_xml := EMPTY_CLOB(); 126 | 127 | end; 128 | ``` 129 | 130 | -- Navigate back to SQL Workshop, SQL Commands and execute the following query. 131 | 132 | ![](assets/xml_ORDS_ingestion-e5f9992f.png) 133 | 134 | ``` 135 | select * from stage_xml 136 | ``` 137 | 138 | -- Upload the sample xml documents in postman. order1.xml, order2.xml. Please reference this video on how to upload binary documents via postman. [Video](https://youtu.be/rnqGQrhvhLA) 139 | 140 | -- Run the query above again to see the xml documents. 141 | 142 | ![](assets/xml_ORDS_ingestion-472aa6d7.png) 143 | 144 | -- In the raw form this information can look complicated, however with relative ease we can query and create views to view the xml information in this form however we require. Create the following views, then query the information to get a better feel for how it works. 145 | 146 | -- Example query to view the Message Header information in the XML documents. 147 | 148 | ``` 149 | create or replace view v_messageheader as 150 | SELECT ID, MESSAGEHEADER.* FROM STAGE_XML, XMLTABLE('/OrdersToFulfill' PASSING STAGE_XML.xml_col 151 | COLUMNS 152 | std VARCHAR2(30) PATH 'MessageHeader/Standard', 153 | headerversion NUMBER(6,2) PATH 'MessageHeader/HeaderVersion', 154 | VersionReleaseNumber NUMBER(6,2) PATH 'MessageHeader/VersionReleaseNumber', 155 | SourceId varchar2(30) PATH 'MessageHeader/SourceData/SourceId', 156 | SourceType varchar2(30) PATH 'MessageHeader/SourceData/SourceType', 157 | DestinationId varchar2(30) PATH 'MessageHeader/DestinationData/DestinationId', 158 | DestinationType varchar2(30) PATH 'MessageHeader/DestinationData/DestinationType', 159 | EventType varchar2(30) PATH 'MessageHeader/EventType', 160 | MessageId varchar2(30) PATH 'MessageHeader/MessageData/MessageId', 161 | CorrelationId varchar2(30) PATH 'MessageHeader/MessageData/CorrelationId', 162 | CreateDateAndTime varchar2(30) PATH 'MessageHeader/CreateDateAndTime' 163 | ) MESSAGEHEADER 164 | ``` 165 | ![](assets/xml_ORDS_ingestion-c13cab02.png) 166 | 167 | -- Execute the query 168 | ``` 169 | select * from v_messageheader 170 | ``` 171 | 172 | ![](assets/xml_ORDS_ingestion-8919434f.png) 173 | 174 | -- Build the Order Header View 175 | 176 | ``` 177 | create or replace view v_orderheader as 178 | SELECT ID, ORDERHEADER.* FROM STAGE_XML, XMLTABLE('/OrdersToFulfill' PASSING STAGE_XML.xml_col COLUMNS 179 | MessageId varchar2(30) PATH 'MessageHeader/MessageData/MessageId', 180 | CATALOGID VARCHAR2(255) PATH 'Order/OrderHeader/ExtendedAttributes[Name="CatalogId"]/Value', 181 | CLIENTID VARCHAR2(255) PATH 'Order/OrderHeader/ClientId', 182 | CUSTOMERORDERID VARCHAR2(255) PATH 'Order/OrderHeader/CustomerOrderId', 183 | FACILITYID VARCHAR2(255) PATH 'Order/OrderHeader/FacilityId', 184 | FULFILLMENTCHANNEL VARCHAR2(255) PATH 'Order/OrderHeader/FulfillmentChannel', 185 | ORDERTYPE VARCHAR2(255) PATH 'Order/OrderHeader/OrderType', 186 | OMSORDERID VARCHAR2(40) PATH 'Order/OrderHeader/OMSOrderId', 187 | SPLITORDERINDICATOR VARCHAR2(255) PATH 'Order/OrderHeader/SplitOrderIndicator', 188 | ORDERENTRYDATETIME VARCHAR2(255) PATH 'Order/OrderHeader/OrderEntryDateTime', 189 | INVOICECREATEDATETIME VARCHAR2(255) PATH 'Order/OrderHeader/InvoiceCreateDateTime', 190 | PROMISESHIPDATE VARCHAR2(255) PATH 'Order/OrderHeader/PromiseShipDate', 191 | PROMISERECEIPTDATE VARCHAR2(255) PATH 'Order/OrderHeader/PromiseReceiptDate', 192 | LOCALE VARCHAR2(255) PATH 'Order/OrderHeader/Locale', 193 | GSI_STORE_ID VARCHAR2(255) PATH 'Order/OrderHeader/ExtendedAttributes[Name="gsi_store_id"]/Value', 194 | GSI_CLIENT_ID VARCHAR2(255) PATH 'Order/OrderHeader/ExtendedAttributes[Name="gsi_client_id"]/Value' 195 | ) ORDERHEADER 196 | ``` 197 | 198 | -- Query the view 199 | 200 | ``` 201 | Select * from v_orderheader 202 | ``` 203 | ![](assets/xml_ORDS_ingestion-a6449a5f.png) 204 | 205 | 206 | -- Create a Billto view. 207 | 208 | ``` 209 | create or replace view v_billto as 210 | SELECT ID, BILLTO.* FROM STAGE_XML, XMLTABLE('/OrdersToFulfill' PASSING STAGE_XML.xml_col COLUMNS 211 | MessageId varchar2(30) PATH 'MessageHeader/MessageData/MessageId', 212 | CUSTOMERID VARCHAR2(255) PATH 'Order/OrderHeader/BillTo/CustomerId', 213 | FULLNAME VARCHAR2(255) PATH 'Order/OrderHeader/BillTo/FullName', 214 | FIRSTNAME VARCHAR2(255) PATH 'Order/OrderHeader/BillTo/FirstName', 215 | LASTNAME VARCHAR2(255) PATH 'Order/OrderHeader/BillTo/LastName', 216 | EMAILADDRESS VARCHAR2(255) PATH 'Order/OrderHeader/BillTo/EmailAddress', 217 | PREFERREDLANGUAGECODE VARCHAR2(255) PATH 'Order/OrderHeader/BillTo/PreferredLanguageCode' 218 | ) BillTO 219 | ``` 220 | 221 | -- Select from the billto view 222 | ``` 223 | select * from v_billto 224 | ``` 225 | ![](assets/xml_ORDS_ingestion-147e05fe.png) 226 | 227 | -- How to select and display repeating xml elements with a primary key. In this example we will display the ExtendedAttributes repeating elements. 228 | 229 | ``` 230 | create or replace view v_extendedattributes as 231 | SELECT ID, m.messageID, m.customerorderid, m.OMSORDERID, ea.name, ea.description, ea.value 232 | FROM STAGE_XML, XMLTABLE('/OrdersToFulfill' PASSING STAGE_XML.xml_col COLUMNS 233 | MessageId varchar2(30) PATH 'MessageHeader/MessageData/MessageId', 234 | CUSTOMERORDERID VARCHAR2(255) PATH 'Order/OrderHeader/CustomerOrderId', 235 | OMSORDERID VARCHAR2(40) PATH 'Order/OrderHeader/OMSOrderId' 236 | ) m, 237 | XMLTABLE('/OrdersToFulfill/Order/OrderDetail/ItemId/ExtendedAttributes' PASSING STAGE_XML.xml_col COLUMNS 238 | name varchar2(30) PATH 'Name', 239 | description varchar2(30) PATH 'Description', 240 | value varchar2(30) PATH 'Value' 241 | ) ea 242 | ``` 243 | 244 | -- Query the view 245 | ``` 246 | select * from v_extendedattributes 247 | ``` 248 | ![](assets/xml_ORDS_ingestion-9fa40b81.png) 249 | 250 | -- Multi-row invoice query 251 | 252 | ``` 253 | create or replace view invoiceamount as 254 | SELECT ID, m.messageID, m.customerorderid, m.OMSORDERID, ia.amounttype, ia.monetaryamount, ia.currencycode 255 | FROM STAGE_XML, XMLTABLE('/OrdersToFulfill' PASSING STAGE_XML.xml_col COLUMNS 256 | MessageId varchar2(30) PATH 'MessageHeader/MessageData/MessageId', 257 | CUSTOMERORDERID VARCHAR2(255) PATH 'Order/OrderHeader/CustomerOrderId', 258 | OMSORDERID VARCHAR2(40) PATH 'Order/OrderHeader/OMSOrderId' 259 | ) m, 260 | XMLTABLE('/OrdersToFulfill/Order/OrderHeader/InvoiceAmount' PASSING STAGE_XML.xml_col COLUMNS 261 | amounttype varchar2(30) PATH 'Amount/AmountType', 262 | monetaryamount varchar2(30) PATH 'Amount/MonetaryAmount', 263 | currencycode varchar2(30) PATH 'Amount/CurrencyCode' 264 | ) ia 265 | ``` 266 | 267 | -Query the invoice. 268 | ``` 269 | select * from invoiceamount 270 | ``` 271 | ![](assets/xml_queries-3de3d3cf.png) 272 | -------------------------------------------------------------------------------- /xmltojson.md: -------------------------------------------------------------------------------- 1 | ## Example Queries to quickly convert to JSON 2 | While working on a project we came across a undocumented API that is very useful inside Oracle Autonomous DB. XMLTOJSON() is an API that will convert XML directly into JSON for you in a single query action. If you would like to work through the example below we suggest you first watch the following video to setup and upload XML via REST through ORDS in your database. [How to Ingest/Access XML Files with ORDS and APEX on Oracle ATP](https://www.youtube.com/watch?v=JPyVzhQgTV0&list=PLsnBif_-5JnA8Hzvp8e1bQ3fo6VEvYEB0&index=13&t=256s&pp=gAQBiAQB) 3 | 4 | If you come across this git repo first we encourage you to watch this video before attempting the code below. []() 5 | 6 | - Insert the following XML file into your database. []() 7 | 8 | - Run the following queries to test the upload. 9 | ``` 10 | SELECT ID, PurchaseOrder.* FROM STAGE_XML, XMLTABLE('/PurchaseOrder' PASSING STAGE_XML.xml_col 11 | COLUMNS 12 | PONumber VARCHAR2(30) PATH '@PurchaseOrderNumber', 13 | OrderDate VARCHAR2(30) PATH '@OrderDate', 14 | shiptoName VARCHAR2(30) PATH 'Address[@Type="Shipping"]/Name', 15 | billingName VARCHAR2(30) PATH 'Address[@Type="Billing"]/Name', 16 | notes VARCHAR2(30) PATH 'DeliveryNotes' 17 | ) PurchaseOrder 18 | 19 | SELECT ID, Items.* FROM STAGE_XML, XMLTABLE('/PurchaseOrder/Items/Item' PASSING STAGE_XML.xml_col 20 | COLUMNS 21 | PartNumber VARCHAR2(30) PATH '@PartNumber', 22 | ProductName VARCHAR2(30) PATH 'ProductName', 23 | Quantity number(5) PATH 'Quantity', 24 | Price number(8,2) PATH 'USPrice', 25 | Notes VARCHAR2(30) PATH 'Comment' 26 | ) Items 27 | 28 | SELECT PurchaseOrder.*, Items.* FROM STAGE_XML, XMLTABLE('/PurchaseOrder/Items/Item' PASSING STAGE_XML.xml_col 29 | COLUMNS 30 | PartNumber VARCHAR2(30) PATH '@PartNumber', 31 | ProductName VARCHAR2(30) PATH 'ProductName', 32 | Quantity number(5) PATH 'Quantity', 33 | Price number(8,2) PATH 'USPrice', 34 | Notes VARCHAR2(30) PATH 'Comment' 35 | ) Items, 36 | XMLTABLE('/PurchaseOrder' PASSING STAGE_XML.xml_col 37 | COLUMNS 38 | PONumber VARCHAR2(30) PATH '@PurchaseOrderNumber', 39 | OrderDate VARCHAR2(30) PATH '@OrderDate', 40 | shiptoName VARCHAR2(30) PATH 'Address[@Type="Shipping"]/Name', 41 | billingName VARCHAR2(30) PATH 'Address[@Type="Billing"]/Name', 42 | notes VARCHAR2(30) PATH 'DeliveryNotes' 43 | ) PurchaseOrder 44 | ``` 45 | - In the past json could be created leveraging a number of api's one of the most popular being 46 | ``` 47 | SELECT ID, json_object('PONumber' VALUE PurchaseOrder.PONumber, 'OrderDate' VALUE PurchaseOrder.OrderDate, 48 | 'Items' VALUE (select LISTAGG(json_object('PartNumber' VALUE Items.PartNumber, 'Product Name' VALUE Items.ProductName,'Quantity' VALUE Items.Quantity,'Price' VALUE Items.Price,'Notes' VALUE Items.Notes FORMAT JSON)) as ITEMJSONOUTPUT 49 | FROM STAGE_XML, XMLTABLE('/PurchaseOrder/Items/Item' PASSING STAGE_XML.xml_col 50 | COLUMNS 51 | PartNumber VARCHAR2(30) PATH '@PartNumber', 52 | ProductName VARCHAR2(30) PATH 'ProductName', 53 | Quantity number(5) PATH 'Quantity', 54 | Price number(8,2) PATH 'USPrice', 55 | Notes VARCHAR2(30) PATH 'Comment' 56 | ) Items 57 | group by ID) FORMAT JSON) JSONOUTPUT 58 | FROM STAGE_XML, XMLTABLE('/PurchaseOrder' PASSING STAGE_XML.xml_col 59 | COLUMNS 60 | PONumber VARCHAR2(30) PATH '@PurchaseOrderNumber', 61 | OrderDate VARCHAR2(30) PATH '@OrderDate' 62 | ) PurchaseOrder 63 | ``` 64 | 65 | - Leveraging the undocumented APO XMLtoJSON. WIP 66 | ``` 67 | select id, XMLTOJSON(XML_COL) JSON_OUTPUT from STAGE_XML 68 | ``` 69 | --------------------------------------------------------------------------------