Oracle APEX automatic column add/remove in region - oracle

I have made a view that changes it's columns frequently with dynamic SQL. I use a pivot to make rows into columns. I display the view in an interactive grid. The SQL query that is executed:
select * from <DB>.<VIEWNAME>.
On refresh it updates the ROWS in the grid, but not the COLUMNS. The select * does not take column changes into account, BUT if I alter the SQL query by adding a space ( or any other thing in the query) and then saving the page in the page designer, the columns sync up to the view.
Does someone know a good solution to my problem? Where can I find the procedure that executes this refresh? If I know where it is I can possiby use it after the insertion of a column (or delete / update). Any tips? Warning, I am a total novice in oracle apex and sql developer.
Thanks in advance!

This is the wrong way to go about this. In Apex, and in Oracle in general, columns are determined when the query is parsed. If you change the underlying structure, your query has to be reparsed and only then do the columns change.
Think about it. If the first column in your result set was a DATE and you had your Apex column attributes set up to format and display that data, then your query changed to a NUMBER, its not clear what would happen.
What you probably want to do is create your region based on a function that returns a sql query as a VARCHAR2. (I think you can do this in 18.x; I'm still mostly using 5.2.) Your function gets parsed when the region is displayed. You can even use another function to return a colon-separated list of column headers if the names are dynamic.

Related

ORACLE APEX / SQL DEVELOPER: Cannot get PK to autoincrement

I am trying to implement my SQLDeveloper DB into Oracle APEX. I cannot figure out how to get the PK's in my table to auto-increment starting from a certain value (i.e. 400001). I have tried making triggers and sequences but when I try to add a row using a form in APEX, my PK increments from 40 for some reason.
Here is my APEX form outcome
enter image description here
Here is how it inserts into SQL Developer
enter image description here
Basically, can someone describe to me how I can edit the existing trigger, or create a sequence, that would make application_id of a new entry auto-increment by 1.
Thanks!
Find max application_id:
select max(application_id) From your_Table;
Suppose it is 400010 (as screenshot suggests). Now recreate the sequence (presuming its name is seq_app):
drop sequence seq_app;
create sequence seq_app start with 400011 increment by 1 nocache;
Trigger is most probably OK, as you see values being inserted into the table.
Side note: sequences will be unique, but not necessarily gapless. CACHE (or NOCACHE) might affect that, but - for performance sake, you'd rather let Oracle cache sequence numbers (default is 20) which means that - if you don't use some of those cached numbers, they will be lost. I wouldn't worry, if I were you.

Updating Resultset that points to an Oracle view

Is it possible to do updates via Resultset to an Oracle view? Asking as my code is giving me insufficient priviledge error when it does the rs.updateRow() call. I have checked and I definitely have access to the table/view.
The code looks like:
white (rs.next()) {
int updateStatus = getPSCforAction(status);
rs.updateInt("SPSC", updateStatus);
rs.updateRow;
}
The SELECT statement changes depends on operation but it will always be querying an Oracle view (and in some cases multiple views). My main question is whether updating via resultSet can be done to an Oracle view (or views)?
To answer your question one must see a definition of you view and a SELECT statament that is used to produce the resulset in your Java code. Without looking at this it is hard to give the answer
Anyway, generar rules and limitations are described in the Oracle Database JDBC Developer's guide:
Result Set Limitations
The following limitations are placed on queries for enhanced result
sets. Failure to follow these guidelines results in the JDBC driver
choosing an alternative result set type or concurrency type.
To produce an updatable result set:
A query can select from only a single table and cannot contain any
join operations.
In addition, for inserts to be feasible, the query must select all
non-nullable columns and all columns that do not have a default value.
A query cannot use SELECT * . However, there is a workaround for this.
A query must select table columns only.
It cannot select derived columns or aggregates, such as the SUM or MAX
of a set of columns.
To produce a scroll-sensitive result set:
A query cannot use SELECT *. However, there is a workaround for this.
A query can select from only a single table.
Scrollable and updatable result sets cannot have any column as Stream.
When the server has to fetch a Stream column, it reduces the fetch
size to one and blocks all columns following the Stream column until
the Stream column is read. As a result, columns cannot be fetched in
bulk and scrolled through.
They vaguely write that:
A query can select from only a single table and cannot contain any
join operations.
Could be that they mean "exlusively from tables, but not views", but also they could mean: "from tables and views", nobody knows, one must test this.
Another possible problem - your view may not be updatable, that is it doesn't conform to the following rules:
Notes on Updatable Views The following notes apply to updatable views:
An updatable view is one you can use to insert, update, or delete base
table rows. You can create a view to be inherently updatable, or you
can create an INSTEAD OF trigger on any view to make it updatable.
To learn whether and in what ways the columns of an inherently
updatable view can be modified, query the USER_UPDATABLE_COLUMNS data
dictionary view. The information displayed by this view is meaningful
only for inherently updatable views. For a view to be inherently
updatable, the following conditions must be met:
Each column in the view must map to a column of a single table. For
example, if a view column maps to the output of a TABLE clause (an
unnested collection), then the view is not inherently updatable.
The view must not contain any of the following constructs:
A set operator
A DISTINCT operator
An aggregate or analytic function
A GROUP BY, ORDER BY, MODEL, CONNECT BY, or START WITH clause
A collection expression in a SELECT list
A subquery in a SELECT list
A subquery designated WITH READ ONLY Joins, with some exceptions, as
documented in Oracle Database Administrator's Guide
In addition, if an
inherently updatable view contains pseudocolumns or expressions, then
you cannot update base table rows with an UPDATE statement that refers
to any of these pseudocolumns or expressions.
If you want a join view to be updatable, then all of the following
conditions must be true:
The DML statement must affect only one table underlying the join.
For an INSERT statement, the view must not be created WITH CHECK
OPTION, and all columns into which values are inserted must come from
a key-preserved table. A key-preserved table is one for which every
primary key or unique key value in the base table is also unique in
the join view.
For an UPDATE statement, the view must not be created WITH CHECK
OPTION, and all columns updated must be extracted from a key-preserved
table.
For a DELETE statement, if the join results in more than one
key-preserved table, then Oracle Database deletes from the first table
named in the FROM clause, whether or not the view was created WITH
CHECK OPTION.

Delphi XE7 TFDTable View RowID error

I'm converting a Delphi 5 / BDE application to Delphi XE7 / FireDAC. One of my forms has a TFDTable component that points to an Oracle view containing a group by clause in its create statement.
This used to work fine in the BDE application, but with FireDAC I'm getting this error.
ORA-01446: cannot select ROWID from, or sample, a view with DISTINCT,
GROUP BY, etc.
I understand the error I'm getting from Oracle, but I'm not selecting ROWID, FireDAC is! Is there a property in the TFDTable that I can set to prevent it from adding ROWID to the query? If not, how am I supposed to use this view?
FireDAC fetches ROWID because it tries to identify tuples in the resultset for possible updates. For stopping that just enable the ReadOnly option which will properly make the grouped view resultset read only (properly as one cannot just identify particular tuples if they are grouped in a resultset for updating).
The SQL command is generated in TFDPhysCommandGenerator.GenerateSelectTable method, if you wanted to know the source of this problem. There is appended generic unique tuple identifier to the select list according to the ReadOnly property setting (which is ROWID for Oracle DBMS).
Include fiMeta in FetchOptions.Items.
TFDQuery, TFDTable, TFDMemTable, and TFDCommand automatically retrieve
the unique identifying columns (mkPrimaryKeyFields) for the main
(first) table in the SELECT ... FROM ... statements, when fiMeta is
included in FetchOptions.Items. Note:
mkPrimaryKeyFields querying may be time consuming;
the application may need to explicitly specify unique identifying columns, when FireDAC fails to determine them correctly.
To explicitly specify columns, exclude fiMeta from FetchOptions.Items,
and use one of the following options:
set UpdateOptions.KeyFields to a ';' separated list of column names;
include pfInKey into the corresponding TField.ProviderFlags property.
When the application creates persistent fields, then initially
TField.ProviderFlags will be set correctly. After that, automatic
field setup will not happen, when the DB structure or query is
changed. You should manually update ProviderFlags to adjust the column
list. Also, if the primary key consists of several fields, then all of
them must be included into persistent fields. Row Identifying Columns
Alternatively, a row identifying column may be included into the
SELECT list. When FireDAC founds such columns, it will not retrieve
mkPrimaryKeyFields metadata and it will use this column. The supported
DBMSs are the following:
DBMS Row identifying column
Firebird DB_KEY
Informix ROWID
Interbase DB_KEY / RDB$DB_KEY
Oracle ROWID
PostgreSQL OID. The table must be created with OIDs.
SQLite ROWID
Source : http://docwiki.embarcadero.com/RADStudio/XE8/en/Unique_Identifying_Fields_%28FireDAC%29

T-SQL: UPDATE perfomance in case if some column values are the same

Suppose I want to perform an UPDATE of the object stored as a row in SQL Server 2012, and some of the column values are different, but most of them are the same. Question is simple - will Sql Server perform hard disk write only of the changed columns, or it will write the entire row, uselessly rewriting existing column values with just the same? And what if the object is kept in DB spread over many tables (complex object)?
I should I rephrase my question - Is perfomance hit of doing non updating UPDATEs of some columns when updating the row worth even worrying it?
BTW I use id column as clustered key.

How can I tell if a Materialized View in Oracle is being used?

We have some Materialized views in our Oracle 9i database that were created a long time ago, by a guy no longer working here. Is there an easy (or any) method to determine whether Oracle is using these views to serve queries? If they aren't being used any more, we'd like to get rid of them. But we don't want to discover after the fact that those views are the things that allow some random report to run in less than a few hours. The answer I'm dreaming of would be something like
SELECT last_used_date FROM dba_magic
WHERE materialized_view_name = 'peters_mview'
Even more awesome would be something that could tell me what actual SQL queries were using the materialized view. I realize I may have to settle for less.
If there is a solution that requires 10g, we are upgrading soon, so those answers would be useful also.
Oracle auditing can tell you this once configured as per the docs. Once configured, enable it by "AUDIT SELECT ON {name of materialized view}". The audit trail will be in the AUD$ table in the SYS schema.
One method other than auditing would be to read the v$segment_statistics view after one refresh and before the next refresh to see if there have been any reads. You'd have to account for any automatic statistics collection jobs also.
V$SQLAREA table has two columns which help identify the queries executed by the database.
SQL_TEXT - VARCHAR2(1000) - First thousand characters of the SQL text for the current cursor
SQL_FULLTEXT - CLOB - All characters of the SQL text for the current cursor
We can use this columns to find the queries using the said materialized views

Resources