Oracle Applications - How to get the value of zd_edition_name - oracle

In Oracle Applications 12c release 1 there is a new column that forms part of many primary keys called zd_edition_name. This relates to editions that you can have for keeping the database up during changes. So you would have two editions, you can make changes to the non-live on and then just live swap over when you are done (my limited understanding - I am not a dba).
My questions is how can I get the value of zd_edition_name, since this is now part of the primary key and also because tables like fnd_descr_flex_col_usage_tl would bring back two rows instead of one if you don't pass the value of zd_edition_name.
Also what does the zd stand for?

EBS and Edition Base Redefinition and Online Patching
The column, zd_edition_name, is just a component of the edition based redefinition feature of an Oracle 11G 2 (or greater) database as you have indicated.
Oracle Applications does not leverage this edition based redefinition database feature until 12.2 EBS.
The apps owned synonym will display the run time value, SET1 or SET2. It will be one value. For EBS 12.1, I would expect the run time value to be SET1.
APPS#db> select
2 zd_edition_name
3 from
4 fnd_descr_flex_col_usage_tl
5 group by zd_edition_name;
ZD_EDITION_NAME
SET1
With the editionable view and the table, we do not have that restriction:
APPS#db>SELECT
2 zd_edition_name
3 FROM
4 applsys.fnd_descr_flex_col_usage_tl
5 GROUP BY
6 zd_edition_name;
ZD_EDITION_NAME
SET2
SET1
In EBS 12.2, one could identify the active file system which should have a correspondence with SET1/SET2 through logging in to the Oracle Apps server(s) and echoing the environment variables:
$FILE_EDITION = patch
$RUN_BASE = /u01/R122_EBS/fs1
$PATCH_BASE = /u01/R122_EBS/fs2
By querying the apps owned synonym, this is unnecessary to know the value of ZD_EDITION_NAME (it is a value associated with the run edition which will be the value).
You can view the editionable objects associated with table with a query like this:
APPS#db>VAR b_object_name varchar2(30);
APPS#db>EXEC :b_object_name:= 'FND_DESCR_FLEX_COL_USAGE_TL';
PL/SQL procedure successfully completed.
APPS#db>SELECT
2 ao.owner,
3 ao.object_name,
4 ao.object_type
5 FROM
6 all_objects ao
7 WHERE
8 1 = 1
9 AND owner IN (
10 'APPS',
11 'APPLSYS'
12 )
13 AND ao.object_name IN (
14 :b_object_name,
15 substr(:b_object_name,1,29)
16 || '#'
17 );
OWNER OBJECT_NAME OBJECT_TYPE
APPLSYS FND_DESCR_FLEX_COL_USAGE_TL TABLE
APPLSYS FND_DESCR_FLEX_COL_USAGE_TL# VIEW
APPS FND_DESCR_FLEX_COL_USAGE_TL SYNONYM
Here are list of versions existing in an EBS instance:
APPS#db>SELECT
2 level,
3 de.edition_name,
4 de.parent_edition_name
5 FROM
6 dba_editions de
7 START WITH
8 de.edition_name = 'ORA$BASE'
9 CONNECT BY
10 PRIOR de.edition_name = de.parent_edition_name
11 ORDER BY
12 de.edition_name;
LEVEL EDITION_NAME PARENT_EDITION_NAME
1 ORA$BASE
2 V_20160703_2120 ORA$BASE
3 V_20160708_1723 V_20160703_2120
...
29 V_20180117_1118 V_20171206_1115
30 V_20180130_0107 V_20180117_1118
For an 12.1 EBS environment, I would expect the starting edition, ORA$BASE, to be the only edition.

Related

Cross lookup in oracle without creating a table

I have a list of 20 records mapping year to a number from 2001 to 2021. For a couple of reasons these can not be loaded into a table, and I do not have permissions to create temporary tables. This lookup means I can't just run a single query in oracle - I have to export and join with a script. Is there a way I could just do a lookup in memory? I could do a CASE WHEN statement to handle each of the 20 cases. But is there some other smoother way to check values against a list in Oracle when you can't write to a table in between?
If I understood you correctly, a CTE might help:
SQL> with years as
2 (select 2000 + level as year
3 from dual
4 connect by level <= 21
5 )
6 select year
7 from years
8 /
YEAR
----------
2001
2002
2003
2004
<snip>
2020
2021
21 rows selected.
SQL>
You'd now join years with other tables, e.g.
with years as
...
select y.year, e.hiredate
from years y join employees e on e.year = y.year
where ...

Checksum in Oracle PL/SQL

Do we have similar kind of checksum function (SQL) in oracle function. I would to store it in a table and use key/value for update statements. One of my current process contains 15 columns, need to check any change is there between source and destination, instead of checking one by one column whether change is happened or not, would like to have single column in table to helps whether change happened in 15 columns
Databases are good at keeping track of changes, that's what they are for.
Maybe the built-in ORA_ROWSCN is good enough for your change tracking? By default it tracks only the changes per block, but you can enable a table to track the change for each row with the - oddly named - clause ROWDEPENDENCIES:
CREATE TABLE t (
a NUMBER,
b NUMBER,
c NUMBER
) ROWDEPENDENCIES;
INSERT INTO t VALUES (1,1,1);
INSERT INTO t VALUES (2,2,2);
SELECT current_scn FROM v$database;
2380496
After a while:
UPDATE t SET b=20, c=20 WHERE a=2;
SELECT current_scn FROM v$database;
2380665
Now you can query the system change number SCN each row was changed:
SELECT ORA_ROWSCN AS scn, a,b,c FROM t;
SCN A B C
2380496 1 1 1
2380665 2 20 20
For the last 5 days, Oracle can translate a SCN to approximate real time (in Oracle 10 ± 5 minutes, from Oracle 11 ± 3 seconds):
SELECT ORA_ROWSCN AS SCN, SCN_TO_TIMESTAMP(ORA_ROWSCN) AS ts, a,b,c FROM t;
SCN TS A B C
2380496 2020-05-15 20:20:38 1 1 1
2380665 2020-05-15 20:23:06 2 20 20
It's documented in Oracles SQL Language Reference.

Oracle SQL: Extracting rows data into multiple columns using SQL

I have one scenario where data are in table as follows:
Ser_num File_name
1 DBA OBJECT~ALL_OBJECT
2 ./outfile_26094843.txt
3 ./outfile_26094844.txt
4 ./DataFile.txt
5 DBA OBJECT~AP_INVOICES_ALL
6 ./XXFA_GL_ICOMP_JOURNAL.rdf
7 ./outfile_26094844.txt
I have to extract data as follow
ALL_OBJECT
outfile_26094843.txt
outfile_26094844.txt
DataFile.txt
AP_INVOICES_ALL
XXFA_GL_ICOMP_JOURNAL.rdf
outfile_26094844.txt
please advise me SQL for this.

How can I get several oracle rows into one?

In this oracle situation, how can I get the following results in a single query?
Table 1
Customer | Order_Number
1 1
1 2
2 1
Table 2
Customer | Order_Number | Employee | Tag
1 1 Bob on hold
1 1 Larry shipped
1 2 Larry shipped
Results
Customer | Order_Number | Tags
1 1 Bob - on hold; Larry - shipped
1 2 Larry - shipped;
2 1 (Empty or null)
I'm getting tripped up on returning the tags as a single string.
You have not mentioned your DB version. So the answer would completely depend on which version are you on.
If you are on 11g and up, use LISTAGG.
However, if you are on pre 11g release, then you have the following options :
ROW_NUMBER() and SYS_CONNECT_BY_PATH functions in Oracle 9i
COLLECT function in Oracle 10g
STRAGG function suggested by Tom Kyte here http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2196162600402
Note : Never use WM_CONCAT in production system, it is undocumented. Just raise a SR to Oracle support and say you used it, and see the response. And it doesn't exist in 12c.
More examples here http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php
You're in need of LISTAGG.
If your Oracle version is old enough, it can be replaced with user-defined aggregate function, WM_CONCAT or SYS_CONNECT_BY_PATH.

ORACLE PL/Scope

I didn't find much data about the internals of PL/Scope.
I'd like to use it to analyze identifiers in PL/SQL scripts. Does it work only on Oracle 11g instances? Can I reference its dlls to use it on a machine with only ORACLE 9/10 installed?
In a related manner, do I have to execute the script in order for its identifiers to be analyzed?
To answer the easy question first, we do not have to execute the program unit. We have to compile it. That is relatively simple:
SQL> alter session set plscope_settings='IDENTIFIERS:ALL'
2 /
Session altered.
SQL> alter function str_to_number_tokens compile
2 /
Function altered.
SQL> SELECT LPAD(' ', level*2, ' ') || name AS name, type, usage, usage_id, line, col
2 FROM user_identifiers
3 START WITH usage_context_id = 0
4 CONNECT BY PRIOR usage_id = usage_context_id;
NAME TYPE USAGE USAGE_ID LINE COL
------------------------------ ------------------ ----------- ---------- ---------- ----------
STR_TO_NUMBER_TOKENS FUNCTION DECLARATION 1 1 10
STR_TO_NUMBER_TOKENS FUNCTION DEFINITION 2 1 10
P_STRING FORMAL IN DECLARATION 3 2 10
P_SEPARATOR FORMAL IN DECLARATION 4 3 13
P_SEPARATOR FORMAL IN ASSIGNMENT 5 3 13
RETURN_VALUE VARIABLE DECLARATION 6 6 5
REGEX_STR VARIABLE DECLARATION 7 7 5
REGEX_STR VARIABLE ASSIGNMENT 8 10 9
P_SEPARATOR FORMAL IN REFERENCE 9 10 31
REGEX_STR VARIABLE REFERENCE 10 17 46
P_STRING FORMAL IN REFERENCE 11 17 36
REGEX_STR VARIABLE REFERENCE 12 16 47
P_STRING FORMAL IN REFERENCE 13 16 37
REGEX_STR VARIABLE REFERENCE 14 12 57
P_STRING FORMAL IN REFERENCE 15 12 47
RETURN_VALUE VARIABLE ASSIGNMENT 16 14 22
RETURN_VALUE VARIABLE REFERENCE 17 19 16
17 rows selected.
SQL>
(Credit where credit is due, I took that query from my mate Tim Hall's Oracle-Base site)
Incidentally, note that PL/Scope operates on named PL/SQL programs (procedures, functions, packages, etc). It doesn't work on anonymous PL/SQL blocks. I mention this because you talk of "scripts" rather than programs. It won't do anything with a SQL script containing some PL/SQL blocks.
The other thing to bear in mind is that PL/Scope populates tables on the SYSAUX tablespace, and can chew up a lot of storage. That's why it isn't run by default, and it's why we should use it judiciously.
As for backwards compatibility: it is a new feature in 11g, and it is a compiler feature at that. So I doubt whether it is something you could just crowbar into a 10g install.
Won't work on 10g, but you can copy the code to a scratch environment for analysis
You could get an OTN edition of 11g and copy the code in there just for the analysis.
If you think it would get classed as production use, you can get Personal Edition on Windows for a few hundred dollars

Resources