Thursday, August 7, 2025

Hacking OAS dataset files

We had a request to save a copy of every dataset created and saved in Oracle Analytics Server (OAS). I will cover only local OAS datasets that are not in the database. Usually, this kind of requests come because of legal demands to save such data on external server.

In theory I can create a script that periodically copies the dataset files to the backup server/FTP.

The datasets files are saved on the server under 

  • Domain_Home/bidata/components/DSS/storage/ssi
  • Domain_Home/servers/obis1/cache/ xsastorage
  • Domain_Home/servers/obis1/cache/xsacache
NEVER update or do anything directly on those files. Only deal with copies of the files that are located in your folders.
NEVER change manually RCU database data.

The files I want are in Domain_Home/bidata/components/DSS/storage/ssi. Only files with DSS extension are relevant. The files names are strings that have nothing to do with the dataset name in OAS. 



My datasets can come from 2 different sources:

  • A file (CSV/Text/Excel) loaded as dataset from the UI.
  • A dataset created by Data Flow.

The loaded based DSS files are usually in the original files format, so renaming the DSS make them usable and in Parquet format. 

The Data Flow based DSS files are in CSV format and in Parquet format.

For Parquet files we usually need a special reader utility. 


How can I know what those DSS files formats are?

How can I know the real Dataset name?

The secret is in the XXX_BIFOUNDATION schema table S_NQ_DSS_DATASETS.


In that table I see different behavior for loaded files vs. Data Flow based ones.

While the Data Flow based datasets are represented by one row the Loaded datasets are represented by few rows (2 in my case).  

Data Flow based dataset

For Data Flow based dataset, the DATASET_NAME column holds the real Dataset name, and the DATAMODEL_ID is NULL. The MIMETYPE column value is "text/csv".

In the FILESTORE_ID column I see the DSS file names. The CSV file and the Parquet file. For example: 

{"src":"06a918f7-916f-49de-be33-9c046d53e869","src_parquet":"f76f107c-cb48-4853-a0d7-52839d4f194e"}

Checking the Domain_Home/bidata/components/DSS/storage/ssi I can see 2 DSS files:

  • 06a918f7-916f-49de-be33-9c046d53e869.dss - actually a CSV file
  • f76f107c-cb48-4853-a0d7-52839d4f194e.dss - actually a Parquet file

Now I have 2 options to handle the files:

  • Checking the S_NQ_DSS_DATASETS table for updates (LAST_MODIFIED column). Finding the relevant files names in FILESTORE_ID. Copying them with correct filenames and extensions.
  • Checking the Folder for new files on Linux/Windows level and finding the file name in the S_NQ_DSS_DATASETS table for proper dataset name and extension.


Loaded files, based dataset

For Loaded files, based dataset, we have a dataset row and the real data row in the S_NQ_DSS_DATASETS table. It is very similar to what we see in the UI where we can have several tables or files in a single dataset.

For the entire dataset row the DATASET_NAME column holds the real Dataset name, and the DATAMODEL_ID is NULL. The MIMETYPE column value is NULL. We can disregard the FILESTORE_ID column here. The FILE_LENGTH column value is -1.

For the data row in S_NQ_DSS_DATASETS we can see in the DATAMODEL_ID  column, the value of the dataset row DATASET_ID. By joining the 2 we can have the original dataset name for the data row.

In the data row, in the FILESTORE_ID column I see the DSS file names. The CSV file and the Parquet file. For example: 

{"src":"8f815cc1-044a-4caa-9026-431be828e347","src_parquet":"261dfba0-9adc-4572-a7d7-9cd4c95dccf5"}

Checking the Domain_Home/bidata/components/DSS/storage/ssi I can see 2 DSS files:

  • 8f815cc1-044a-4caa-9026-431be828e347.dss - actually a CSV or EXCEL or Text file
  • 261dfba0-9adc-4572-a7d7-9cd4c95dccf5.dss - actually a Parquet file

How do I know the proper format? By using the MIMETYPE column where I have values:

  • application/csv for CSV file.
  • application/vnd.openxmlformats-officedocument.spreadsheetml.sheet for Excel file.

Now I have 2 options to handle the files:

  • Checking the S_NQ_DSS_DATASETS table for updates (LAST_MODIFIED column). Finding the relevant files names in FILESTORE_ID .Copying them with correct filenames and extensions.
  • Checking the Folder for new files on Linux/Windows level and finding the file name in the S_NQ_DSS_DATASETS table for proper dataset name and extension.


I recommend a select of the following type to work with the data, this way you have proper names of DSS files and in FULL Name the name of the dataset:


SELECT

    a.dataset_id,

    a.stripe_id,

    a.dataset_name,

    b.dataset_name DS_name,

    b.dataset_name||(case when b.dataset_name IS NULL then '' else '-' end)||a.dataset_name FULL_NAME,

    a.filestore_id,

    substr(a.filestore_id, 9, instr(a.filestore_id, ',')-1-9)||'.dss' Orig_file,

    case when substr(a.filestore_id, instr(a.filestore_id, ':', -1)+1,4)='null' then NULL else     substr(a.filestore_id, instr(a.filestore_id, ':', -1)+2, length(a.filestore_id)-(instr(a.filestore_id, ':', -1)+2)-1 )||'.dss' end Parquet_file,

    a.acl_id,

    a.filetype_id,

    a.mimetype,

    a.owner_id,

    a.createdby_id,

    a.provider_id,

    a.type_options_xml,

    a.provider_options_xml,

    a.filetype_knobs,

    a.file_length,

    a.storage_file_length,

    a.last_modified,

    a.created_date,

    a.biservermetadata_last_modified,

    a.rawfile_last_modified,

    a.is_embryonic,

    a.is_user_striped,

    a.internal_id,

    a.namespace,

    a.connection_id,

    a.partition_key,

    a.refresh_option,

    a.schedule_xml,

    a.datamodel_id,

    a.error_code,

    a.error_message,

    a.parent_dataset_id,

    a.child_dataset_type,

    a.app_module_id,

    a.properties_last_modified

FROM

    dev_biplatform.s_nq_dss_datasets A, dev_biplatform.s_nq_dss_datasets B

where A.file_length<>-1 and a.datamodel_id=b.dataset_id(+)   

ORDER BY a.last_modified DESC

  ;







Thursday, July 31, 2025

Oracle APEX - Using user input text in an AI RAG Source - APEX$AI_LAST_USER_PROMPT

With APEX we can create a chatbot and connect it to AI data source. There are lots of good materials about it, but I was struggling with the problem how to pass the user input text as part of the RAG code. My colleague Yohay Asraf gave me the tip of using APEX$AI_LAST_USER_PROMPT that solved my problem. Thanks, Yohay!

In APEX we can now use AI options and configure RAG sources, Oracle 23ai Database features like SelectAI and OCI AI Agents. See links to few Labs at the end of the post.


In an APEX application under "Shared Components" - "Generative AI Configuration" I created a RAG query that uses the Vector option of the 23ai but how can we make it dynamic?


In my case, I loaded various car guides into a table and created chunks of the books and vectors from those chunks. Next, I'm looking for chunks of text that are similar to a specific text (Bla Bla Bla in the next example). 

In the example 

  • I'm using existing Encoder named doc_model to convert the input string to vector and name it "embedding". 
  • I compare the input vector to existing text chunks looking for minimal distance and limiting it to the selected Vehicle Make and model. 
  • I return 4 best results.

 WITH query_vector AS (

            SELECT VECTOR_EMBEDDING(doc_model USING 'Bla Bla Bla' AS data) as embedding)

SELECT embed_id, TEXT_CHUNK

FROM WKSP_APEX.VECTOR_STORE, query_vector

Where VECTOR_DISTANCE(EMBED_VECTOR, query_vector.embedding, COSINE)<0.6

AND VEHICLE_MAKE=:P2_MAKE  AND VEHICLE_MODEL=:P2_MODEL

ORDER BY VECTOR_DISTANCE(EMBED_VECTOR, query_vector.embedding, COSINE)

FETCH APPROX FIRST 4 ROWS ONLY


How do I make the input string dynamic? Here we have 2 options 

  • APEX$AI_LAST_USER_PROMPT - Retrieves the most recent user-entered prompt.
  • APEX$AI_ALL_USER_PROMPTS - Retrieves all user prompts, concatenated into a single string.

 https://docs.oracle.com/en/database/oracle/apex/24.2/htmdb/managing-ai-configurations-and-rag-sources.html#GUID-D1274017-381C-4988-8E6E-36095BA06655


Here is the new code:

WITH query_vector AS (

            SELECT VECTOR_EMBEDDING(doc_model USING :APEX$AI_LAST_USER_PROMPT AS data) as embedding)

SELECT embed_id, TEXT_CHUNK

FROM WKSP_APEX.VECTOR_STORE, query_vector

Where VECTOR_DISTANCE(EMBED_VECTOR, query_vector.embedding, COSINE)<0.6

AND VEHICLE_MAKE=:P2_MAKE AND VEHICLE_MODEL=:P2_MODEL

ORDER BY VECTOR_DISTANCE(EMBED_VECTOR, query_vector.embedding, COSINE)

FETCH APPROX FIRST 4 ROWS ONLY


As you can see, we are using 2 RAG sources Car Problems table and a Books table.



There is a nice blog by Harry Snart that uses it - RAG based Chatbots made easy 


If you want to start using AI or RAG and APEX, there are many Blogs and great labs in Oracle LiveLabs. 


Sunday, July 13, 2025

Oracle DB MCP server - Oracle SQLcl, few links

 Last week Oracle has announced the availability of Oracle DB MCP server, joining the general hype of MCP servers rather fast. Most of the materials were published by https://x.com/thatjeffsmith and https://x.com/krisrice. All I do here is gather few links from the webcasts and X for future use.

They wrote about it here: Introducing MCP Server for Oracle Database

The MCP server is part of Oracle SQLcl. It should work with all supported Oracle DB versions (On-Prem. & Cloud), meaning 19c and up.

If you want a general MCP intro: https://modelcontextprotocol.io/introduction 


There were 2 webcasts. The first (and longer) one covers everything that was covered in the introduction one, so I advise watching it only. 

Introducing SQL Developer Copilot Integration in Microsoft VSCode & MCP Support for Oracle Database: https://youtu.be/hj6WoZVGUBg?si=9C58_wcDBE9wkruT (1 hour).

The shorter - Oracle Developer Coaching: July News Edition https://youtu.be/Xnmty5_-v-M (33 min)

Screenshots from the webcasts:









Links and Resources:

Latest version of Oracle SQLcl download link:  

https://www.oracle.com/uk/database/sqldeveloper/technologies/sqlcl/download/

or direct link to the 25.2 version https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-25.2.0.184.2054.zip 


Documentation: https://docs.oracle.com/en/database/oracle/sql-developer-command-line/25.2/sqcug/using-oracle-sqlcl-mcp-server.html


Example MCP Clients: https://github.com/punkpeye/awesome-mcp-clients

Example MCP Servers: https://github.com/punkpeye/awesome-mcp-servers

AI for code tooling: https://github.com/oracle-samples/ml4code/tree/main/08_tooling


A blog on the subject by Hamza Eraoui: SQLcl MCP Server: Tips, Tricks, and Use Cases | by Hamza Eraoui | Jul, 2025 | Medium

Jeff Smith himself: 

And an intro by Paulo Portugal: Oracle SQLcl MCP: Bringing AI to SQL with Model Context Protocol

Eric Avidon on Techtarget: Oracle adds MCP support to advance agentic AI development




and what looks like oracle internal ref. https://ml4code.oraclecorp.com/libs/#mcp










Monday, June 2, 2025

讛转驻诇讙讜转 转讜爪讗讜转 诪讘讞谞讬 讘讙专讜转 讘诪转诪讟讬拽讛 5 讬讞讬讚讜转 讘砖谞讬诐 2013-2023

诪砖专讚 讛讞讬谞讜讱 (+ 讛转谞讜注讛 诇讞讜驻砖 讛诪讬讚注) 诪驻专住诐 转讜爪讗讜转 诪讘讞谞讬 讘讙专讜转 诇驻讬 讘转讬 住驻专, 讛讞诇 诪砖谞转 2013. 注讚 讻讛 驻讜专住诪讜 讛转讜爪讗讜转 讘专爪祝 注讚 砖谞转 2023. 讛驻专住讜诐 讛讜讗 诇驻讬 诪拽爪讜注 + 讬讞讬讚讜转 诇讬诪讜讚, 诇诪讜住讚 讞讬谞讜讻讬, 诇砖谞讛 诪住讜讬诪转, 讻讗砖专 讗诐 讬砖 驻讞讜转 诪10 谞讘讞谞讬诐 讘诪拽爪讜注 诪住讜讬讬诐, 讛爪讬讜谉 诇讗 诪转驻专住诐.  

讗讜诇讬 专讗讬转诐 讻转讘讜转 讛谞讜砖讗 诇讗讞专讜谞讛 讘YNET. 讛转讞诇转讬 诇讗住讜祝 讗转 讛谞转讜谞讬诐 诇驻谞讬 讻诪讛 砖谞讬诐, 讘谞住讬讜谉 诇住讬讬注 诇讘谞讬 诇讘讞讜专 讘讬转 住驻专 转讬讻讜谉, 讜诪讗讝 讗谞讬 讗讜住祝 讗讜转诐 讘讗讚讬拽讜转.


讘讜讗讜 谞讞拽讜专 拽爪转 讬讜转专 讗转 讛讛讬住讟讜专讬讛, 讛诪讙诪讜转 讜讛转讜爪讗讜转 讛砖讜谞讜转. 讛驻注诐 讗转诪拽讚 讘转讜爪讗讜转 诪讘讞谞讬 诪转诪讟讬拽讛 5 讬讞讬讚讜转. 

讛讬讚注转诐 砖诪讬 砖谞诪爪讗 讘诪拽讜诐 讛砖谞讬 讘2023 讘诪诪讜爪注 转讜爪讗讜转 讛讘讙专讜转 讘诪转诪讟讬拽讛 5 讬讞讬讚讜转 讛讜讗 讘讬转 住驻专 讞专讚讬? 

诇诪讛 爪专讬讱 诇转转 讻讘讜讚 诇讗讜诇驻谞转 爪讘讬讛 讘讘谞讬 讘专拽? 

讛讬讚注转诐 砖讘转讬 讛住驻专 讛诪讜讘讬诇讬诐 讛诐 诪讝专诐 诪诪诇讻转讬 讚转讬 讜讞专讚讬?

讜讙诐 专讙注... 诇讗 诇讛转诇讛讘 讙诐 诪讛转讜爪讗讜转 讛诇诇讜, 讻讬 讬砖 "讗讘诇"...

讛谞讬转讜讞 谞注砖讛 讘注讝专转 Oracle Analytics Cloud.


讛注讚驻讜转 讬讞讬讚讜转 诇讬诪讜讚 讘诪转诪讟讬拽讛 


讘讙专祝 谞讬转谉 诇专讗讜转 诪讙诪讛 拽讘讜注讛 砖诇 讬专讬讚讛 讘讗讞讜讝 讛谞讘讞谞讬诐 讘诪转诪讟讬拽讛 3 讬讞讬讚讜转. 诪65% 诪讻诇诇 讛谞讙砖讬诐 诇讘讙专讜转 讘诪转诪讟讬拽讛 讘砖谞转 2013 讜注讚 54.68% 讘砖谞转 2023. 讘砖谞转 2023 讬砖 讛讬驻讜讱 拽诇 砖诇 讛诪讙诪讛, 注诐 注诇讬讛 拽诇讛 诇注讜诪转 2022.

讘诪拽讘讬诇,  讗谞讜 专讜讗讬诐 诪讙诪讛 讛驻讜讻讛 讘诪转诪讟讬拽讛 5 讬讞讬讚讜转. 讗讞讜讝 讛谞讘讞谞讬诐 讘讛拽祝 砖诇 5 讬讞讬讚讜转 诪讻诇诇 讛谞讘讞谞讬诐 讘讘讙专讜转 讘诪转诪讟讬拽讛 注诇讛 诪12.05% 讘砖谞转 2013 讜注讚 诇20.38% 讘砖谞转 2022. 砖谞转 2023 讗谞讜 专讜讗讬诐 谞驻讬诇讛 诪讚讗讬讙讛 砖诇 讗讞讜讝 诇讜诪讚讬 5 讛讬讞讬讚讜转 诇18.77%, 讘谞讬讙讜讚 诇讻诇 诪讙诪讜转 讛注讘专. 诇诪注砖讛 讘砖谞转 2023 讗谞讜 讞讜讝专讬诐 诇讗讞讜讝讬诐 砖诇 砖谞转 2017! 讻驻讬 砖谞讬转谉 诇专讗讜转 讘讙专祝 讛讘讗, 诇诪专讜转 砖住讱 诪住驻专 讛谞讘讞谞讬诐 讘诪转诪讟讬拽讛 注诇讛 讘讻5,000 谞讘讞谞讬诐, 诪住驻专 讛谞讘讞谞讬诐 讘5 讬讞讬讚讜转 讬专讚 讘讻750 谞讘讞谞讬诐 讘讬谉 讛砖谞讬诐 2022 诇2023. 讻讚讗讬 诇注拽讜讘 讗讞专 讛诪讙诪讛 砖谞讬诐 讛讘讗讜转. 讛讗诐 讛讬讗 拽砖讜专讛 诇诪讙驻转 讛拽讜专讜谞讛?


注讜讚 诪讙诪讛 诪注谞讬讬谞转, 砖谞讬转谉 诇专讗讜转 讘讙专祝 讛转讞转讜谉, 讛讜讗 诪诪讜爪注 讛爪讬讜谞讬诐. 诪诪讜爪注 讛爪讬讜谞讬诐 讘3 讬讞讬讚讜转, 讛讜讗 诪砖诪注讜转讬转 谞诪讜讱 诪诪讜爪注 讛爪讬讜谞讬诐 讘4 讜5 讬讞讬讚讜转. 讘谞讜住祝, 诪诪讜爪注 讛爪讬讜谞讬诐 讘4 讬讞讬讚讜转 谞诪讜讱 讘诪拽爪转 诪讝讛 砖诇 5 讬讞讬讚讜转. 诪讗讞专 讜诇讻诇 诪住诇讜诇 讘讞讬谞讜转 谞驻专讚讜转 讛砖讜谞讜转 诪讗讜讚 讝讜 诪讝讜, 讗讬谉 讻讗谉 讛砖讜讜讗讛 诪讚讜讬讬拽转. 讜注讚讬讬谉 诪注谞讬讬谉 诇专讗讜转 砖诇诪专讜转 砖讛讘讞讬谞讜转 砖诇 3 讬讞讬讚讜转 拽诇讜转 诪砖诪注讜转讬转 诪讛讘讞讬谞讜转 砖诇 4 讜-5 讬讞讬讚讜转, 诪诪讜爪注 讛爪讬讜谞讬诐 谞砖讗专 谞诪讜讱 诇讗讜专讱 讻诇 讛砖谞讬诐.

讗谞讜 专讜讗讬诐 讬专讬讚讛 讞讚讛 诇诪讚讬 讘诪诪讜爪注 讻诇 讛诪住诇讜诇讬诐 讘砖谞讬诐 2018 讜2019. 诇讗 谞讬转谉 诇讛讗砖讬诐 讗转 讛拽讜专讜谞讛 讘讻讱. 讛讛砖驻注讛 砖诇讛 讛讬讗 讚讜讜拽讗 注诇 爪讬讜谞讬 2020 讜讗讬诇讱. 讛谞讬讞讜砖 讛讗讬砖讬 砖诇讬 讛讜讗 讬讜转专 讘讻讬讜讜谉 砖诇 讻讜转讘讬 讛讘讞讬谞讜转 讘砖谞讬诐 讗诇讜. 诪讛 砖注砖讜讬 诇讛讬讜转 拽砖讜专 诇拽讜专讜谞讛 讛讜讗 讛讬专讬讚讛 讘住讱 讛谞讘讞谞讬诐 讘诪转诪讟讬拽讛 讘砖谞转 2022, 讘谞讬讙讜讚 诇诪讙诪讛 讛讻诇诇讬转.


诪注讻砖讬讜 谞转诪拽讚 讘转讜爪讗讜转 诪讘讞谞讬 诪转诪讟讬拽讛 5 讬讞讬讚讜转 讘诇讘讚.


谞转讜谞讬诐 诇驻讬 驻讬拽讜讞 (诪诪诇讻转讬 / 诪诪诇讻转讬 讚转讬 / 讞专讚讬)

讘讗讜驻谉 注拽讘讬 诪讗讚, 诪诪讜爪注 转讜爪讗讜转 诪讘讞谞讬 诪转诪讟讬拽讛 5 讬讞讬讚讜转 砖诇 讛驻讬拽讜讞 讛诪诪诇讻转讬 讚转讬 讙讘讜讛 诪诪诪讜爪注 爪讬讜谞讬 讛驻讬拽讜讞 讛诪诪诇讻转讬 讛讻诇诇讬, 讘爪讜专讛 诪砖诪注讜转讬转 砖诇 讬讜转专 诪谞拽讜讚讛. 讻讱 诇讚讜讙诪讗 讘砖谞转 2023 讗谞讜 专讜讗讬诐 诪诪讜爪注 84.32 讘诪诪诇讻转讬 讚转讬, 诇注讜诪转 82.76 讘驻讬拽讜讞 讛诪诪诇讻转讬.




诇诪讬 砖讞砖砖 砖讛驻注专 谞讜讘注 诪讻讱 砖讛讞讬谞讜讱 讛诪诪诇讻转讬 讻讜诇诇 讙诐 谞讘讞谞讬诐 诪诪讙讝专 注专讘讬, 讘讚讜讗讬 讜讚专讜讝讬. 讛转讜爪讗讜转 讻诪注讟 诇诇讗 砖讬谞讜讬 讙诐 讻砖讘讜讞专讬诐 讗转 讛诪讙讝专 讛讬讛讜讚讬 讘诇讘讚. 讻讱 诇诪砖诇, 讘砖谞转 2023, 诪诪讜爪注 讛驻讬拽讜讞 讛诪诪诇讻转讬 诇诪讙讝专 讛讬讛讜讚讬 讘诇讘讚 讛讜讗 82.9.




讛讗诐 讬砖 诇讻讱 拽砖专 诇转讬拽爪讜讘 讛砖讜谞讛 砖诇 转诇诪讬讚讬诐 讘讝专诪讬诐 讛砖讜谞讬诐? 专讗讜 转专砖讬诐 2 讘诪住诪讱 注诇 "谞转讜谞讬诐 注诇 注诇讜转 诪诪讜爪注转 诇驻讬 诪注诪讚 诪砖驻讟讬 讜驻讬拽讜讞" 诪讗转专 讛讻谞住转 讘讜 专讜讗讬诐 讘讘专讜专 砖注诇讜转 转诇诪讬讚 讘讞讬谞讜讱 讛诪诪诇讻转讬 讚转讬 讙讘讜讛讛 诪砖诪注讜转讬转 诪讬转专 讛转诇诪讬讚讬诐. 讗讘诇, 讘诪拽专讛 讝讛 诪讛 诇讙讘讬 转讜爪讗讜转 讛诪讙讝专 讛讞专讚讬 讜讛注专讘讬? 讛转专砖讬诐 讛讘讗 谞诇拽讞 诪讛诪住诪讱 讛谞"诇.

诪讛 诇讙讘讬 讛诪讙讝专 讛讞专讚讬? 讛诪诪讜爪注 砖诐 讘砖谞转 2023 讛讜讗 85.47, 诪专砖讬诐. 驻注专 砖诇 讬讜转专 诪谞拽讜讚讛 砖诇诪讛 诇注讜诪转 讛诪诪诇讻转讬 讚转讬. 砖诇讗 诇讚讘专 注诇 讝讬谞讜拽 诪专砖讬诐 讘砖谞讬诐 2016 讜2017 讘讛谉 讛讞讬谞讜讱 讛讞专讚讬 讛讜讘讬诇 注诇 讛诪诪诇讻转讬 讚转讬 讘驻注专 砖诇2.02 讜4.2 谞拽讜讚讜转, 讘讛转讗诪讛. 拽砖讛 诇讛转讬讬讞住 诇爪讬讜谞讬诐 砖诇 讛驻讬拽讜讞 讛讞专讚讬. 讻驻讬 砖专讜讗讬诐 讘讙专祝 讛讘讗, 诪住驻专 讛谞讘讞谞讬诐 讛讗讘住讜诇讜讟讬 讘诪转诪讟讬拽讛 讘驻讬拽讜讞 讝讛 谞诪讜讱 讜讗讞讜讝 讛讘讜讞专讬诐 讘5 讬讞讬讚讜转 讛讜讗 谞诪讜讱 讘讬讜转专. 讻砖诪住驻专 讛谞讘讞谞讬诐 诪爪讜诪爪诐, 注诇讜诇讛 诇讛讜讜爪专 转谞讜讚转讬讜转 诇讗 诪讜住讘专转 讘转讜爪讗讜转 讘讬谉 砖谞讬诐 砖讜谞讜转. 讛转诇讜转 讘讛爪诇讞讛 砖诇 讻诇 讗讞讚 诪讛转诇诪讬讚讬诐 砖讻谉 谞讬讙砖讬诐 讛讬讗 讙讚讜诇讛. 讘讙专祝 讛拽讜 砖诪注诇 专讜讗讬诐 讗转 讛转谞讜讚讜转 讘诪诪讜爪注 讛驻讬拽讜讞 讛讞专讚讬, 砖爪诇诇讜 诇注转讬诐. 诇诪砖诇 讘砖谞转 2017 诇注讜诪转 2018 (诪88.97 诇81.66).


讗诐 谞讘讞谉 讗转 讛讞诇讜拽讛 讘讬谉 讬讞讬讚讜转 讛诇讬诪讜讚 讘诪转诪讟讬拽讛, 诇驻讬 拽讘讜爪讜转 讛驻讬拽讜讞 讛砖讜谞讜转, 谞专讗讛 驻注专讬诐 诪砖诪注讜转讬讬诐. 讻讱 诇诪砖诇 讘砖谞转 2023 讛诪诪讜爪注 讘驻讬拽讜讞 讛讞专讚讬 讗诪谞诐 85.47 讗讘诇 讛讜讗 讛讜砖讙 注诇 讬讚讬 383 转诇诪讬讚讬 5 讬讞讬讚讜转 讘诇讘讚, 诇注讜诪转 2,922 讘诪诪诇讻转讬 讚转讬 讜15,779 讘讞讬谞讜讱 讛诪诪诇讻转讬. 讬砖 诇爪讬讬谉 砖讻诪讜转 谞讬讙砖讬诐 砖诇 383 讛讬讗 讝讬谞讜拽 讗讚讬专 诇注讜诪转 讻100 谞讘讞谞讬诐 讘5 讬讞讬讚讜转 讘砖谞讬诐 2020 - 2013.

讘讛转驻诇讙讜转 诇驻讬 讬讞讬讚讜转 诇讬诪讜讚 谞专讗讛 驻注专讬诐 讙讚讜诇讬诐. 讘驻讬拽讜讞 讛讞专讚讬 谞讬讙砖讜 讘2023 诇5 讬讞讬讚讜转 诪转讟讬拽讛 专拽 5.21% 诪诇讜诪讚讬 讛诪转诪讟讬拽讛, 诇注讜诪转 诪注诇 19% 讘诪诪诇讻转讬 讜诪诪诇讻转讬 讚转讬. 专讜讘 诪讜讞诇讟 砖诇 讻诪注讟 77% 诪讛讞专讚讬诐 谞讬讙砖 诇3 讬讞讬讚讜转 诇讬诪讜讚 讘诪转诪讟讬拽讛. 


谞转讜谞讬诐 诇驻讬 诪讙讝专 (讘讚讜讗讬 / 讚专讜讝讬 / 讬讛讜讚讬 / 注专讘讬)

讘诪诪讜爪注 诪转诪讟讬拽讛 5 讬讞讬讚讜转 诇驻讬 诪讙讝专 谞讬转谉 诇专讗讜转 砖转讬 拽讘讜爪讜转 诪讜讘讞谞讜转: 注专讘讬 & 讬讛讜讚讬 讘讛诐 驻注专讬诐 谞诪讜讻讬诐 诪讗讚 讘诪诪讜爪注 诇注讜诪转 讚专讜讝讬 讜讘讚讜讗讬 讘讛诐 讛诪诪讜爪注讬诐 谞诪讜讻讬诐 诪砖诪注讜转讬转 注诐 驻注专讬诐 砖诇 诪注诇 6 谞拽讜讚讜转 诇注讜诪转 讛注专讘讬 & 讬讛讜讚讬. 讝讛讜 驻注专 注爪讜诐. 
 

诇注讜诪转 讝讗转 讛讘讞讬专讛 讘诇讬诪讜讚讬 5 讬讞讬讚讜转 诪转诪讟讬拽讛 砖讜谞讛 诪讗讚 讘诪讙讝专讬诐 讛砖讜谞讬诐:

诇注讜诪转 讛诪讙讝专 讛讘讚讜讗讬, 讘讜 砖谞转 2023 专拽 2.31% 诪4,454 讛谞讘讞谞讬诐 讘诪转诪讟讬拽讛 谞讬讙砖讜 诇5 讬讞讬讚讜转, 讘诪讙讝专 讛讚专讜讝讬 诪注诇 17% 诪2,350 讛谞讘讞谞讬诐 讘诪转诪讟讬拽讛 谞讬讙砖讜 诇讘讙专讜转 5 讬讞讬讚讜转. 讗讞讜讝 讙讘讜讛 诪砖诪注讜转讬转 诪讝讛 砖讘诪讙讝专 讛注专讘讬 (12.2%) 讗讱 注讚讬讬谉 谞诪讜讱 诪讝讛 砖讘诪讙讝专 讛讬讛讜讚讬 讘讜 诪注诇 21% 谞讘讞谞讜 讘讘讙专讜转 5 讬讞讬讚讜转 讘诪转诪讟讬拽讛. 讻讱 谞讜爪专 驻注专 诪砖诪注讜转讬 砖诇 16,630 谞讘讞谞讬 5 讬讞讬讚讜转 讘诪讙讝专 讛讬讛讜讚讬, 诇注讜诪转 1,950 讘诇讘讚 讘诪讙讝专 讛注专讘讬.

讗讙讘, 诇讙讘讬 讛诪讙讝专 讛讚专讜讝讬, 讬砖 诇爪讬讬谉 诇讟讜讘讛 讗转 讘讬转 讛住驻专 讗讘讜-住诇讬诐 住诇诪讗谉 讗诇砖讬讬讱 诪讗讘讜 住谞讗谉 砖24 转诇诪讬讚讬讜 拽讬讘诇讜 诪诪讜爪注 89.08 讘诪转诪讟讬拽讛 5 讬讞讬讚讜转 讘2023, 讘讚讜诪讛 诇转讜爪讗讜转 砖讛讜砖讙讜 讘讜 讘砖谞讬诐 拽讜讚诪讜转.


谞转讜谞讬诐 诇驻讬 诪讞讜讝讜转 诪砖专讚 讛讞讬谞讜讱

讗诐 谞转讘讜谞谉 讘谞转讜谞讬 2023 (诪讘讞谞讬诐 砖讛转拽讬讬诪讜 讘拽讬抓 诇驻谞讬 驻专讜抓 讛诪诇讞诪讛) 诇驻讬 诪讞讜讝讜转 谞专讗讛 转诪讜谞转 诪爪讘 诪讚讗讬讙讛 讘诪讞讜讝讜转 讛爪驻讜谉 讜讛讚专讜诐. 讛转诪讜谞讛 诇讗 砖讜谞讛 诪讛讜转讬转 讘砖谞转 2022:


 

讜讗诐 讗转诐 讞讜砖讘讬诐 砖讛转诪拽讚讜转 讘诪讙讝专 讛讬讛讜讚讬 讘诇讘讚, 转砖驻专 讗转 讛转诪讜谞讛, 讟注讜转 讘讬讚讻诐:


讗谞讜 专讜讗讬诐 驻注专讬诐 讙讚讜诇讬诐 讘讬谉 诪讞讜讝 爪驻讜谉 讜讚专讜诐 诇讬转专 讛诪讞讜讝讜转.

讛诪讙诪讛 讛诪讚讗讬讙讛 诪砖转拽驻转 讙诐 讘讗讞讜讝 讛谞讬讙砖讬诐 诇5 讬讞讬讚讜转: 讘住讘讬讘讜转 25% 讘转诇 讗讘讬讘 讜讛诪专讻讝 诇注讜诪转 14.56% 讘爪驻讜谉 讜11.87% 讘讚专讜诐:



讘转讬 住驻专 诪爪讟讬讬谞讬诐

讻砖谞讬讙砖转讬 诇讘讞讜谉 讗转 讘转讬 讛住驻专 讛诪爪讟讬讬谞讬诐, 专爪讬转讬 诇专讗讜转 讛讗诐 讬砖 诇诪爪讘 讛住讜爪讬讜讗拽讜谞讜诪讬 砖诇 讛讬讬砖讜讘 讛砖驻注讛 注诇 讛爪讬讜谞讬诐. 注诇 讻谉 砖讬诇讘转讬 讗转 讛谞转讜谞讬诐 砖诇 讛讘讙专讜讬讜转 注诐 谞转讜谞讬 讛诇砖讻讛 讛诪专讻讝讬转 诇住讟讟讬住讟讬拽讛. 讘诪拽专讛 讝讛 注诐 谞转讜谞讬 2019 讘转讜专 驻砖专讛 讘讬谉 2013 讜2023. 讻讻诇 砖爪讘注 讛砖讜专讛 讻讛讛 讬讜转专, 讻讱 讟讜讘 讛诪爪讘 讛住讜爪讬讜讗拽讜谞讜诪讬 砖诇 讛讬讬砖讜讘.

讗诐 谞讘讞谉 讗转 讘转讬 讛住驻专 讛诪讜讘讬诇讬诐 讘砖谞转 2023 讘5 讬讞讬讚讜转 诇讬诪讜讚 讘诪转诪讟讬拽讛, 谞专讗讛 砖讞讜抓 诪讬砖讬讘转 注诪讬讗诇 讛讞专讚讬转 讘转诇 讗讘讬讘, 讬转专 讛诪讜讘讬诇讬诐 讘诪拽讜诪讜转 1-6 讛诐 诪驻讬拽讜讞 诪诪诇讻转讬 讚转讬. 专讜讘 讛诪讜讘讬诇讬诐 诪砖讻讘讛 住讜爪讬讜讗拽讜谞讜诪讬转 讙讘讜讛讛. 


讛讗诐 讛诪讜讘讬诇讬诐 讘砖谞转 2023 砖讜诪专讬诐 注诇 诪拽讜诪讜转 讙讘讜讛讬诐 讘注拽讘讬讜转?

住讬诪谞转讬 讗转 讛讚讬专讜讙 砖诇 讘讬转 讛住驻专 讘讻诇 砖谞讛 讘讬专讜拽, 讘诪讬讚讛 讜讛讬讜 讘50 讛专讗砖讜谞讬诐 讘讗讜转讛 砖谞讛. 讘专讜讘诐 讗谞讜 专讜讗讬诐 注拽讘讬讜转 诇讗讜专讱 讛砖谞讬诐 讛讗讞专讜谞讜转:


诪爪讘 讚讜诪讛 讛讬讛 讙诐 讘2022:


诪注谞讬讬谉 砖讛谞转讜谞讬诐 诇驻讬 注砖讜专 讛讬讜 砖讜谞讬诐 诪讗讚. 讗诐 谞爪讬抓 讘讚讬专讜讙 2013-2015 谞专讗讛 砖讛诪讜讘讬诇讬诐, 诇专讜讘, 讛讬讜 讘转讬 住驻专 注专讘讬讬诐 注诐 专拽注 住讜爪讬讜讗拽讜谞讜诪讬 诇讗 讙讘讜讛.

2013:


2014:


2015: (讗讜诇驻谞转 爪讘讬讛 诪讘谞讬 讘专拽 讝讬谞拽讛 诇诪拽讜诐 讛专讗砖讜谉)


2016: 


讛砖讬谞讜讬 讛讞诇 讘砖谞讬诐 2017-2018

2017:


2018:


讜诇住讬讜诐, 诪讬 讘转讬 讛住驻专 注诐 诪诪讜爪注 讛讚讬专讜讙 讛讙讘讜讛 讘讬讜转专 讘讻诇 讛砖谞讬诐 (2013-2023)? 7 诪注砖专转 讛专讗砖讜谞讬诐 讛诐 诪驻讬拽讜讞 诪诪诇讻转讬 讚转讬.

讗讜诇驻谞转 爪讘讬讛 讘谞讬 讘专拽 讛讬讗 讛诪谞爪讞转 讛讙讚讜诇讛:


讘讜讗讜 谞驻专拽 讗转 讝讛.

驻讬拽讜讞 讞专讚讬:

诇讘讙专讜转 2023 讘诪转诪讟讬拽讛 5 讬讞讬讚讜转 谞讬讙砖讜 转诇诪讬讚讬 13 诪讜住讚讜转 讞专讚讬讬诐 (诇讟讜讘转 讞讚讬 讛注讬谉 讘讬谞讬讻诐 讛讜住驻转讬 讗转 住诪诇 讛诪讜住讚, 讻讚讬 砖转专讗讜 砖讗讻谉 讬砖 讬讜转专 诪住诪讬谞专 讘讬转 讬注拽讘 讗讞讚 讘讬专讜砖诇讬诐): 


讘驻拽讜讞 讛讞专讚讬, 诪讜住讚讜转 讻诪讜

  • 讬砖讬讘转 讛专讘 注诪讬讗诇 诪转诇 讗讘讬讘 - 讬驻讜
  • 转讬讻讜谉 讘讬转 讬注拽讘 讘讬专讜砖诇讬诐
  • 讗讜诇驻谞转 讚专讻讬 谞讜注诐 讘驻转讞 转拽讜讜讛
  • 讬砖讬讘转 讚专讻讬 谞讜注诐 讘驻转讞 转拽讜讜讛

讜谞讜住驻讬诐

.砖讜诪专讬诐 砖谞讛 讗讞专 砖谞讛 注诇 专诪讛 讙讘讜讛讛 砖诇 讛砖讙讬诐 讘诪转诪讟讬拽讛 5 讬讞讬讚讜转 

 


驻讬拽讜讞 诪诪诇讻转讬 讚转讬:



讘驻讬拽讜讞 讛诪诪诇讻转讬 讚转讬, 诪讜住讚讜转 讻诪讜 

  • 讬砖讬讘转 讘谞"注 诇驻讬讚 讘诪讜讚注讬谉-诪讻讘讬诐 专注讜转 
  • 讗讜诇驻谞转 爪讘讬讛 讘谞讬 讘专拽 
  • 讬砖讬讘转 诪注专讘讗 讘诪讟讛 讘谞讬诪讬谉 
  • 讗诪讬"转 讘谞讬诐 诪讜讚讬注讬谉 
  • 讗讜诇驻谞讛 诇讘谞讜转 讘讙讘注转 砖诪讜讗诇 
  • 讬砖讬讘讛 转讬讻讜谞讬转 讞讬住驻讬谉 

讜谞讜住驻讬诐

砖讜诪专讬诐 砖谞讛 讗讞专 砖谞讛 注诇 专诪讛 讙讘讜讛讛 砖诇 讛讬砖讙讬诐 讘讘讙专讜转 诪转诪讟讬拽讛 5 讬讞讬讚讜转. 


驻讬拽讜讞 诪诪诇讻转讬 - 诪讙讝专 讬讛讜讚讬:


讘驻讬拽讜讞 讛诪诪诇讻转讬 - 讬讛讜讚讬 诪讜住讚讜转 讻诪讜 

  • 转讬讻讜谉 诇讬讚 讛讗讜谞讬讘专住讬讟讛 讬专讜砖诇讬诐
  • 转讬讻讜谉 注诇 砖诐 讬爪讞拽 专讘讬谉 讻驻专 住讘讗
  • 注转讬讚 诇诪讚注讬诐 诇讜讚
  • 诪讬转专讬诐 专注谞谞讛
  • 讞拽诇讗讬 讛讻驻专 讛讬专讜拽 专诪转 讛砖专讜谉
  • 转讬讻讜谉 注"砖 讬爪讞拽 讘谉 爪讘讬 拽专讬转 讗讜谞讜
  • 注诪诇 诇讬讬讚讬 讚讬讜讜讬住 转诇 讗讘讬讘
  • 注讬专讜谞讬 讚' 转诇 讗讘讬讘
  • 注讬专讜谞讬 讛' 转诇 讗讘讬讘
  • 注讬专讜谞讬 讬讚' 转诇 讗讘讬讘
  • 讘讬转 讞讬谞讜讱 注"砖 专讘讬谉 转诇 诪讜谞讚

讜谞讜住驻讬诐  

砖讜诪专讬诐 砖谞讛 讗讞专 砖谞讛 注诇 专诪讛 讙讘讜讛讛 砖诇 讛讬砖讙讬诐 讘讘讙专讜转 诪转诪讟讬拽讛 5 讬讞讬讚讜转. 


诪讙讝专 注专讘讬:


谞讬转谉 诇专讗讜转 讬专讬讚讛 讘住拽讗诇讛 砖诇 讛讚讬专讜讙 讛住讜爪讬讜讗拽讜谞讜诪讬.

讘诪讙讝专 讛注专讘讬 诪讜住讚讜转 讻诪讜

  • 谞讜讟专讚讗诐 诪注讬诇讬讗
  • 诪拽讬祝 诪讜砖专讬驻讛 诪注诇讛 注讬专讜谉
  • 诪拽讬祝 讗诇讘讟讜祝 注专讗讘讛
  • 讘讬转 住驻专 讗诇讘砖讗讗专 住讞谞讬谉
  • 诪拽讬祝 讻讗讜讻讘

讜谞讜住驻讬诐

砖讜诪专讬诐 砖谞讛 讗讞专 砖谞讛 注诇 专诪讛 讙讘讜讛讛 砖诇 讛讬砖讙讬诐 讘讘讙专讜转 诪转诪讟讬拽讛 5 讬讞讬讚讜转. 


诪讙讝专 讚专讜讝讬:


砖讬诪讜 诇讘 砖转讜讜讱 讛讚讬专讜讙 讛住讜爪讬讜讗拽讜谞讜诪讬 讛讜讗 3-5.

讘诪讙讝专 讛讚专讜讝讬 讗爪讬讬谉 讗转 讘讬转 讛住驻专 讗讘讜-住诇讬诐 住讗诇诪谉 讗诇砖讬讬讱 诪讗讘讜 住谞讗谉 讛砖讜诪专 砖谞讛 讗讞专 砖谞讛 注诇 专诪讛 讙讘讜讛讛 砖诇 讛讬砖讙讬诐 讘讘讙专讜转 诪转诪讟讬拽讛 5 讬讞讬讚讜转. 


诪讙讝专 讘讚讜讗讬:


砖讬诪讜 诇讘 砖转讜讜讱 讛讚讬专讜讙 讛住讜爪讬讜讗拽讜谞讜诪讬 讛讜讗 1-3!

讘诪讙讝专 讛讘讚讜讗讬 讗爪讬讬谉 讗转 诪拽讬祝 讘讜注讬讬谞讛 谞讜讙'讬讚讗转 讛砖讜诪专 砖谞讛 讗讞专 砖谞讛 注诇 专诪讛 讙讘讜讛讛 砖诇 讛讬砖讙讬诐 讘讘讙专讜转 诪转诪讟讬拽讛 5 讬讞讬讚讜转. 





讜讗诐 诪讜转专 讛注专讛 谞讜住驻转. 专砖讜转 讛讞讬谞讜讱 砖诇 诪讜讚注讬谉-诪讻讘讬诐-专注讜转, 讗谞讬 诪住讬专 讘驻谞讬讻诐 讗转 讛讻讜讘注:





Monday, May 26, 2025

Custom exceptions UI in OAC/OAS table

 Sometimes we want to create an exceptions UI that is beyond the regular options of the tool.

Specifically, something like this:

Let's see what was created by default and what is a customization...

To create the square near the "% profit" I used the standard Conditional Formatting: 



Added an icon:
Add a note (you see it at the top right of the first image, only for the first line):

Since in the previous screen "Show rule condition" is marked, the Legend appears as well:


Now what about the extra column with the red and green squares? 
Since I don't have this visualization built-in, I created a dynamic column, with the following calculation:

case 
when @calculation("profit") < 0.1 then '馃煡馃煡馃煡馃煡馃煡馃煡馃煡馃煡馃煡馃煡' 
when @calculation("profit") < 0.2 then '馃煡馃煡馃煡馃煡馃煡馃煡馃煡馃煡馃煡馃煩' 
when @calculation("profit") < 0.3 then '馃煡馃煡馃煡馃煡馃煡馃煡馃煡馃煡馃煩馃煩' 
when @calculation("profit") < 0.4 then '馃煡馃煡馃煡馃煡馃煡馃煡馃煡馃煩馃煩馃煩' 
when @calculation("profit") < 0.5 then '馃煡馃煡馃煡馃煡馃煡馃煡馃煩馃煩馃煩馃煩' 
when @calculation("profit") < 0.6 then '馃煡馃煡馃煡馃煡馃煡馃煩馃煩馃煩馃煩馃煩' 
when @calculation("profit") < 0.7 then '馃煡馃煡馃煡馃煡馃煩馃煩馃煩馃煩馃煩馃煩' 
when @calculation("profit") < 0.8 then '馃煡馃煡馃煡馃煩馃煩馃煩馃煩馃煩馃煩馃煩' 
when @calculation("profit") < 0.9 then '馃煡馃煡馃煩馃煩馃煩馃煩馃煩馃煩馃煩馃煩' 
when @calculation("profit") < 1.0 then '馃煡馃煩馃煩馃煩馃煩馃煩馃煩馃煩馃煩馃煩' 
else '馃煩馃煩馃煩馃煩馃煩馃煩馃煩馃煩馃煩馃煩'  end


How does it work? The red square and many others are valid characters... I only use them. See examples here:

https://unicodeplus.com/U+1F7E5

or here:

https://www.compart.com/en/unicode/U+1F7E9

The remaining problem is the Oracle Analytics automatic column width. The above-mentioned squares need more space than regular character. 

As a "quick and dirty" work around I forced a longer column title:


You can always use "hard space" to force the longer header. Like this: "            The percent of profit"

Copy/Paste from the blog wouldn't work here, but you can always create a hard space by holding the "ALT" key and pressing 255. 


The same calculation works here as well (Watchlist UI):

 



Useful examples:

Orange Circle 1F7E0 - 馃煚

Yellow Circle 1F7E1 - 馃煛

Green Circle 1F7E2 -  馃煝

Purple Circle 1F7E3 - 馃煟

Brown Circle 1F7E4 - 馃煠


Red Sq. 1F7E5 -         馃煡

Blue Sq. 1F7E6 -        馃煢

Orange Sq. 1F7E7 -    馃煣

Yellow Sq. 1F7E8 -    馃煥

Green Sq. 1F7E9 -     馃煩

Purple Sq. 1F7EA -    馃煪

Brown Sq. 1F7EB  -  馃煫 


Blue Heart 1F499 - 馃挋

Green Heart 1F49A - 馃挌

Yellow Heart 1F49B - 馃挍

Purple Heart 1F49C - 馃挏

Heart Decor 1F49F - 馃挓


White star 2B50 - 

Manual W-Chair 1F9BD - 馃    267F - 

Nine Branches 1F54E - 馃晭