DBMS_APPLICATION_INFO.SET_CLIENT_INFO not working - oracle

I need to set the client_info value to differentiate between different clients.
These are the scripts that I am running to test.
Step 1:SYS SCHEMA
ALTER SYSTEM FLUSH SHARED_POOL;
ALTER SYSTEM FLUSH BUFFER_CACHE;
Step 2:HR SCHEMA
EXEC DBMS_APPLICATION_INFO.SET_CLIENT_INFO(UTL_INADDR.GET_HOST_NAME );
EXEC DBMS_APPLICATION_INFO.SET_MODULE( 'CHECK','select' );
select
a.FIRST_NAME || ' ' || LAST_NAME AS FULL_NAME
from
HR.EMPLOYEES a
where
a.DEPARTMENT_ID = '40'
;
Step 3:SYS SCHEMA
select
*
from
(
select
a.SQL_ID
,a.SQL_FULLTEXT
,to_char( a.LAST_ACTIVE_TIME,'DD-MON-YYYY HH24:MI:SS' ) as LAST_ACTIVE_TIME
,a.SERVICE
,b.SCHEMANAME
,b.CLIENT_INFO
,a.MODULE
,a.ACTION
from
GV$SQL a
left outer join GV$SESSION b
on
(
b.SQL_ID = a.SQL_ID
)
where
a.EXECUTIONS != 0
)
c
where
c.MODULE like '%CHECK%'
order by
c.LAST_ACTIVE_TIME desc ;
The MODULE and ACTION columns are getting the values but the CLIENT_INFO is not showing anything.
Is there anything I am missing?
Update:
I have also tried with no luck
EXEC DBMS_APPLICATION_INFO.SET_CLIENT_INFO( SYS_CONTEXT('userenv','ip_address') );
EXEC DBMS_APPLICATION_INFO.SET_CLIENT_INFO( '10.10.10.10' );

SET_CLIENT_INFO is related to a Session, not to a single SQL Statement.
DO THIS
Step 1:SYS SCHEMA
ALTER SYSTEM FLUSH SHARED_POOL;
ALTER SYSTEM FLUSH BUFFER_CACHE;
Step 2:HR SCHEMA
EXEC DBMS_APPLICATION_INFO.SET_CLIENT_INFO(UTL_INADDR.GET_HOST_NAME );
EXEC DBMS_APPLICATION_INFO.SET_MODULE( 'CHECK','select' );
Step 3:SYS SCHEMA
SELECT
a.SQL_ID
,a.CLIENT_INFO
,a.MODULE
,a.ACTION
,a.SCHEMANAME
,a.USERNAME
FROM
V$SESSION a
WHERE
a.MODULE = 'CHECK';

Related

How to modify column data-type while column is in used

I have problem while I use SELECT query. Unfortunettly, the ID is store as VARCHAR which is big mistake and right now I have problem in following function
FUNCTION GET_SUB_PROJECTS(p_currentUserId IN VARCHAR,p_projectId IN INT)
RETURN SYS_REFCURSOR IS
rc SYS_REFCURSOR;
-- getSubProject
BEGIN
OPEN rc FOR
SELECT
p.*,
a.number_ AS activityNumber,
a.description AS activityDescription
FROM
projects p
LEFT JOIN
project_users_schedule_dates pusd
ON
pusd.ProjectID = p.ProjectID AND pusd.UserID = p_currentUserId
LEFT JOIN
activities a
ON
a.id = p.activity
LEFT JOIN
responsible_persons rp
ON
rp.ProjectID = p.ProjectID AND rp.UserID = p_currentUserId
LEFT JOIN
users u
ON
u.UserID = p_currentUserId
WHERE
(u.User_roleID = 1 AND
p.CustomName LIKE CONCAT((SELECT CustomName FROM projects pr WHERE pr.ProjectID = p_projectId), '%') AND p.ProjectID <> p_projectId)
OR
((
(p.Responsible_person_id = p_currentUserId OR p.Delivery_contact = p_currentUserId OR rp.UserID = p_currentUserId OR (pusd.UserID = p_currentUserId AND SYSTIMESTAMP BETWEEN TO_DATE(pusd.StartDate,'YYYY-MM-DD') AND TO_DATE(pusd.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY AND
SYSTIMESTAMP BETWEEN TO_DATE(p.StartDate,'YYYY-MM-DD') AND TO_DATE(p.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY))
)
AND
p.CustomName LIKE CONCAT((SELECT CustomName FROM projects pr WHERE pr.ProjectID = p_projectId), '%') AND p.ProjectID <> p_projectId)
ORDER BY p.CustomName;
RETURN rc;
END GET_SUB_PROJECTS;
When I call function it needs to return data, but it doesn't. Somehow, here p.Responsible_person_id and p.Delivery_contact needs to be NUMBER but somehow it is VARCHAR
When I call function I use
SELECT PROJECT_PACKAGE.GET_SUB_PROJECTS('199',141) FROM DUAL
I found one solution to modify but It throw me error like
Error report -
ORA-01439: column to be modified must be empty to change datatype
01439. 00000 - "column to be modified must be empty to change datatype"
What to do in this situation ? What is the best method to solve this issue ?
You can change the data type of a column online using dbms_redefinition
create table t (
c1 varchar2(10)
primary key
);
create table t_new (
c1 number(10, 0)
primary key
);
insert into t values ( '1.0000' );
commit;
begin
dbms_redefinition.start_redef_table (
user, 't', 't_new',
col_mapping => 'to_number ( c1 ) c1',
options_flag => dbms_redefinition.cons_use_rowid
);
end;
/
exec dbms_redefinition.sync_interim_table ( user, 't', 't_new' );
exec dbms_redefinition.finish_redef_table ( user, 't', 't_new' );
desc t
Name Null? Type
C1 NOT NULL NUMBER(10)
select * from t;
C1
1
There are also options to copy constraints, triggers, indexes, etc. automatically in this process.

How to extract ddl for oracle db links?

Is there anyway to extract ddl for all database links?
I would like to get in sql and recreate them via sql.
I can use below and it works for PUBLIC user but for non public user it doesn't give me db link owner.
Set long 1000
SELECT DBMS_METADATA.GET_DDL('DB_LINK',db.db_link,db.owner) from dba_db_links db;
Sample link owner and name
Owner db_link
public link1
public link2
user1 link3
If I ran above select it will give me below, #3 doesn't have username in it.
Output from above SELECT
1. create public database link "link1" using "db_alias"
2. create public database link "link2" using "db_alias"
3. create database link "link3" using "db_alias"
I recreate links using SYS and don't want to create #3 as SYS user.
Seems that even as SYS user you can't easity create dblink for another user (except of public dblink).
Even if you run create database link your_user.link3 using "db_alias" it's owner will be SYS.
Possible hacks are connect as another user (you may add conn into SQL*Plus script if you have credentials)
Or create procedure for user that need to have dblink that run create database link command with parameters and call it from sys.
this should help with links that do a "connect to"
SELECT MYCOMMAND
FROM
(
select trim(l.owner)||'__'||trim(l.db_link)||'__'||trim(l.username) ||'__'||trim(l.host) , '10'
, ' connect '||trim(l.owner)||'/CCCCCCCC#'||TRIM(INSTANCE_NAME)
AS MYCOMMAND
from dba_db_links l , V$INSTANCE i , dba_users u
where l.username = u.username
and l.username is not null
and l.username <> ' '
UNION ALL
select trim(l.owner)||'__'||trim(l.db_link)||'__'||trim(l.username)||'__'||trim(l.host) , '20'
, ' DROP DATABASE LINK '||trim(l.db_link)||' ; ' AS MYCOMMAND
from dba_db_links l , V$INSTANCE i , dba_users u
where l.username = u.username
and l.username is not null
and l.username <> ' '
UNION ALL
select trim(l.owner)||'__'||trim(l.db_link)||'__'||trim(l.username)||'__'||trim(l.host) , '30'
, ' CREATE DATABASE LINK '||trim(l.db_link)
||' CONNECT TO "'||trim(l.username)||'"'
||' IDENTIFIED BY "NNNNNNNN" '
||' USING '||trim(l.host) ||' ; 'AS MYCOMMAND
from dba_db_links l , V$INSTANCE i , dba_users u
where l.username = u.username
and l.username is not null
and l.username <> ' '
ORDER BY 1,2,3
)
To get ddl from db links, run the output of the command below:
set pages 999;
set long 90000;
SELECT 'SELECT dbms_metadata.get_ddl(''DB_LINK'',''' || db_link || ''',''' || owner || ''') FROM dual;'
FROM dba_db_links
WHERE db_link
IN ('DB_LINK1',
'DB_LINK2',
'DB_LINK3');
For create a db link for other user, with user SYS execute the DDL below:
CREATE DATABASE LINK "OWNER.DBLINK_NAME"
CONNECT TO "USER" IDENTIFIED BY "Password_user"
USING 'ALIAS';

Oracle sqlplus logging stops

This is strange...
I'm running a script in sqlplus. It seeems to have completed it's function, however when I review the .log it seems to have stopped logging...has anyone else had this experience?
I think I may have opened the logfile at some stage while the script was running to check process, perhaps that's no-no?
The redacted details are:
set serveroutput on;
set feedback off;
set echo on;
spool 4logfilethatstops.log
BEGIN
/*-----------------------------------------*/
/* Establishing AUID on dmt_identifier table*/
update DMT_CUSTOMER_ID
set auid=CUSTOMER_ID
where CUSTOMER_ID_ZONE_OFFICE = '&&var_DM_ID_ZONE_OFFICEority'
and batch_id = '&&var_batchid';
/*-----------------------------------------*/
/*Copying DM_ID to all tables*/
update dmt_ a
set DM_ID= (select CUSTOMER_ID from DMT_CUSTOMER_ID b
where b.PRI_CLT_RECORD_ID=a.PRI_CLT_RECORD_ID
and b.batch_id = '&&var_batchid'
and b.CUSTOMER_ID_ZONE_OFFICE = '&&var_DM_ID_ZONE_OFFICEority'
and b.CUSTOMER_ID_major_flag = 'Y'
and b.CUSTOMER_ID_type_code = '004')
where a.batch_id = '&&var_batchid';
[10 more similar statements]
/*-----------------------------------------*/
/*Exclude records with no DM_IDs*/
update dmt_address c
set c.batch_id = c.batch_id||'-EXCLUDE'
where c.batch_id = '&&var_batchid'
and c.pri_clt_record_id in
(SELECT pri_clt_record_id FROM dmt_
where DM_ID is NULL );
[10 more similar statements]
/*-----------------------------------------*/
/*Exclude merged records from dmt_ tables*/
update dmt_ c
set batch_id = batch_id||'-EXCLUDE'
where batch_id not like '%EXCLUDE%'
and c.pri_clt_record_id in
(select b.pri_clt_record_id from dmt_ a , dmt_ b
where a.container_sequence_number = b.container_sequence_number
and b.rpl_pri_clt_record_id = a.pri_clt_record_id
and a.rpl_pri_clt_record_id is null);
[1 more similar statement]
/*--------------------------------------------------------*/
/*Exclude dmt_insurance records from dmt_ that are not MRA*/
update dmt_insurance
set batch_id = batch_id||'-EXCLUDE'
where batch_id not like '%EXCLUDE%'
and client_insurance_record_id not like 'MRA-%';
/*-----------------------------------------------------*/
/*Populate dmt_demog with dmt_profile data*/
update dmt_staticdemographics a
set MSTATUS=(select CLIENT_ATTRIBUTE_CODE
from dmt_profile
where CLIENT_ATTRIBUTE_TYPE_CODE = 02
and batch_id = '&&var_batchid'
and PRI_CLT_RECORD_ID=a.PRI_CLT_RECORD_ID);
[4 more similar statements]
/*--------------------*/
/*Populate DM_* tables*/
/*----------------*/
/*inserting person*/
insert into dm_person
(CUSTOMER_ID, DOB,DOB_EST,SEX,
CREATED_DATE,LAST_UPDATE_DATE, batch_id)
select DM_ID, DATE_OF_BIRTH,DATE_OF_BIRTH_ESTIMATION_FLAG,
SEX_CODE,MSTATUS,INDIGENOUS,RELIGION,LANGUAGE
from dmt_staticdemographics
where DM_ID is not null
and batch_id = '&&var_batchid';
[3 more similar statements]
/*----------------------------------------------------------------------------------*/
-- inserting external identifiers
insert into DM_IDENTIFIER
(CUSTOMER_ID,IDENTIFIER_START_DATE,IDENTIFIER_END_DATE,IDENTIFIER_TYPE,ID_VALUE,CREATED_DATE,LAST_UPDATE_DATE, BATCH_ID, ZONE_OFFICEority)
select DM_ID,effective_start_date,effective_end_date, ext_clt_id_type_code, EXT_CLT_ID,SOURCE_CREATE_DATETIME, SOURCE_MODIFIED_DATETIME,
BATCH_ID, ext_clt_id_ZONE_OFFICE
from dmt_extidentifier
where DM_ID is not null
and batch_id = '&&var_batchid';
[4 more similar statements]
COMMIT;
END;
/

Oracle function within a transaction

I am inserting a record within a transaction and then later I am retrieving the same record via an Oracle function. The oracle function is returning no records. My DBA told me that Oracle functions do not operate inside a transaction. How do I get around this?
Example:
Begin transaction using the oracle provider
Execute some SQL:
INSERT OWNER
(FIRST_NAME, LAST_NAME)
VALUES
('JOHN', 'SMITH')
Get the record back within the transaction from a function (71 is an example ID):
select * from table (GET_OWNER_DETAILS_FNC (71) )
Here is the Oracle Function:
CREATE OR REPLACE FUNCTION "AROH"."GET_OWNER_DETAILS_FNC" (p_owner_information_oid in aroh_owner_information.owner_information_oid%type )
return OWNER_DETAILS_TABLE_TYPE_FNC
IS
PRAGMA AUTONOMOUS_TRANSACTION;
v_owner_details_set OWNER_DETAILS_TABLE_TYPE_FNC := OWNER_DETAILS_TABLE_TYPE_FNC();
CURSOR c_owner_dtls IS
select oi.owner_information_oid,
oi.first_name,
oi.last_name,
oi.company_name,
oi.license_information,
oi.company_ind,
oi.middle_initial,
oi.title_type_oid,
oi.suffix,
oi.status_type_code,
oi.primary_phone,
oi.secondary_phone,
oi.secondary_phone_type_code,
oi.primary_phone_type_code,
oi.email_address,
oi.comments,
oi.primary_phone_extension,
oi.secondary_phone_extension,
poa.owner_address_oid as primaryaddressid,
poa.address_type_code as primaryaddresscode,
poa.address1 as primaryaddress1,
poa.address2 as primaryaddress2,
poa.city as primarycity,
poa.state as primarystate,
poa.postal_code as primaryzip,
poa.current_ind as primarycurrent,
soa.owner_address_oid as secondaryaddressid,
soa.address_type_code as secondaryaddresscode,
soa.address1 as secondaryaddress1,
soa.address2 as secondaryaddress2,
soa.city as secondarycity,
soa.state as secondarystate,
soa.postal_code as secondaryzip,
soa.current_ind as secondarycurrent,
( select
( select oa2.owner_information_oid
from aroh_owner_aircraft_rlshp oa2
where upper(primary_owner) like '%PRIMARY%'
and oa2.aircraft_oid = oa1.aircraft_oid
and rownum = 1) as prim_owner_oid
from aroh_owner_aircraft_rlshp oa1
where oa1.owner_information_oid = p_owner_information_oid
and rownum = 1
) as primary_owner_oid,
( select
case when (upper(primary_owner) like '%PRIMARY%')
then 'Y'
else 'N' end as isprimary
from aroh_owner_aircraft_rlshp
where owner_information_oid = p_owner_information_oid
and rownum = 1
) as is_primary
from aroh_owner_information oi
inner join (select *
from aroh_owner_address
where upper(current_ind) = 'Y'
and address_type_code = 'OPRIM') poa
on oi.owner_information_oid = poa.owner_information_oid
left outer join (select *
from aroh_owner_address
where upper(current_ind) = 'Y'
and address_type_code = 'OSEC') soa
on oi.owner_information_oid = soa.owner_information_oid
where oi.owner_information_oid = p_owner_information_oid;
begin
For main_row in c_owner_dtls
loop
v_owner_details_set.EXTEND;
v_owner_details_set(v_owner_details_set.LAST) := OWNER_DETAILS_TYPE (main_row.owner_information_oid , main_row.first_name , main_row.last_name , main_row.company_name
, main_row.license_information , main_row.company_ind , main_row.middle_initial , main_row.title_type_oid , main_row.suffix , main_row.status_type_code , main_row.primary_phone
, main_row.secondary_phone , main_row.secondary_phone_type_code , main_row.primary_phone_type_code , main_row.email_address , main_row.comments , main_row.primary_phone_extension
, main_row.secondary_phone_extension , main_row.primaryaddressid , main_row.primaryaddresscode , main_row.primaryaddress1 , main_row.primaryaddress2 , main_row.primarycity
, main_row.primarystate , main_row.primaryzip , main_row.primarycurrent , main_row.secondaryaddressid , main_row.secondaryaddresscode , main_row.secondaryaddress1
, main_row.secondaryaddress2 , main_row.secondarycity , main_row.secondarystate , main_row.secondaryzip , main_row.secondarycurrent , main_row.primary_owner_oid , main_row.is_primary );
end loop;
return v_owner_details_set;
EXCEPTION
When others
then dbms_output.put_line ('Oracle error: '||SQLERRM);
end;
The AUTONOMOUS_TRANSACTION pragma means that the function operates in the context of a separate transaction. By default (see http://docs.oracle.com/cd/B19306_01/server.102/b14220/consist.htm#sthref1972) this uses the "read committed" isolation level, meaning that, when the transaction queries data, it sees only data that was committed before the query began. Since the data you inserted has not been committed, this means that the function can't see it.
From Oracle Docs:
The AUTONOMOUS_TRANSACTION pragma changes the way a subprogram works within a transaction. A subprogram marked with this pragma can do SQL operations and commit or roll back those operations, without committing or rolling back the data in the main transaction.
Can you try getting rid of that pragma?
Lastly, "My DBA told me that Oracle functions do not operate inside a transaction" is questionable. I'm no expert but I sincerely doubt whether this is correct.

Describe in SQL*Plus - does it call a package or run SQL? (Or something else?)

When I describe an Oracle TYPE in SQL*Plus, what does SQL*Plus do "under the bonnet" - Is it calling DBMS_METADATA (or similar)? Or is it querying the data dictionary directly?
Or something else entirely?
You can obviously use alter session set sql_trace=true to answer such questions.
For
create type desc_type as object (
dummy varchar2(1),
constructor function desc_type (a number) return self as result,
final member procedure m
);
/
alter session set sql_trace=true;
desc desc_type
alter session set sql_trace=false;
drop type desc_type
/
I find the following relevant SQL Statements in my trace file:
select procedure#,procedurename,properties,itypeobj#
from procedureinfo$ where obj#=:1
order by procedurename desc, overload# desc
select position#,
sequence#,
level#,
argument,
type#,
charsetid,
charsetform,
properties,
nvl(length, 0),
nvl(precision#, 0),
nvl(scale, 0),
nvl(radix, 0),
type_owner,
type_name,
type_subname,
type_linkname,
pls_type
from argument$
where obj#=:1 and procedure#=:2 order by sequence# desc
select max(procedure#) from procedurec$ where obj#=:1
select max(procedure#) from procedureplsql$ where obj#=:1
select max(procedure#) from procedurejava$ where obj#=:1
select procedure#,entrypoint# from procedurec$
where obj#=:1 order by procedure#
select procedure#,entrypoint#
from procedureplsql$ where obj#=:1 order by procedure#
select procedure#,ownerlength,classlength,methodlength,siglength, flagslength,cookiesize
from procedurejava$ where obj#=:1 order by procedure#
select ownername,classname,methodname,signature,flags
from procedurejava$ where obj#=:1 and procedure#=:2 order by procedure#
select count(*)
from vtable$ where obj#=:1
select vindex,itypetoid,imethod#,iflags,itypeowner,itypename
from vtable$ where obj#=:1 order by vindex
select externtype, externname
from type$ where tvoid=:1
So, under the bonnet, SQL*Plus uses plain SQL.

Resources