ORACLE APEX ADMIN LOGIN ISSUE - sql

I am getting an authentication required message on google chrome when logging into oracle apex admin.
screenshot of error:

I'm assuming you're using the embedded PL/SQL Gateway and the XDB Protocol Server, correct? If so, please ensure:
You have run #apex_epg_config.sql
You have unlocked the ANONYMOUS database user
https://docs.oracle.com/database/apex-5.1/HTMIG/configuring-embedded-PL-SQL-gateway.htm#HTMIG29205

Why this happens? Because the ANONYMOUS account is locked and/or expired.
Log in to main container database (not PDB)
Run the following query to determine status:
select account_status from dba_users where username = 'ANONYMOUS';
If account_status is expired, run the following:
alter user ANONYMOUS identified by anonymous;
alter user ANONYMOUS account unlock;
If account_status is locked, run the following:
alter user ANONYMOUS account unlock;

When using IE instead of Chrome the login message refers to XDB. It seems like a problem with anonymous connection. This thread gives a solution for enabling this anonymous access. Though I think this is not probably a good solution, I don't have enough knowledge to solve it in a better way. In case the link is broken, I'm pasting the solution here. It worked for me, and I've seen this solution in a few more places so I maybe this is quite common...
(with CONN sys/password AS SYSDBA)
SET SERVEROUTPUT ON
DECLARE
l_configxml XMLTYPE;
l_value VARCHAR2(5) := 'true'; -- (true/false)
BEGIN
l_configxml := DBMS_XDB.cfg_get();
IF l_configxml.existsNode('/xdbconfig/sysconfig/protocolconfig/httpconfig/allow-repository-anonymous-access') = 0 THEN
-- Add missing element.
SELECT insertChildXML
(
l_configxml,
'/xdbconfig/sysconfig/protocolconfig/httpconfig',
'allow-repository-anonymous-access',
XMLType('<allow-repository-anonymous-access xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd">' ||
l_value ||
'</allow-repository-anonymous-access>'),
'xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd"'
)
INTO l_configxml
FROM dual;
DBMS_OUTPUT.put_line('Element inserted.');
ELSE
-- Update existing element.
SELECT updateXML
(
DBMS_XDB.cfg_get(),
'/xdbconfig/sysconfig/protocolconfig/httpconfig/allow-repository-anonymous-access/text()',
l_value,
'xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd"'
)
INTO l_configxml
FROM dual;
DBMS_OUTPUT.put_line('Element updated.');
END IF;
DBMS_XDB.cfg_update(l_configxml);
DBMS_XDB.cfg_refresh;
END;
/

Related

Oracle PL/SQL debug procedure - using $$plsql_line

I'm looking to create a procedure that helps with debugging specific variables, and for the sake of re-usability I'd like to store it in it's own procedure and pass in the specific variable when needed such as
debugz(var_x);
and the debug procedure would do the following -
PROCEDURE debugz (var_x VARCHAR2(1000))
AS
BEGIN
DBMS_OUTPUT.put_line ('Variable value: '|| var_x || ' | Line number: ' || $$plsql_line ||' | Unit: '|| $$plsql_unit);
END;
The problem is, I want the PL/SQL line number and PL/SQL unit to be based off of where the procedure call originates, i.e. the line/unit of "debugz(var_x);". Is there anyway for debugz to output that line number without passing in additional information?
Check out DBMS_UTILITY.FORMAT_CALL_STACK
You may need/want to parse the output depending on your exact requirements, but may be a good place to start.
Oracle 10g onwards.
Also note DBMS_UTILITY.FORMAT_ERROR_BACKTRACE and DBMS_UTILITY.FORMAT_ERROR_STACK for error handling.
There is a very good debugging package unit called debugf which provides good functionality
The debug file contains information such as session id,date and time,packages being called and the line number of each debug message and the debug message itself
Example usage is given below
This is used to intialize the debug, the first parameter 'ALL' meaning all modules(can be function,procedure or package etc) and SYSTEM meaning the schema i want to debug
debug.init(p_modules => 'ALL',p_file =>'C:\debugf123\temp\test.txt',p_user =>'SYSTEM',p_show_date => 'YES',p_date_format =>'DD/MM/YYYY HH24:MI:SS',p_name_len => 30,p_show_sesid => 'YES');
This one works like printf in C and the maximum you can give is 10 parameters where v_word1 is a parameter
debug.f('the first is %s',v_word1);
This is same as debug.f but here you can give more than 10 parameters
debug.fa('the third is %s and %s',debug.argv(v_word1,v_amount));
The source code for this package is available at
http://gerardnico.com/wiki/database/oracle/debugf
OWA_UTIL.WHO_CALLED_ME(
owner OUT VARCHAR2,
name OUT VARCHAR2,
lineno OUT NUMBER,
caller_t OUT VARCHAR2);
Have you tried remote debugging? Here's how you can do it in SQL Developer:
1) Reference:
http://sueharper.blogspot.ca/2006/07/remote-debugging-with-sql-developer_13.html
2) User privileges:
grant EXECUTE on DBMS_DEBUG_JDWP to USERXX;
grant DEBUG CONNECT SESSION to USERXX;
grant DEBUG ANY PROCEDURE to USERXX;
3) Set Remote Debug on USERXX connection in SQL Developer:
Port: 80 (use 4000 if not blocked by firewall)
Local Address: IP address of your local machine
4) Compile code (package, procedure or function) in USERXX in SQL Developer for debug
5) Set breakpoints in code
6) On the remote (this could be your application invoking the PLSQL code):
before invoking the PLSQL code run/include the following:
DBMS_DEBUG_JDWP.CONNECT_TCP( 'IP address in 3', port in 3 ) when this is run SQL developer will switch to debug mode.
7) Run application or invoke procedure from remote as USERXX
8) SQL developer stops at first breakpoint, step into, view/change values and etc.

Oracle - Strange intermittent error with data/state being lost between procedure calls

I have a bug I've been trying to track down for a few weeks now, and have pretty much isolated exactly what's going wrong. However, why this happens is beyond me.
I have a very large Oracle package (around 4,100 lines of code) and I'm calling several procedures. However, data seems to be getting lost between procedure calls.
The data that is being lost is:
dpmethodstate varchar_state_local_type;
First, I call this procedure:
PROCEDURE delivery_plan_set_state (
messages OUT ReferenceCursor,
state IN varchar_state_local_type
) AS
BEGIN
logMessage('state COUNT is: ' || state.COUNT);
dpmethodstate := state;
FOR I IN 1..dpmethodstate.COUNT LOOP
logMessage(dpmethodstate(I));
END LOOP;
logMessage('delivery_plan_set_state end - dpmethodstate count is now ' || dpmethodstate.COUNT);
OPEN messages FOR SELECT * FROM TABLE(messageQueue);
messageQueue := NULL;
END delivery_plan_set_state;
I pass in state, which is a valid array of a single string. I can verify in the logs that dpmethodstate has a COUNT of 1 when the procedure ends.
Next, I call the execute_filter procedure which looks like this:
PROCEDURE execute_filter (
--Whole bunch of OUT parameters
) AS
--About 50 different local variables being set here
BEGIN
SELECT TO_CHAR(SYSTIMESTAMP, 'HH24:MI:SS.ff') INTO TIMING FROM DUAL;
logMessage('[' || TIMING || '] execute_filter begin');
logMessage('a) dpmethodstate Count is: ' || dpmethodstate.COUNT);
--Rest of procedure
However, this time dpmethodstate.COUNT is 0. The value I set from delivery_plan_set_state has vanished!
When I look at my logs, it looks something like this:
proposed
delivery_plan_set_state end - dpmethodstate count is now 1
[21:39:48.719017] execute_filter begin
a) dpmethodstate Count is: 0
As you can see, dpmethodstate got lost between procedure calls. There's a few things to note:
Nothing else in this package is capable of setting the value for dpmethodstate besides delivery_plan_set_state. And I can see nothing else has called it.
My client side code is written in C#, and not much happens between the two procedure calls.
This happens perhaps 1 out of every 100 times, so it's very difficult to track down or debug.
First off, what's the best way to debug a problem like this? Is there any more logging I can do? Also, how does Oracle maintain state between procedure calls and is there anything that can intermittently reset this state? Any pointers would be much appreciated!
Is dpmethodstate a package global variable? I'm assuming it is, but I don't see that explicitly mentioned.
Since package global variables have session scope, are you certain that the two procedure calls are always using the same physical database connection and that nothing is using this connection in the interim? If you're using some sort of connection pool where you get a connection from the pool before each call and return the connection to the pool after the first call, it wouldn't be terribly unusual in a development environment (or low usage environment) to get the same connection 99% of the time for the second call but get a different session 1% of the time.
Can you log the SID and SERIAL# of the session where you are setting the value and where you are retrieving the value?
SELECT sid, serial#
FROM v$session
WHERE sid = sys_context( 'USERENV', 'SID' );
If those are different, you wouldn't expect the value to persist.
Beyond that, there are other ways to clear session state but they require someone to take explicit action. Calling DBMS_SESSION.RESET_PACKAGE or DBMS_SESSION.MODIFY_PACKAGE_STATE(DBMS_SESSION.REINITIALIZE) will clear out any session state set in your session. Compiling the package will do the same thing but that should throw an error warning you that your session state was discarded when you try to read it.

Oracle debugging techniques

I'm having difficulty debugging triggers in Oracle. Currently I'm using Oracle's Sql Developer tool.
To test a trigger I write inserts or deletes in a test window but I can't see what is happening inside the trigger. I would like to step through the trigger and see what is happening as the trigger fires. Is there any way to use select statements to display variable values inside the triggers?
Firstly, don't "start from here", or more specifically, don't use triggers. Triggers are going to force switching to row-level processing if the triggers are going to fire for each row. It's better to put the logic in a stored procedure which you call. You've then got a start (where you validate inputs) and an end and a logic path all the way through. Stored procedures are a lot easier to debug as you follow one path.
Second, never test for an error you don't know how to handle. If you don't catch it, it bubbles up to the client who gets an error report saying what went wrong (error message) and where (i.e. the error/call stack). If you try to catch it, you have to know what to do with it (and if you don't know the tendency is to ignore it - which is BAD).
Finally, you can't readily see each 'layer' of a select. The explain plan will generally tell you how its going about things. v$session_longops MAY indicate what it is currently doing. The current wait event MAY give clues as to what table/block/row it is currently working on.
A rough-and-ready simple method if you must debug triggers is to use DBMS_OUTPUT.
e.g.
SQL> CREATE OR REPLACE TRIGGER mytrigger
BEFORE UPDATE ON mytable
FOR EACH ROW
...
BEGIN
DBMS_OUTPUT.put_line('mytrigger STARTING');
... do some logic ...
DBMS_OUTPUT.put_line('old=' || :OLD.mycolumn);
DBMS_OUTPUT.put_line('new=' || :NEW.mycolumn);
DBMS_OUTPUT.put_line('mytrigger FINISHED');
END;
/
SQL> SET SERVEROUT ON
SQL> UPDATE mytable SET mycolumn = mycolumn + 1;
2 rows updated.
mytrigger STARTING
old=10
new=11
mytrigger FINISHED
mytrigger STARTING
old=20
new=21
mytrigger FINISHED
Application
I use a program from Quest called TOAD available at www.quest.com/toad/toad-for-oracle.aspx.
As mentioned above, DBMS_OUTPUT is very handy. In your editor, make sure you enable the Output window.
PL/SQL works on "blocks" of code and you can catch it with an EXCEPTION keyword.
(Please forgive my formatting, not sure how to format for web)
DECLARE
C_DATE_FORMAT VARCHAR2(20) := 'DD-Mon-YYYY';
C_TIME_FORMAT VARCHAR2(20) := 'HH24:MI:SS';
C_NOT_IMPLEMENTED_CODE CONSTANT NUMBER(5) := -20200;
C_NOT_IMPLEMENTED_MESSAGE CONSTANT VARCHAR2(255) := 'Not implemented';
not_implemented EXCEPTION; -- user defined exception
BEGIN
--RAISE not_implemented; -- raise user defined exception
RAISE_APPLICATION_ERROR(C_NOT_IMPLEMENTED_CODE, C_NOT_IMPLEMENTED_MESSAGE); -- user defined exception
EXCEPTION -- exception block
WHEN not_implemented THEN -- catch not_implemented exception
DBMS_OUTPUT.PUT_LINE('Error: Not implemented');
WHEN OTHERS THEN -- catch all other exceptions
DBMS_OUTPUT.PUT_LINE('Error occured.');
DBMS_OUTPUT.PUT_LINE('Date: ' || TO_CHAR(SYSDATE, C_DATE_FORMAT));
DBMS_OUTPUT.PUT_LINE('Time: ' || TO_CHAR(SYSDATE, C_TIME_FORMAT));
DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM); --deal with error
RAISE; -- raise to calling object
END;
Follow below steps to DEBUG trigger in Oracle PL/SQL
Open your trigger using Edit option. Set breakpoint by clicking on line number (See below).
Open Test Window as shown below.
Write Insert/Update query for your table. (Note: Your trigger could be set on update/insert or both)
Click Start debugger button.
As soon as value will be updated in your Table. Debugger will take you to trigger. Where you can continue your debugging.

Would like help with LOGON Trigger

I've created a logon trigger in MS SQL that needs to check dm_exec_sessions for a login. This login is the user listed in the connection string and has owner right to the database. If the login is verified, I need it to update a specific table and send an email.
So far I've done just the following piece and it disabled my web site. The error I get is: "Logon failed for login 'dev' due to trigger execution. Changed database context to 'mydatabase'. Changed language setting to us_english."
Any idea what I did wrong? Thanks,
Risho
CREATE TRIGGER TDY_Assets_Notification
ON ALL SERVER WITH EXECUTE AS 'dev'
FOR LOGON
AS
BEGIN
IF ORIGINAL_LOGIN()='dev' AND
(SELECT COUNT(*) FROM sys.dm_exec_sessions
WHERE is_user_process = 1 AND
original_login_name = 'dev') > 1
UPDATE Assets_TDY
SET Suspense = 1, Warning = 1
WHERE (Date_Returned IS NULL) AND (GETDATE() >= DATEADD(day, 3, Date_Return))
END
Try connecting with the Dedicated Administrator Connection. That will give you an opportunity to disable the faulty logon trigger.
DISABLE TRIGGER [TDY_Assets_Notification] ON ALL SERVER

Sleep function in ORACLE

I need execute an SQL query in ORACLE it takes a certain amount of time.
So I wrote this function:
CREATE OR REPLACE FUNCTION MYSCHEMA.TEST_SLEEP
(
TIME_ IN NUMBER
)
RETURN INTEGER IS
BEGIN
DBMS_LOCK.sleep(seconds => TIME_);
RETURN 1;
EXCEPTION
WHEN OTHERS THEN
RAISE;
RETURN 1;
END TEST_SLEEP;
and I call in this way
SELECT TEST_SLEEP(10.5) FROM DUAL
but to work I need set grant of DBMS_LOCK to the owner of the procedure.
How I can rewrite this function without using the DBMS_LOCK.sleep function?
Short of granting access to DBMS_LOCK.sleep, this will work but it's a horrible hack:
IN_TIME INT; --num seconds
v_now DATE;
-- 1) Get the date & time
SELECT SYSDATE
INTO v_now
FROM DUAL;
-- 2) Loop until the original timestamp plus the amount of seconds <= current date
LOOP
EXIT WHEN v_now + (IN_TIME * (1/86400)) <= SYSDATE;
END LOOP;
Create a procedure which just does your lock and install it into a different user, who is "trusted" with dbms_lock ( USERA ), grant USERA access to dbms_lock.
Then just grant USERB access to this function. They then wont need to be able to access DBMS_LOCK
( make sure you don't have usera and userb in your system before running this )
Connect as a user with grant privs for dbms_lock, and can create users
drop user usera cascade;
drop user userb cascade;
create user usera default tablespace users identified by abc123;
grant create session to usera;
grant resource to usera;
grant execute on dbms_lock to usera;
create user userb default tablespace users identified by abc123;
grant create session to userb;
grant resource to useb
connect usera/abc123;
create or replace function usera.f_sleep( in_time number ) return number is
begin
dbms_lock.sleep(in_time);
return 1;
end;
/
grant execute on usera.f_sleep to userb;
connect userb/abc123;
/* About to sleep as userb */
select usera.f_sleep(5) from dual;
/* Finished sleeping as userb */
/* Attempt to access dbms_lock as userb.. Should fail */
begin
dbms_lock.sleep(5);
end;
/
/* Finished */
From Oracle 18c you could use DBMS_SESSION.SLEEP procedure:
This procedure suspends the session for a specified period of time.
DBMS_SESSION.SLEEP (seconds IN NUMBER)
DBMS_SESSION.sleep is available to all sessions with no additional grants needed.
Please note that DBMS_LOCK.sleep is deprecated.
If you need simple query sleep you could use WITH FUNCTION:
WITH FUNCTION my_sleep(i NUMBER)
RETURN NUMBER IS
BEGIN
DBMS_SESSION.sleep(i);
RETURN i;
END;
SELECT my_sleep(3) FROM dual;
db<>fiddle demo
There is a good article on this topic: PL/SQL: Sleep without using DBMS_LOCK that helped me out. I used Option 2 wrapped in a custom package. Proposed solutions are:
Option 1: APEX_UTIL.sleep
If APEX is installed you can use the procedure “PAUSE” from the publicly available package APEX_UTIL.
Example – “Wait 5 seconds”:
SET SERVEROUTPUT ON ;
BEGIN
DBMS_OUTPUT.PUT_LINE('Start ' || to_char(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
APEX_UTIL.PAUSE(5);
DBMS_OUTPUT.PUT_LINE('End ' || to_char(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
END;
/
Option 2: java.lang.Thread.sleep
An other option is the use of the method “sleep” from the Java class “Thread”, which you can easily use through providing a simple PL/SQL wrapper procedure:
Note: Please remember, that “Thread.sleep” uses milliseconds!
--- create ---
CREATE OR REPLACE PROCEDURE SLEEP (P_MILLI_SECONDS IN NUMBER)
AS LANGUAGE JAVA NAME 'java.lang.Thread.sleep(long)';
--- use ---
SET SERVEROUTPUT ON ;
BEGIN
DBMS_OUTPUT.PUT_LINE('Start ' || to_char(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
SLEEP(5 * 1000);
DBMS_OUTPUT.PUT_LINE('End ' || to_char(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
END;
/
If executed within "sqlplus", you can execute a host operating system command "sleep" :
!sleep 1
or
host sleep 1
What's about Java code wrapped by a procedure? Simple and works fine.
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED SNOOZE AS
public final class Snooze {
private Snooze() {
}
public static void snooze(Long milliseconds) throws InterruptedException {
Thread.sleep(milliseconds);
}
}
CREATE OR REPLACE PROCEDURE SNOOZE(p_Milliseconds IN NUMBER) AS
LANGUAGE JAVA NAME 'Snooze.snooze(java.lang.Long)';
It would be better to implement a synchronization mechanism. The easiest is to write a file after the first file is complete. So you have a sentinel file.
So the external programs looks for the sentinel file to exist. When it does it knows that it can safely use the data in the real file.
Another way to do this, which is similar to how some browsers do it when downloading files, is to have the file named base-name_part until the file is completely downloaded and then at the end rename the file to base-name.
This way the external program can't "see" the file until it is complete. This way wouldn't require rewrite of the external program. Which might make it best for this situation.
If Java is installed on your 11G then you can do it in a java class and call it from your PL/SQL, but I am not sure that it does not require also a specific grant to call java.
Seems the java procedure/function could work. But why don't you compile your function under a user like the application schema or a admin account that has this grant and just grant your developer account execute on it. That way the definer rights are used.
You can use DBMS_PIPE.SEND_MESSAGE with a message that is too large for the pipe, for example for a 5 second delay write XXX to a pipe that can only accept one byte using a 5 second timeout as below
dbms_pipe.pack_message('XXX');<br>
dummy:=dbms_pipe.send_message('TEST_PIPE', 5, 1);
But then that requires a grant for DBMS_PIPE so perhaps no better.
You can use the DBMS_ALERT package as follows:
CREATE OR REPLACE FUNCTION sleep(seconds IN NUMBER) RETURN NUMBER
AS
PRAGMA AUTONOMOUS_TRANSACTION;
message VARCHAR2(200);
status INTEGER;
BEGIN
DBMS_ALERT.WAITONE('noname', message, status, seconds);
ROLLBACK;
RETURN seconds;
END;
SELECT sleep(3) FROM dual;