Inconsistencies between RPT and SQL*Forms
Date: 1997/03/03
Message-ID: <5fev1e$c8s_at_knot.queensu.ca>
Hello:
Warning: This posting is rather long. But it needs to be, because I'm having one heck of a problem that I'd like to find a solution for. :-(
Basically, using identical code segments and algorithms, I get one result using RPT report writer (ie. the correct results), and inconsistent or inaccurate results using SQL*Forms 3.0 (ie. no data, or missing data). This is driving me nuts, and holding up some query screens I had promised to have ready.
As part of an absence management system I've been developing, I am creating query screens and reports to track employee absences.
I wanted a way to restrict absence data to only those who are authorized to see them (ie. supervisory staff). To do so, I took advantage of some information in our payroll system (a table containing job descriptions, with a "Reports To" field) to ensure this. Here's a brief description:
Financial Services Manager / \ Payroll Accounting Supervisor Supervisor / \ / \ PClerk 1 PClerk 2 AClerk 1 AClerk 2
In my example, the Financial Services manager can see all staff members in the heirarchy. But the Payroll Supervisor can only see the PClerk 1 & 2 employees, while the Accounting Supervisor can only see the AClerk 1 & 2 employees.
I accomplish this, by populating a auth_table containing a list of positions that a given "report runner" (whoever they happen to be in the heirarchical model) can see. After this table is populated, the appropriate report or query screen is executed.
Here is the code I am using to populate the auth_table (you can skip by it if you aren't interested, the code works great):
- begin code snippet ---
/* Create the table of jobs the "report runner" is allowed to see. */ create or replace table fl_absence_reportauth_temp
(job_code varchar2(9), location_code varchar2(8), establishment_code varchar2(8)); /* Insert the "report runner's" info -- he can see his *own* data :-) */ /* The "1" passed parameter is his employee_id #. */insert into fl_absence_reportauth_temp select lpad(&1,9), null, null
from dual;
/* Level 1: People who report directly to the "report runner" */
insert into fl_absence_reportauth_temp
select pos.job_code, pos.location_code, pos.establishment_code
from ec_employee_positions pos
where pos.employee_id = &1
and pos.absn_group_code is not null
and nvl(pos.position_end_date,to_char(sysdate,'YYMMDD')) >=
to_char(sysdate,'YYMMDD')and pos.record_status = 'A';
commit;
/* This is a recursive PL/SQL procedure that then fills the table */ /* with the next n levels, ie. any job which reports to any job */ /* already in the table. :-) */declare
procedure build_reportauth_table(start_count integer) is reportauth_size integer;
begin
select count(*)
into reportauth_size
from fl_absence_reportauth_temp;
if (reportauth_size <> start_count) then
insert into fl_absence_reportauth_temp select opc.job_code, opc.location_code, opc.establishment_code from ec_positions opc, fl_absence_reportauth_temp ath where opc.reporting_job_code = ath.job_code and opc.reporting_location_code = ath.location_code and opc.reporting_establishment_code = ath.establishment_code and 1 not in (select 1 from fl_absence_reportauth_temp tst where tst.job_code = opc.job_code and tst.location_code = opc.location_code and tst.establishment_code = opc.establishment_code) and nvl(opc.position_term_date,to_char(sysdate,'YYMMDD')) >=
to_char(sysdate,'YYMMDD')
and opc.record_status = 'A';
commit;
build_reportauth_table(reportauth_size);
end if;
end;
begin
build_reportauth_table(0);
end;
- end code snippet --
Are you still with me? Ah, you are *most* patient. :-)
When running the above code segment, I will get a table containing the following (example) data:
JOB_CODE LOCATION ESTABLIS
--------- -------- --------
10263 // ID # for "report runner" MANAGER 01 FINANCE // The Financial Services manager SUPERVSR 01 PAYROLL // Supervisor of Payroll SUPERVSR 01 ACCNTNG // Supervisor of Accounting PCLERK 01 PAYROLL // Payroll clerical staff ACLERK 01 ACCNTNG // Accounting clerical staff
Using this data, my reports can then present absence data for any employees having either (a) an employee # that matchs the record with no location or establishment code, or (b) a job, location, and establishment code that matches any in the auth_table. Pretty nifty eh? :-)
The following code, taken from an RPT report, will do just that:
- begin code snippet ---
select pos.employee_id,
rtrim(emp.surname)||', '||rtrim(emp.first_name)||' '||
substr(emp.second_name,1,1)||decode(emp.second_name,NULL,'','.'),
job.description_text
into employee_id, name, job_description
from ec_employee_positions pos, ec_employee emp, ec_jobs job,
fl_absence_reportauth_temp ath
where pos.employee_id = emp.employee_id and pos.absn_group_code is not null and pos.job_code = ath.job_code and pos.location_code = ath.location_code and pos.establishment_code = ath.establishment_codeand nvl(pos.position_end_date,to_char(sysdate,'YYMMDD')) >=
to_char(sysdate,'YYMMDD')
and pos.record_status = 'A'
and pos.job_code = job.job_code
order by emp.surname, emp.first_name, job.description_text;
- end code snippet ---
This works *great*! All my RPT reports produce the correct results. However, plugging this code into the MASTER block of an SQL*Forms 3.0 application, as follows, doesn't give consistant results:
- begin code segment --- DEFINE BLOCK
NAME = MASTER TABLE = FL_ABSENCE_VIEW IN_MENU = OFF ROWS_DISPLAYED = 1 ROWS_BUFFERED = 99 BASE_LINE = 1 LINES_PER_ROW = 0 ARRAY_SIZE = 0 ORDERING = <<< where (employee_id, location_code) in (select pos.employee_id, pos.location_code from ec_employee_positions pos, fl_absence_reportauth_temp ath where pos.location_code = ath.location_code and pos.job_code = ath.job_code and pos.establishment_code = ath.establishment_code and pos.position_start_date <= to_char(sysdate,'YYMMDD') and nvl(pos.position_end_date, to_char(sysdate,'YYMMDD')) >= to_char((sysdate-31),'YYMMDD') and pos.record_status = 'A') and upper(name) like upper(nvl(:MASTER.NAME_DISPLAY,'%')) order by name >>>
- end code segment ---
What's strange about this is, it's so inconsistent! With some "report runners", it works great. With others, it doesn't! In some cases, removing the "order by name" makes the difference (which is completely illogical).
Are there subtle differences between RPT and SQL*Forms implementations of SQL? Any ideas why this is working fine with my RPT files and not with my Forms? They are both using the same authorization information in the same table...
I'm using RPT 1.1.10.3.2. SQL*FORMS 3.0.16.12.0 (with Oracle Toolkit 1.00.20.00.00 and PL/SQL 1.00.35.01.00) Upgrading these are not an option (we are at the mercy of using "supported" released -- supported, that is, by the vendor who writes our business applications.
Thanks in advance...
---------------< LINUX: The choice of a GNU generation. >---------------
Steve Frampton http://qlink.queensu.ca/~3srfWork: <frampton_at_mail.flarc.edu.on.ca> School: <3srf_at_qlink.queensu.ca> --< NOTICE! I do not accept unsolicited commercial e-mail messages! >-- Received on Mon Mar 03 1997 - 00:00:00 CET