Showing posts with label e-BS. Show all posts
Showing posts with label e-BS. Show all posts

Wednesday, July 11, 2012

Concurrent processes information script

The following query will display useful information about your eBS' concurrent processes:
  SELECT P.CONCURRENT_PROCESS_ID,
         QU.USER_CONCURRENT_QUEUE_NAME,
         QU.CONCURRENT_QUEUE_NAME,
         DECODE (P.PROCESS_STATUS_CODE,
                 'A', 'Active',
                 'G', 'Awaiting Discovery',
                 'C', 'Connecting',
                 'S', 'Deactivated',
                 'D', 'Deactiviating',
                 'Z', 'Initializing',
                 'M', 'Migrating',
                 'R', 'Running',
                 'P', 'Suspended',
                 'K', 'Terminated',
                 'T', 'Terminating',
                 'Unknown')
            "STATUS",
         P.NODE_NAME,
         P.OS_PROCESS_ID,
         P.DB_NAME,
         P.DB_INSTANCE,
         SS.SID,
         P.ORACLE_PROCESS_ID,
         P.PROCESS_START_DATE,
         P.MANAGER_TYPE,
         P.LOGFILE_NAME
    FROM APPLSYS.FND_CONCURRENT_PROCESSES P,
         APPS.FND_CONCURRENT_QUEUES_VL QU,
         GV$SESSION SS
   WHERE     P.CONCURRENT_QUEUE_ID = QU.CONCURRENT_QUEUE_ID
         AND P.SESSION_ID = SS.AUDSID(+)
         AND P.INSTANCE_NUMBER = SS.INST_ID(+)

Tuesday, July 10, 2012

Concurrent programs maximum, minimum and average execution times report

The following script will give you the maximum, minimum and average execution times of each concurrent program had been executed in your eBS. It will measure only the successfully completed concurrent requests.
SELECT P.CONCURRENT_PROGRAM_NAME,
         PT.USER_CONCURRENT_PROGRAM_NAME,
         COUNT (*),
            TRUNC (MAX (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE))
         || ' Days'
         || ' + '
         || TO_CHAR (
               TRUNC (SYSDATE)
               + NUMTODSINTERVAL (
                    MAX ( (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE))
                    * 86400,
                    'second'),
               'HH24:MI:SS')
            "MAXIMUM",
            TRUNC (MIN (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE))
         || ' Days'
         || ' + '
         || TO_CHAR (
               TRUNC (SYSDATE)
               + NUMTODSINTERVAL (
                    MIN ( (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE))
                    * 86400,
                    'second'),
               'HH24:MI:SS')
            "MINIMUM",
            TRUNC (AVG (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE))
         || ' Days'
         || ' + '
         || TO_CHAR (
               TRUNC (SYSDATE)
               + NUMTODSINTERVAL (
                    AVG ( (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE))
                    * 86400,
                    'second'),
               'HH24:MI:SS')
            "AVERAGE"
    FROM APPLSYS.FND_CONCURRENT_REQUESTS F,
         APPLSYS.FND_CONCURRENT_PROGRAMS P,
         APPLSYS.FND_USER A,
         APPLSYS.FND_CONCURRENT_PROGRAMS_TL PT
   WHERE     PHASE_CODE = 'C'
         AND STATUS_CODE = 'C'
         AND F.CONCURRENT_PROGRAM_ID = P.CONCURRENT_PROGRAM_ID
         AND P.CONCURRENT_PROGRAM_ID = PT.CONCURRENT_PROGRAM_ID
         AND A.USER_ID(+) = F.REQUESTED_BY
GROUP BY P.CONCURRENT_PROGRAM_NAME, PT.USER_CONCURRENT_PROGRAM_NAME;

CONCURRENT_PROGRAM_NAMEUSER_CONCURRENT_PROGRAM_NAMECOUNT (*)MAXIMUMMINIMUMAVERAGE
XXI_UPD_CONF_ORDER_STATUSXXI : Update Order Status for Confirmed Orders330760 Days + 00:10:510 Days + 00:00:040 Days + 00:00:11
FNDWFBGWorkflow Background Process489058 Days + 13:34:250 Days + 00:00:000 Days + 00:02:42
FAPROJDepreciation Projection370 Days + 03:12:100 Days + 00:00:350 Days + 00:45:31
XXIEX_RUN_STRATEGIESRequest Set OTE Run Strategies1080 Days + 19:42:550 Days + 07:17:490 Days + 12:51:35
..................

Monday, July 9, 2012

Concurrent requests information scripts

The first script will report information about your concurrent requests, such as if it's scheduled, running or completed, which users run them, request IDs, their arguments.
For example, to find all runs of Workflow Background Process program:
    SELECT F.REQUEST_ID,
         A.USER_NAME,
         DECODE (TO_CHAR (F.ACTUAL_START_DATE, 'DD/MM/YYYY HH24:MI:SS'),
                 NULL, 'PENDING',
                 TO_CHAR (F.ACTUAL_START_DATE, 'DD/MM/YYYY HH24:MI:SS'))
            DATE_STARTED,
         DECODE (
            DECODE (
               TRUNC (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE),
               0, NULL,
                  TRUNC (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE)
               || ' Days'
               || ' + ')
            || TO_CHAR (
                  TRUNC (SYSDATE)
                  + NUMTODSINTERVAL (
                       (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE) * 86400,
                       'second'),
                  'HH24:MI:SS'),
            ' Days + ', 'RUNNING',
            DECODE (
               TRUNC (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE),
               0, NULL,
                  TRUNC (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE)
               || ' Days'
               || ' + ')
            || TO_CHAR (
                  TRUNC (SYSDATE)
                  + NUMTODSINTERVAL (
                       (F.ACTUAL_COMPLETION_DATE - F.ACTUAL_START_DATE) * 86400,
                       'second'),
                  'HH24:MI:SS'))
            REQ_DURATION,
         F.COMPLETION_TEXT,
         P.CONCURRENT_PROGRAM_NAME CONC_PROGRAM,
         F.ARGUMENT_TEXT
    FROM APPLSYS.FND_CONCURRENT_REQUESTS F,
         APPLSYS.FND_USER A,
         APPLSYS.FND_CONCURRENT_PROGRAMS P,
         APPLSYS.FND_CONCURRENT_PROGRAMS_TL PT
   WHERE     A.USER_ID(+) = F.REQUESTED_BY
         AND F.CONCURRENT_PROGRAM_ID = P.CONCURRENT_PROGRAM_ID
         AND P.CONCURRENT_PROGRAM_ID = PT.CONCURRENT_PROGRAM_ID
         AND PT.USER_CONCURRENT_PROGRAM_NAME = 'Workflow Background Process'
         AND PT.LANGUAGE = 'US'
ORDER BY F.REQUESTED_START_DATE DESC;

REQUEST_IDUSER_NAMEDATE_STARTEDREQ_DURATIONCOMPLETION_TEXTCONC_PROGRAMARGUMENT_TEXT
39363160COLL_SETUPPENDINGRUNNINGFNDWFBGXXSTRYRE, , , N, Y, Y
39363194COLL_SETUP09/07/2012 12:00:0300:00:09Normal completionFNDWFBGXXSTRYRE, , , Y, N, N
39362136SYSADMIN09/07/2012 11:36:10RUNNINGFNDWFBGOEOL, , , Y, N, N
.....................
38021590SYSADMIN09/05/2012 10:25:034 Days + 23:06:07FNDWFBGOEOL, , , Y, N, N

If DATE_STARTED has a value of PENDING, then this concurrent request has not started yet. Ignore, in this case, the RUNNING value of REQ_DURATION.

You may filter the result by using specific columns in the WHERE clause.

PHASE_CODE and STATUS_CODE of APPLSYS.FND_CONCURRENT_REQUESTS table.
PHASE_CODE
VALUEMEANING
CCompleted
IInactive
PPending
RRunning

STATUS_CODE
VALUEMEANING
AWaiting
BResuming
CNormal
DCancelled
EError
FScheduled
GWarning
HOn hold
INormal
MNo manager
QStandby
RNormal
SSuspended
TTerminating
UDisabled
WPaused
XTerminated
ZWaiting

CONCURRENT_PROGRAM_NAME of APPLSYS.FND_CONCURRENT_PROGRAMS table, if you want to use its short name (FNDWFBG for our case).
ACTUAL_START_DATE of APPLSYS.FND_CONCURRENT_REQUESTS to limit the result by date.
USER_NAME of APPLSYS.FND_USER to check runs of specific users.

The second script will report the running/pending concurrent requests, to which concurrent manager are assigned, the node they are running their process IDs, log and output files, and database session information.
  SELECT
         REQ.REQUEST_ID "REQUEST ID",
         USR.USER_NAME "USER",
         QU.USER_CONCURRENT_QUEUE_NAME "CONC. MANAGER",
         REQ.REQUEST_DESCRIPTION "NAME",
         REQ.CONCURRENT_PROGRAM_NAME "SHORT NAME",
         REQ.ARGUMENT_TEXT "ARGUMENTS",
         DECODE (REQ.PHASE_CODE,
                 'R', 'RUNNING',
                 'P', 'PENDING',
                 'I', 'INCACTIVE')
            "PHASE",
         REQ.REQUEST_DATE "DATE SUBMITTED",
         REQ.REQUESTED_START_DATE "REQUESTED START DATE",
         REQ.ACTUAL_START_DATE "DATE STARTED",
         REQ.LOGFILE_NODE_NAME "NODE",
         REQ.LOGFILE_NAME "LOG",
         REQ.OUTFILE_NAME "OUTPUT",
         REQ.OS_PROCESS_ID "NODE PROCESS",
         REQ.ORACLE_PROCESS_ID "DB PROCESS",
         SS.INST_ID "DB INSTANCE",
         SS.SID "DB SID",
         SS.STATUS "DB SESSION STATUS"
    FROM APPS.FND_CONCURRENT_WORKER_REQUESTS REQ,
         APPLSYS.FND_USER USR,
         GV$SESSION SS,
         APPS.FND_CONCURRENT_QUEUES_VL QU
   WHERE     USR.USER_ID = REQ.REQUESTED_BY
         AND REQ.ORACLE_SESSION_ID = SS.AUDSID(+)
         AND REQ.CONCURRENT_QUEUE_ID = QU.CONCURRENT_QUEUE_ID
ORDER BY REQUEST_ID DESC;

Thursday, June 10, 2010

Forms fail to generate after 10g RDBMS upgrade [cannot pass cursor variables to a procedure that is called through a database link]

After 10g RDBMS upgrade some forms fail to generate. An example is shown in the image, where you can see the generation is stuck compiling a trigger.
The relevant Metalink note is 300990.1:
Compiling Form Fails or FRM-10760 When Using TYPE Declarations In Procedure Called Via DB Link.

Although the note refers to Forms 9.0 to 10.1, the problem also occurs in Forms 6i, since it is a RDBMS functionality change:

In Oracle Server 10g and higher restrictions have been placed on cursor variables. To quote from the Oracle Server 10g documentation, Chapter 6 Performing SQL Operations from PL/SQL:
Restrictions on Cursor Variables
You cannot pass cursor variables to a procedure that is called through a database link.
The restriction therefore applies to TYPE declarations, %TYPE and %ROWTYPE used in a remote database procedure.

In the trigger, in which the compilation hungs, there is a call to a procedure:

XXE_F36_LLU_WCRM.prc_Get_LocationInfo

In this package there are declarations, like:

prec_cli IN w_llu_ll_order@datallu%ROWTYPE
p_wcrm_order_id IN w_llu_ll_order.order_id@datallu%TYPE

w_llu_ll_order is a table in a remote database, accessed via a DB link.
These declarations have to be replaced.
I tried 2 workarounds, which both work.
The first is to create local views that point to the remote table, like:

create view apps.v_w_llu_ll_order as select * from w_llu_ll_order@datallu;

and then replace the above declarations:

prec_cli IN v_w_llu_ll_order%ROWTYPE
p_wcrm_order_id IN v_w_llu_ll_order.order_id%TYPE

The second is to check the column types in the remote table and explicitly set the variable types to match them:

p_wcrm_order_id IN number(10)

Now, the form generation will not hung.

Tuesday, June 2, 2009

Oracle Quoting error: ORA-06508 on submit order



When a user submits a new order, sometimes will get an error:

Error in Line 1.0: ORA-06508:PL/SQL:could not find program unit being called in Package OM_TAX_UTIL Procedure Tax_Line

This error is persistent and relogin does not allow the user to bypass the error.
This framework uses Java Apache processes to connect to the DB, and not the default connection method, seen when a form opens a session and closes it when it is done.
These Apache processes stay connected to the DB, until an Apache restart/shutdown occurs.

We enable tracing for ORA-06508:
ALTER SYSTEM SET EVENTS '6508 trace name errorstack level 3';

The trace files created by the "submit orders" attempts contain the following group of ORA errors:
ORA-04061: existing state of package body "APPS.ARP_PROCESS_TAX" has been invalidated

ORA-04065: not executed, altered or dropped package body "APPS.ARP_PROCESS_TAX"

ORA-06508: PL/SQL: could not find program unit being called

In OM_TAX_UTIL.TAX_LINE there are calls to ARP_PROCESS_TAX's procedures.
ARP_PROCESS_TAX package gets its body invalidated by a AR purge process, which executes DDL operations on a few AR interface tables.
This process recompiles every object it invalidates, before it finishes.
So, ARP_PROCESS_TAX spec and body have VALID status, when its procedures are called by TAX_LINE.
The key for this problem is the fact that the Apache processes that handle the Quoting requests, stay always connected to the database.
For some reason (probably Bug 2747350) the new package state is not picked up.

A demonstration is following to simulate the issue.
We create a table:
CREATE TABLE SYSTEM.TEST_TABLE
TABLESPACE TOOLS
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
NOMONITORING
AS
   SELECT * FROM DBA_OBJECTS;

A view on this table:
CREATE OR REPLACE FORCE VIEW SYSTEM.TEST_VIEW
(
   OWNER,
   OBJECT_NAME,
   SUBOBJECT_NAME,
   OBJECT_ID,
   DATA_OBJECT_ID,
   OBJECT_TYPE,
   CREATED,
   LAST_DDL_TIME,
   TIMESTAMP,
   STATUS,
   TEMPORARY,
   GENERATED,
   SECONDARY
)
AS
   SELECT "OWNER",
          "OBJECT_NAME",
          "SUBOBJECT_NAME",
          "OBJECT_ID",
          "DATA_OBJECT_ID",
          "OBJECT_TYPE",
          "CREATED",
          "LAST_DDL_TIME",
          "TIMESTAMP",
          "STATUS",
          "TEMPORARY",
          "GENERATED",
          "SECONDARY"
     FROM TEST_TABLE;

A package which uses this view, and is equivalent to ARP_PROCESS_TAX:
CREATE OR REPLACE PACKAGE TEST_PKG
IS
   X   CONSTANT NUMBER := 1;
   GVAR         VARCHAR2 (50);

   FUNCTION GETINFO
      RETURN VARCHAR2;
END;
/

CREATE OR REPLACE PACKAGE BODY TEST_PKG
IS
   FUNCTION GETINFO
      RETURN VARCHAR2
   IS
   BEGIN
      SELECT OBJECT_NAME
        INTO GVAR
        FROM TEST_VIEW
       WHERE OBJECT_ID = 100;
      RETURN GVAR;
   END;
END;
/

A package which calls test_pkg.getInfo and has exception handling of ORA-6508 error.
This is equivalent to the OM_TAX_UTIL package:
CREATE OR REPLACE PACKAGE TEST_PKG_RUN
IS
   X   CONSTANT NUMBER := 1;

   PROCEDURE RUNPROC;
END;
/

CREATE OR REPLACE PACKAGE BODY TEST_PKG_RUN
IS
   PROCEDURE RUNPROC
   IS
      PACKAGE_EXCEPTION   EXCEPTION;
      PRAGMA EXCEPTION_INIT (PACKAGE_EXCEPTION, -6508);
      D                   VARCHAR2 (50);
   BEGIN
      D := TEST_PKG.GETINFO ();
      DBMS_OUTPUT.PUT_LINE (D);
      DBMS_LOCK.SLEEP (10);           --> to allow me time to recreate package
   EXCEPTION
      WHEN PACKAGE_EXCEPTION
      THEN
         DBMS_OUTPUT.PUT_LINE ('Called failed with ' || SQLCODE);
   END;
END;
/

We open one session [1] and run test_pkg_run.runproc:
SQL> conn system@sme_gnvdev
Enter password: *******
Connected.

SQL> set serveroutput on
SQL> exec test_pkg_run.runproc;
I_IDL_UB11
PL/SQL procedure successfully completed.

We open a second session [2] and modify test_view, which invalidates test_pkg's body:
SQL> conn system@sme_gnvdev
Enter password: *******
Connected.

SQL> CREATE OR REPLACE FORCE VIEW SYSTEM.TEST_VIEW
2 (
3 OWNER,
4 OBJECT_NAME,
5 SUBOBJECT_NAME,
6 OBJECT_ID,
7 DATA_OBJECT_ID,
8 OBJECT_TYPE,
9 CREATED,
10 LAST_DDL_TIME,
11 --TIMESTAMP,
12 STATUS,
13 TEMPORARY,
14 GENERATED,
15 SECONDARY
16 )
17 AS
18 SELECT "OWNER",
19 "OBJECT_NAME",
20 "SUBOBJECT_NAME",
21 "OBJECT_ID",
22 "DATA_OBJECT_ID",
23 "OBJECT_TYPE",
24 "CREATED",
25 "LAST_DDL_TIME",
26 -- "TIMESTAMP",
27 "STATUS",
28 "TEMPORARY",
29 "GENERATED",
30 "SECONDARY"
31 FROM test_table;
View created.

SQL> select object_type,status
2 from dba_objects where object_name='TEST_PKG';

OBJECT_TYPE STATUS
------------------
PACKAGE VALID
PACKAGE BODY INVALID

In [2] we compile test_pkg's body and validate it:
SQL> alter package test_pkg compile body;
Package body altered.

SQL> select object_type,status
2 from dba_objects where object_name='TEST_PKG';

OBJECT_TYPE STATUS
------------------
PACKAGE VALID
PACKAGE BODY VALID

In [1] any execution of test_pkg_run.runproc results to a ORA-6508 error:
SQL> set serveroutput on
SQL> exec test_pkg_run.runproc;
Called failed with -6508
PL/SQL procedure successfully completed.

SQL> set serveroutput on
SQL> exec test_pkg_run.runproc;
Called failed with -6508
PL/SQL procedure successfully completed.

SQL> set serveroutput on
SQL> exec test_pkg_run.runproc;
Called failed with -6508
PL/SQL procedure successfully completed.


Oracle has filed this issue under Bug 8613161: PRAGMA EXCEPTION_INIT MASKS ORA-4068 AND PACKAGE IS NOT RE-INSTANTIATED PROBLEM:

 1. Clear description of the problem encountered: 


A PL/SQL package declares a user defined exception using PRAGMA EXCEPTION_INIT for ORA-6508. When this error occurs a second user defined  exception is raised which appears to mask the underlying ORA-4068 error which  accompanies the ORA-6508 error. This has the effect of preventing the Package from being re-instantiated in the session even though the underlying  cause of the ORA-6508 error (an invalid dependent) is resolved.  


    procedure runproc is 
      package_exception exception; 
      rzy_except exception; 
      PRAGMA EXCEPTION_INIT (package_exception, -6508); 
      PRAGMA EXCEPTION_INIT (rzy_except, -20001); 
      d varchar2(50); 
    begin 
      d:=test_pkg.getInfo(); 
      dbms_output.PUT_LINE(d); 
      dbms_lock.sleep(10); --> to allow me time to recreate package 
    exception 
      when package_exception then 
      dbms_output.put_line('Called failed with '||sqlcode); 
      --raise; 
      raise rzy_except; 
    end; 


If the raised user defined exception (raise rzy_except;) is replaced with the raise statement, the ORA-4068 error is shown on the error stack and the package is re-instantiated in the session. 


I have raised this bug as a P2 because the APPS customer has coded a great deal of customisation code before encountering this error and it is not feasible for them to make the necessary code changes.  


=========================     
DIAGNOSTIC ANALYSIS: 
=========================    
WORKAROUND: 
Use the raise statement or reconnect to the db. 
=========================    
RELATED BUGS: 
Bug 229349 ORA-4068 LEADS TO INSERT ALWAYS FAILING IF TRIGGER USES RAISE_APPLICATION_ERROR. 
=========================    
REPRODUCIBILITY: 
 1. State if the problem is reproducible; indicate where and predictability Reproduces every time 
 2. List the versions in which the problem has reproduced   On Solaris Oracle Version 10.2.0.4, 11.1.0.7 
 3. List any versions in which the problem has not reproduced . 
=========================     
tc.sql - creates table, view and package. 
tc1.sql - runs the package 
tc2.sql - drops and recreates the view and checks the status of the package in user_objects. 
Two sessions A and B  
1. Run tc.sql to set up the table, view and package. 
2. Run tc1.sql to run the package and straight after in session B run tc2.sql 
Session A 
SQL> @tc.sql 
SQL> @tc1.sql 
Session B 
SQL> @tc2.sql 


Results: 
ERROR at line 1: 
ORA-20001: 
ORA-06512: at "SCOTT.TEST_PKG_RUN", line 17 
ORA-04061: existing state of package body "SCOTT.TEST_PKG" has been invalidated 
ORA-04065: not executed, altered or dropped package body "SCOTT.TEST_PKG" 
ORA-06508: PL/SQL: could not find program unit being called: "SCOTT.TEST_PKG" 
ORA-06512: at line 1 


This error occurs every time even though the package is now valid, which can be shown in session B. 
When 'raise rzy_except;' is commented out and replaced by 'raise;', the package reports the following error: 


ERROR at line 1: 
ORA-04068: existing state of packages has been discarded 
ORA-04061: existing state of package body "SCOTT.TEST_PKG" has been  invalidated
ORA-04065: not executed, altered or dropped package body "SCOTT.TEST_PKG" 
ORA-06508: PL/SQL: could not find program unit being called: "SCOTT.TEST_PKG" 
ORA-06512: at "SCOTT.TEST_PKG_RUN", line 16 
ORA-06512: at line 1 


The following call to the package works as expected as the ORA-4068 error triggers an in-instantiation of the package. 
This is not a bug.  The only way to force it to clear the package state, recompile the package and load the new instantiation is to allow the ORA-4068 to be raised back to the client.  By trapping it you are signalling to Oracle that you do not want this to happen yet.   


Apart from changing their code the only other option is to use event 10945  that reverts behaviour to 8i so that it will not raise the error at all but carry on using the old copy of the package.  This also means that the package  does not get recompiled on the next call to it in that session.


I would not generally recommend customers do this as, if for instance the application uses connection/session pooling, it could be that some sessions run for a long time using an out of date copy of a package.  


The event can be set at session level via: 
alter session set events = '10945 trace name context forever, level 1'; 


but they'd probably need it set system wide.   


Note, this event only works as long as the old instantiation exists.  If a new session calls the same currently invalid package and therefore recompiles it automatically, or an alter compile is issued, then the event will have no effect on the existing session and the errors will be raised again.   


Using the testcase, with the event set in tc1.sql and the alter compile commented out of tc2.sql the package remains invalid and no errors occur.   


Run the alter compile though and the errors will appear. 

Thursday, April 2, 2009

Viewing Concurrent Requests' output on external viewer stopped working

In e-BS, you have the option to view Reports' output using an external viewer, depending on the output's format.
I got a call saying suddenly users could not view a few Excel Reports. A IE was spawn, but instead of displaying the output, it closed after a few moments.
Nothing was changed in Profile Values and Viewer Options, server side. The funny thing was that it was working for some of my colleagues. The only difference was that they had OS Windows XP SP2. Indeed, users facing the problem had SP3 installed. So, obviously, SP level was the cause.
Since I did not find anything relevant in Metalink, I realized it was one of those cases, where you have to face Microsoft's and Oracle's existential quests, which make our lives so much easier and simpler.
So, I wondered why someone should install a newer SP, according to Microsoft? To make your OS "safer", of course, among other things. After realizing this tremendous fact, I decided to check IE's Security Settings. Since we are facing a download problem, let's view the Downloads Section. "Automatic prompting for file downloads" is disabled?
That looked suspicious. In SP2 its default value is enabled.
So, I enable the option, and problem solved...