Uploaded by Eleodora Lima

Standards for Custom Reports with SAP SuccessFactors Learning Report Designer

advertisement
Standards for Custom Reports with SAP
SuccessFactors Learning Report Designer
TABLE OF CONTENTS
HANDLING DATES AND DATETIME CONVERSIONS............................................................................................. 4
Time Zone Conversion Without Handler Class ................................................................................................ 4
SCRIPT GUIDELINES ................................................................................................................................................... 5
Exporting the Standard Report to Import as Custom Report ........................................................................ 5
Do Not Write Queries that Result in Out of Memory ....................................................................................... 5
Use Column Names in Place of * for Select clause ......................................................................................... 5
Do Not Use Count(*), count(distinct (select ... ................................................................................................ 6
Use Different Alias Names for Tables ................................................................................................................ 8
Add Table Alias Names to Columns Used in JOIN Conditions ...................................................................... 8
Do Not Use WITH Clause inside FROM and JOIN Condition............................................................................. 9
Handling Connect by Queries - Example 1: .................................................................................................... 10
Handling Connect by Queries - Example 2: .................................................................................................... 12
Do Not Use LISTAGG ............................................................................................................................................ 12
Do Not Use DBMS_LOB .......................................................................................................................................... 13
Do Not Use Inner Keyword .............................................................................................................................. 13
Do Not Use WM_CONCAT ........................................................................................................................................ 13
Do Not Use UNIQUE keyword .............................................................................................................................. 13
Do Not Use LOCATION Keyword as Alias .......................................................................................................... 14
Do Not Use INSTR2 .............................................................................................................................................. 14
Do Not Put Spaces in Logical Operators......................................................................................................... 14
Do Not Use Parentheses for Group By Clauses with Multiple Columns.................................................... 14
Do Not Select All Columns................................................................................................................................. 14
Use NVARCHAR Instead of varchar2 in Cast Functions .................................................................................. 15
Aliases with Special Characters ....................................................................................................................... 15
Do Not Use Columns Names with Table Names ............................................................................................ 15
Use Consistent Data Types between DB Column Type and Report Designer Column Type ................ 15
Do Not Use Case Statements with Mixed Datatypes..................................................................................... 15
Using Keywords LIMIT and CURRENT_DATE as Aliases .................................................................................. 16
Column Names in rptdesign file ....................................................................................................................... 16
Do Not Use '&' in Column Alias......................................................................................................................... 16
Do Not Use Group By with Multiple Columns Inside Parentheses ............................................................. 16
Using milliseconds functions............................................................................................................................ 16
Do Not Use CAST_TO_RAW in UTL_RAW .............................................................................................................. 17
Using Federal Customers Functions ............................................................................................................... 17
Using pkg_student.get_delm_stud_qual_stat_rmday .................................................................................. 17
Using Functions that Occur in Select .............................................................................................................. 17
Using Functions that Occur in a Where Clause ............................................................................................. 18
Parameters in the Function ............................................................................................................................... 18
2
Using a Function Wrapped with a System Function ..................................................................................... 19
Using Functions Above Multiple Unions ......................................................................................................... 20
System Tables ...................................................................................................................................................... 20
Using a Column Alias ......................................................................................................................................... 21
Using a Table Alias.............................................................................................................................................. 21
Using a Column Alias with an Apostrophe ..................................................................................................... 21
Using a Numeric Function with SUBSTR ........................................................................................................ 21
Queries that Result in Out of Memory – Example 1: ..................................................................................... 21
Queries that Result in Out of Memory – Example 2: ..................................................................................... 22
3
We continue to optimize the performance and utilization of the SAP SuccessFactors Learning Report
Designer. As such, ANSI SQL is our mandatory standard for SAP SuccessFactors Learning Report Designer.
When you write report SQL in ANSI SQL, we have a higher confidence that those reports will deliver accurate
and consistent results. Dates and datetime conversions may require changes in your reports. Please review
guidance below on handling dates and datetime conversion.
HANDLING DATES AND DATETIME CONVERSIONS
Time zone conversion can be difficult when you write a custom report in Learning. In general, please follow this
standard: start with UTC and convert the date-times into the correct time zone for the user. This applies to datetime fields:
· Date-time fields (as opposed to date fields) appear to report readers in UTC by default.
- If you apply explicit BIRT time zone conversion to a date-time field, the report honors the conversion:
readers of the reports see the date-time converted.
- Do not for example, assume that you can rely on the time zone of the data center. Instead, assume that
the raw date-time is in UTC.
· Date fields (as opposed to date-time fields) should not have a time zone conversion
- For example, assignment date is a date field, so it does not require time zone conversion.
- Do not use the BIRT operator for time zone conversion on date fields because time zones make sense
for date-time fields only.
Time Zone Conversion Without Handler Class
You can use the following function to convert from UTC to your preferred time zone:
pkg_tool_get_new_date(column, 'UTC' ,'America/New_York') alias
column - The column name you want to convert (This must be date time field only)
UTC - The current time zone, which always remains the same
America/New_York - The target time zone you want to convert to
alias - The alias you want to give to your column
Example:
SELECT STUD_ID,
CPNT_ID,
pkg_tool_get_new_date(COMPL_DTE, 'UTC', 'America/New_York') COMPL_DTE
FROM pa_cbt_stud_cpnt;
Note:
The target time zone should be from the list of time zones available in the system. This time zone can be
checked from the Learning Admin Application.
Log in as an Admin and navigate to References > Calendars & Time > Timezone Management
4
SCRIPT GUIDELINES
Follow these guidelines when writing SQL script for custom reports.
Exporting the Standard Report to Import as Custom Report
You may use a standard report and modify it for your own customized use. If your reports were updated, please
remember to export and then make changes. Modified reports are your responsibility going forward.
To export the standard report and import it as a custom report, you need to replace the following statement:
var hanaDBDialectEnabled = session.getAttribute("HanaDBDialectEnabled");
to
var hanaDBDialectEnabled = session.getAttribute("CustomReportHanaDBDialectEnabled
Example:
<method name="beforeFactory"><![CDATA[
importPackage(Packages.com.plateausystems.elms.framework.report.impl)
importPackage(Packages.javax.servlet.http)
importPackage(Packages.javax.servlet)
var reportContext1 = reportContext.getAppContext().get("REPORT_CONTEXT");
var session = reportContext1.session;
var hanaDBDialectEnabled = session.getAttribute("CustomReportHanaDBDialectEnabled");
if( hanaDBDialectEnabled ){
ds =
reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("Learning_Table")
ds.setProperty( "dataSet", "DataSet_Hana" );
}else{
ds =
reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("Learning_Table")
ds.setProperty( "dataSet", "DataSet" );
Do Not Write Queries that Result in Out of Memory
Do not use projection SELECT statements within a projection SELECT statement.
Instead use a JOIN (FROM Clause) or a WITH clause.
Use Column Names in Place of * for Select clause
Previous Script
select * from pa_cpnt_doc
5
Standard Script
select CPNT_ID,
CPNT_TYP_ID,
REV_DTE,
DOC_ID,
REVIEW_FLG,
LST_UPD_USR,
LST_UPD_TSTMP from pa_cpnt_doc
Do Not Use Count(*), count(distinct (select ...
Previous Script
select
*
from ( select
(row_number() over()) row_num,
cpnt_typ_id,
record_num,
course_num,
session_num,
manday
from ( select
coalesce(evt.cpnt_typ_id,
'Grand Total') cpnt_typ_id,
count(*) record_num,
count(distinct IFNULL(to_char(evt.cpnt_typ_id),
'') || IFNULL(to_char(evt.cpnt_id),
'')) course_num,
count(distinct (select
schd_id
from pa_sched
where schd_id = evt.schd_id
and cancelled <> 'Y'
and (closed_date is null
OR LENGTH( closed_date) = 0 ))) session_num,
round(sum(to_number(coalesce(evt.cpe_hrs,
0) + coalesce(evt.credit_hrs,
0) + coalesce(evt.contact_hrs,
0)))/6,
2) manday
from pa_cpnt_evthst evt join pa_student stud on stud.stud_id = evt.stud_id join
pa_cpnt cpnt on cpnt.cpnt_typ_id = evt.cpnt_typ_id
and cpnt.cpnt_id = evt.cpnt_id
and cpnt.rev_dte = evt.rev_dte
where lower(evt.cmpl_stat_id) like '%_complete%'
and (coalesce(evt.cpe_hrs,
0) + coalesce(evt.credit_hrs,
6
0) + coalesce(evt.contact_hrs,
0)) > 0
and evt.compl_dte >= ?
and not (PKG_SQL_SUBTRACT_SECONDS ( evt.compl_dte,
86399 ) ) > ?
group by rollup(evt.cpnt_typ_id)
order by lower(evt.cpnt_typ_id) NULLS LAST ) )
Standard Script
select
*
from ( select
(row_number() over()) row_num,
cmpty_skill,
record_num,
course_num,
session_num,
manday
from ( select
coalesce(cpnt.cmpty_skill,
'Grand Total') cmpty_skill,
count(distinct IFNULL(to_char(evt.cpnt_typ_id),
'') || IFNULL(to_char(evt.cpnt_id),
'')) course_num,
count(distinct (select
schd_id
from pa_sched
where schd_id = evt.schd_id
and (closed_date is null
OR LENGTH( closed_date) = 0 )
and cancelled <> 'Y')) session_num,
count(*) record_num,
round(sum(to_number(coalesce(evt.cpe_hrs,
0) + coalesce(evt.credit_hrs,
0) + coalesce(evt.contact_hrs,
0)))/6,
2) manday
from pa_cpnt_evthst evt join (select
cp.cpnt_typ_id,
cp.cpnt_id,
cp.rev_dte,
cpus.user_value cmpty_skill
from pa_cpnt cp
left join pa_cpnt_user cpus on cpus.cpnt_typ_id = cp.cpnt_typ_id
and cpus.cpnt_id = cp.cpnt_id
and cpus.rev_dte = cp.rev_dte
where cpus.col_num = '10' ) cpnt on cpnt.cpnt_typ_id = evt.cpnt_typ_id
and cpnt.cpnt_id = evt.cpnt_id
and cpnt.rev_dte = evt.rev_dte
left join pa_sched sch on sch.schd_id = evt.schd_id
join pa_student stud on stud.stud_id = evt.stud_id
7
0) +
0) +
0) >
86399
where (cpnt.cmpty_skill is not null
AND LENGTH( cpnt.cmpty_skill) != 0 )
and lower(evt.cmpl_stat_id) like '%_complete%'
and ( coalesce(evt.cpe_hrs,
coalesce(evt.credit_hrs,
coalesce(evt.contact_hrs,
0 )
and evt.compl_dte >= ?
and not (PKG_SQL_SUBTRACT_SECONDS ( evt.compl_dte,
) ) > ?
group by rollup(cpnt.cmpty_skill)
order by cpnt.cmpty_skill NULLS LAST ) )
Use Different Alias Names for Tables
Do not use the same table alias name for more than one table.
Previous Script
SELECT DISTINCT c.cpnt_typ_id,
c.cpnt_id,
c.rev_dte ,
cs.cpnt_src_desc,
from pa_cpnt,
pa_cpnt_src cs,
pa_cpnt_subj cs,
pa_cpnt_formula cf
where cf.cpnt_typ_id (+) = c.cpnt_typ_id
and
cs.cpnt_id(+)
= c.cpnt_id
Standard Script
SELECT DISTINCT c.cpnt_typ_id,
c.cpnt_id,
c.rev_dte ,
cs.cpnt_src_desc,
from pa_cpnt,
pa_cpnt_src cs,
pa_cpnt_subj cs ,
pa_cpnt_formula cf
where c.cpnt_typ_id = cf.cpnt_typ_id (+)
and
c.cpnt_id
= cs.cpnt_id(+)
Add Table Alias Names to Columns Used in JOIN Conditions
Add a table name alias to a column used in join condition. Column names without an alias are not added in the
join clause condition.
Previous Script
Select
pr.FORMULA,
8
pr.CURRENCY_CODE
From PA_CPNT_FORMULA pr
Where IS_DEFAULT (+) = 'Y'
and
fin_var_id (+) = 'ItemDefaultPublishedPrice'
Standard Script
Select
pr.FORMULA,
pr.CURRENCY_CODE
From PA_CPNT_FORMULA pr
Where pr.IS_DEFAULT (+) = 'Y'
and
pr.fin_var_id (+) = 'ItemDefaultPublishedPrice'
Do Not Use WITH Clause inside FROM and JOIN Condition
Use a SELECT statement in place of a WITH clause when you are inside a FROM and JOIN condition. Use WHERE
to add additional SELECT statements.
Previous Script
SELECT *
FROM
(SELECT *
FROM
(WITH summary AS
(SELECT
sct.*,ROW_NUMBER() OVER(PARTITION BY
sct.sc_stud_id_not_used,sct.CPNT_ID,sct.REV_DTE
ORDER BY sct.req_dte,sct.assgn_dte ASC) AS rk
FROM (SELECT NULL as compl_dte,
NULL as cmpl_stat_id,
NULL as cmpl_stat_desc,sc.cpnt_typ_id,
sc.cpnt_id,
sc.rev_dte,
sc.rtyp_id,
sc.stud_id AS sc_stud_id_not_used,
sc.assgn_dte,
sc.req_dte,
sc.exp_dte
FROM pa_stud_qual_cpnt sc
WHERE (sc.compl_dte IS NULL
OR sc.exp_dte
< CURRENT_DATE
OR sc.retrng_int
> 0)
)sct)
SELECT s.*
FROM summary s WHERE s.rk=1)
)
Standard Script
SELECT *
FROM
(SELECT *
FROM
(SELECT * FROM
(SELECT sct.*,ROW_NUMBER() OVER(PARTITION BY
sct.sc_stud_id_not_used,sct.CPNT_ID,sct.REV_DTE
ORDER BY sct.req_dte,sct.assgn_dte ASC) AS rk
9
FROM (SELECT
NULL as compl_dte,
NULL as cmpl_stat_id,
NULL as cmpl_stat_desc,
sc.cpnt_typ_id,
sc.cpnt_id,
sc.rev_dte,
sc.rtyp_id,
sc.stud_id AS sc_stud_id_not_used,
sc.assgn_dte,
sc.req_dte,
sc.exp_dte
FROM pa_stud_qual_cpnt sc
WHERE (sc.compl_dte IS NULL
OR sc.exp_dte
< CURRENT_DATE
OR sc.retrng_int
> 0)
UNION
SELECT
NULL as compl_dte,
NULL as cmpl_stat_id,
NULL as cmpl_stat_desc,
sc.cpnt_typ_id,
sc.cpnt_id,
sc.rev_dte,
sc.rtyp_id,
sc.stud_id AS sc_stud_id_not_used,
sc.assgn_dte,
sc.req_dte,
NULL AS exp_dte
FROM PV_STUD_COURSE sc
WHERE sc.compl_dte IS NULL
)sct)
WHERE rk=1
))
Do Not Use Oracle Specific Tuning Statements
Examples include:
SET ARRAYSIZE
SET LINESIZE
Handling Connect by Queries - Example 1:
Do not use Connect by Prior. Please use H view expressions.
Previous Script
SELECT
'BOR' as BOR,UPPER(s.STUD_ID) AS eID,LOWER(s.EMAIL_ADDR) AS Email,s.FNAME AS First_Name,s.LNAME AS
Last_Name,tEmployee.USER_VALUE AS Employee_Number,tOrg.ORG_DESC AS Department,tJob.JP_DESC AS
Title,s.Super,s.JP_ID as Job_Code,us.user_desc as Manager_Level_Desc,su.user_value as
Manager_Level_Code,s.dmn_id,s.org_id,tCompany.USER_VALUE AS Company,TO_CHAR(s.Hire_dte, 'YYYY-MMDD') as Hire_Date,s.JL_ID as Job_Location_Id,tLoc.JL_DESC AS
Job_Location_Desc,LEVEL,DECODE(s.NOTACTIVE, 'N', 1, 0) as Active
FROM PA_STUDENT sLEFT JOIN PA_ORG tOrg
on s.ORG_ID = tOrg.ORG_ID
LEFT JOIN PA_STUD_USER tEmployee
10
on s.STUD_ID = tEmployee.STUD_IDAND tEmployee.COL_NUM = 1
LEFT JOIN PA_JOB_POS tJob
ON s.JP_ID = tJob.JP_ID
LEFT JOIN PA_STUDENT tMgr
On s.SUPER = tMgr.STUD_ID
LEFT JOIN PA_STUD_USER su
ON s.STUD_ID = su.STUD_IDAND su.col_num = 2
LEFT JOIN PA_USRRF_STUD us
ON su.user_value = us.user_idand us.col_num = 2
LEFT JOIN PA_STUD_USER tCompany
on s.STUD_ID = tCompany.STUD_IDAND tCompany.COL_NUM = 4
LEFT JOIN PA_JOB_LOC tLoc
ON s.JL_ID = tLoc.JL_ID
WHERE s.SUPER != 'PLATEAU'
-- AND s.EMAIL_ADDR is not null-- AND s.NOTACTIVE = 'N'AND LOWER(s.EMAIL_ADDR) NOT IN
('conversion@invalid.com', 'invalid@sap.com')/**and [security:PA_STUDENT s]/START WITH
UPPER(s.STUD_ID) = 'OJG777'CONNECT BY PRIOR UPPER(s.STUD_ID) = UPPER(s.SUPER)ORDER SIBLINGS BY
s.LNAME
Standard Script
SELECT
'BOR' as BOR,
UPPER(s.STUD_ID) AS eID,
LOWER(s.EMAIL_ADDR) AS Email,
s.FNAME AS First_Name,
s.LNAME AS Last_Name,
tEmployee.USER_VALUE AS Employee_Number,
tOrg.ORG_DESC AS Department,
tJob.JP_DESC AS Title,
s.Super,
s.JP_ID as Job_Code,
us.user_desc as Manager_Level_Desc,
su.user_value as Manager_Level_Code,
s.dmn_id,
s.org_id,
tCompany.USER_VALUE AS Company,
TO_CHAR(s.Hire_dte, 'YYYY-MM-DD') as Hire_Date,
s.JL_ID as Job_Location_Id,
tLoc.JL_DESC AS Job_Location_Desc,
LEVEL,
MAP(s.NOTACTIVE, 'N', 1, 0) as Active
FROM PA_STUDENT s
LEFT JOIN PA_ORG tOrg
on s.ORG_ID = tOrg.ORG_ID
LEFT JOIN PA_STUD_USER tEmployee
on s.STUD_ID = tEmployee.STUD_ID
AND tEmployee.COL_NUM = 1
LEFT JOIN PA_JOB_POS tJob
ON s.JP_ID = tJob.JP_ID
LEFT JOIN PA_STUDENT tMgr
On s.SUPER = tMgr.STUD_ID
LEFT JOIN PA_STUD_USER su
ON s.STUD_ID = su.STUD_ID
AND su.col_num = 2
LEFT JOIN PA_USRRF_STUD us
11
ON su.user_value = us.user_id
and us.col_num = 2
LEFT JOIN PA_STUD_USER tCompany
on s.STUD_ID = tCompany.STUD_ID
AND tCompany.COL_NUM = 4
LEFT JOIN PA_JOB_LOC tLoc
ON s.JL_ID = tLoc.JL_ID,
(
SELECT * FROM pa_student_super_hview( "EXPRESSION"=>'subtree("OJG777")' )
)STUD
WHERE s.SUPER != 'PLATEAU'
AND
-- AND s.EMAIL_ADDR is not null
-- AND s.NOTACTIVE = 'N'
S.STUD_ID = STUD.RESULT_NODE
AND
LOWER(s.EMAIL_ADDR) NOT IN ('conversion@invalid.com', 'invalid@sap.com);
/**
and [security:PA_STUDENT s]
Handling Connect by Queries - Example 2:
Previous Script
SELECT
level l,s.stud_id,s.super,sys_connect_by_path(stud_id,' ; ') AS manager_hierarchyFROMpa_student s
CONNECT BY
PRIOR s.stud_id = s.super
Standard Script
SELECT
stud.level l,s.stud_id,s.super,replace(stud.path,'/',';') AS manager_hierarchy
FROM
pa_student s,pa_student_super_hview stud
WHERE
s.stud_id = stud.result_node
Do Not Use LISTAGG
Use STRING_AGG instead.
Previous Script
LISTAGG(ap.ap_desc, ' | ') WITHIN GROUP( ORDER BY ap.ap_desc) FROM pa_assgn_prfl ap,
pa_stud_assgn_prfl sap WHERE 1 = 1 AND ap.ap_id = sap.ap_id AND sap.stud_id = 'stud101'
Standard Script
STRING_AGG(ap.ap_desc, ' | ' ORDER BY ap.ap_desc) from PA_ASSGN_PRFL ap , PA_STUD_ASSGN_PRFL sap
where 1=1 and ap.ap_id = sap.ap_id and sap.stud_id = 'stud123'
12
Do Not Use DBMS_LOB
Use SUBSTR instead.
Previous Script
SELECT
dbms_lob.substr(cbt.activity_tree,4000,1) activity_tree from pa_cbt_cpnt cbt where
dbms_lob.substr(cbt.activity_tree,4000,1) IS NOT NULL
Standard Script
substr(cbt.activity_tree,4000,1) activity_tree from pa_cbt_cpnt cbt where
substr(cbt.activity_tree,4000,1) IS NOT NULL
Do Not Use Inner Keyword
Inner is a reserved keyword.
Previous Script
SELECT inner.* --,
SUBSTR(status_remday, 1,1) AS COMPLETE, -- SUBSTR(status_remday, INSTR(status_remday,'|',1)+1)
Standard Script
SELECT inner1.* --,
SUBSTR(status_remday, 1,1) AS COMPLETE, -- SUBSTR(status_remday, INSTR(status_remday,'|',1)+1)
Do Not Use WM_CONCAT
Use STRING_AGG instead.
Previous Script
select WM_CONCAT (dept_name,' , ' ) from department
Standard Script
select STRING_AGG(dept_name,' , ' ) from department
Do Not Use UNIQUE keyword
Use DISTINCT instead.
Previous Script
SELECT UNIQUE stud_id FROM pa_student ;
Standard Script
SELECT DISTINCT stud_id FROM pa_student ;
13
Do Not Use LOCATION Keyword as Alias
Use another string as the alias.
Previous Script
select stud_id from pa_student location;
Standard Script
select stud_id from pa_student my_alias;
Do Not Use INSTR2
Use INSTR instead.
Previous Script
select instr2('demostring','d',1,1) from dual;
Standard Script
select instr('demostring','d',1,1) from dummy;
Do Not Put Spaces in Logical Operators
For example, if you have != or <=, do not put a space between ! and =
Previous Script
SELECT * from pa_student where pa_stud ! = 'AA';
Standard Script
SELECT * from pa_student where pa_stud != 'AA';
Do Not Use Parentheses for Group By Clauses with Multiple Columns
Previous Script
select stud.stud_id,stud.fname from pa_student stud group by (stud.stud_id, stud.fname)
Standard Script
select stud.stud_id,stud.fname from pa_student stud group by stud.stud_id, stud.fname
Do Not Select All Columns
Select only the required columns.
14
Previous Script
select * from pa_student
Standard Script
select stud_id from pa_student
Use NVARCHAR Instead of varchar2 in Cast Functions
Previous Script
select cast(job_id as varchar2(4000) from dual;
Standard Script
select cast(job_id as NVARCHAR(4000) from dummy;
Aliases with Special Characters
Use double quotation marks around a column alias with special characters.
Previous Script
select su.user_value from pa_stud_user su where col_num = 130 and c.stud_id = su.stud_id) as
Chaveárquico;
Standard Script
Select su.user_value from pa_stud_user su where col_num = 130 and c.stud_id = su.stud_id) as
"CHAVEÁRQUICO";
Do Not Use Columns Names with Table Names
Avoid using a table name with column names in SELECT statements. It adds unwanted schema name in the
alias.
For example, do not use the following:
SELECT PA_INST.FNAME from PA_INST
Use Consistent Data Types between DB Column Type and Report Designer Column Type
Note the DATE field in the bounded column and the DATE-TIME in result set columns within RPTDESIGN.
Do Not Use Case Statements with Mixed Datatypes.
Use the to_char function in cases with mixed data types. For example, if the case statement resulting in a single
column has integer and string values.
15
Previous Script
select decode(eq.ATTEMPT_LIMIT, '0', 'Unlimited', eq.ATTEMPT_LIMIT) as ATTEMPT_LIMITS from
PA_EQB_QUIZ eq
Standard Script
select * from (select (case when eq.ATTEMPT_LIMIT='0' then 'Unlimited' else
to_char(eq.ATTEMPT_LIMIT) end) as ATTEMPT_LIMITS from PA_EQB_QUIZ eq )
Using Keywords LIMIT and CURRENT_DATE as Aliases
Use double quotation marks when using keywords like LIMIT and CURRENT_DATE as aliases.
Previous Script
select LIMIT from PA_TRAINING_REQUEST_LIMIT;
Standard Script
select "LIMIT" from PA_TRAINING_REQUEST_LIMIT;
Column Names in rptdesign file
Use upper case for column names in rptdesign file while mapping.
Do Not Use '&' in Column Alias
Do not use '&' in column alias in SQL and in rptdesign file.
Do Not Use Group By with Multiple Columns Inside Parentheses
Previous Script
select stud_id,fname from pa_student group by (stud_id,fname)
Standard Script
select stud_id,fname from pa_student group by stud_id,fname
Using milliseconds functions
Previous Script
TimezoneUtil.getMillis(rev_dte)
16
Standard Script
SECONDS_BETWEEN(TO_TIMESTAMP('1970-01-01 00:00:00'),c.rev_dte)*1000
Do Not Use CAST_TO_RAW in UTL_RAW
Previous Script
DBMS_LOB.INSTR (CSCMB.BOOKMARK, UTL_RAW.CAST_TO_RAW ('SStart;;'),
1, 1) SSTART
Standard Script
BINTOSTR(CAST(INSTR(BINTOSTR(CAST(CSCMB.BOOKMARK AS BINARY)),BINTOSTR(CAST('SStart;;' AS
BINARY)),1,1) AS BINARY)) SSTART
Using Federal Customers Functions
This function is specifically used by federal customers and its equivalent is not available in our standard.
PKG_CONN_EHRI_ENCRYPTION.ENCRYPT
Using pkg_student.get_delm_stud_qual_stat_rmday
This function is not recommended to be used due to performance issues
Using Functions that Occur in Select
Previous Script
select LIMIT from PA_TRAINING_REQUEST_LIMIT;
select pkg_student.get_delm_stud_qual_stat_rmday (sq.stud_id, sq.qual_id, sq.qual_id_root) AS
status_remday from PA_STUD_QUAL_CPNT sqc, PV_COURSE cpt, PA_CMPL_STAT cs,
PV_STUD_USER
PSU,
pa_student s, pa_user_preference userPref, pa_qual q
Standard Script
select stud_qual_remday.var AS status_remday from PA_STUD_QUAL_CPNT sqc right outer join ( select
sq.stud_id, sq.qual_id, sq.assgn_dte, sq.qual_id_root,
row_number() over (partition by
sq.stud_id,sq.qual_id order by sq.assgn_dte) rnum
from ( select
sq.stud_id,sq.qual_id,sq.assgn_dte,sq.qual_id as qual_id_root
from pa_stud_qual
sq
where 1=1
) sq
) sq on sqc.STUD_ID = sq.stud_id and
sqc.QUAL_ID = sq.qual_id and sqc.QUAL_ID_ROOT = sq.qual_id_root left outer join
pkg_student_get_delm_stud_qual_stat_rmday_tab() stud_qual_remday on sq.qual_id =
17
stud_qual_remday.qual_id and sq.stud_id = stud_qual_remday.stud_id and sq.qual_id_root =
stud_qual_remday.qual_id_root , PV_COURSE cpt, PA_CMPL_STAT cs, PV_STUD_USER PSU, pa_student s,
pa_user_preference userPref, pa_qual q where sq.rnum = 1
and sq.qual_id = q.qual_id
Using Functions that Occur in a Where Clause
Previous Script
select * from PA_STUD_QUAL_CPNT sqc, PV_COURSE cpt, PA_CMPL_STAT cs,
PV_STUD_USER PSU,
pa_student s, pa_user_preference userPref, pa_qual q,
PA_STUD_QUAL_CPNT sq where sqc.STUD_ID
(+)= sq.stud_id
and sqc.QUAL_ID (+)= sq.qual_id
and sqc.QUAL_ID_ROOT(+) = sq.qual_id_root
and
pkg_student.get_delm_stud_qual_stat_rmday (sq.stud_id, sq.qual_id, sq.qual_id_root) = 'status'
OR
PKG_STUDENT.get_delm_stud_qual_stat_rmday(sq.stud_id, sq.qual_id, sq.qual_id_root) = 'j'
and
sq.qual_id = q.qual_id
Standard Script
select sqc.*,cpt.*,cs.*,PSU.*,s.*,userPref.*,q.*,sq.* from PA_STUD_QUAL_CPNT sqc right outer join
PA_STUD_QUAL_CPNT sq on sqc.STUD_ID = sq.stud_id and sqc.QUAL_ID = sq.qual_id and sqc.QUAL_ID_ROOT =
sq.qual_id_root left outer join pkg_student_get_delm_stud_qual_stat_rmday_tab() stud_qual_remday on
sq.qual_id = stud_qual_remday.qual_id and sq.stud_id = stud_qual_remday.stud_id and sq.qual_id_root
= stud_qual_remday.qual_id_root , PV_COURSE cpt, PA_CMPL_STAT cs, PV_STUD_USER PSU, pa_student s,
pa_user_preference userPref, pa_qual q where stud_qual_remday.var = 'status'
OR
stud_qual_remday.var = 'j'
and sq.qual_id = q.qual_id
Parameters in the Function
Parameters should have the same aliasing to be handled by the converter.
Previous Script
- pkg_student.get_delm_stud_qual_stat_rmday (q.stud_id, q.qual_id, q.qual_id)-Handled
-pkg_student.get_delm_stud_qual_stat_rmday (sq.stud_id, q.qual_id, q.qual_id) - Not Handled
-pkg_student.get_delm_stud_qual_stat_rmday (q.stud_id, q.qual_id, q.qual_id_root)-Handled
-pkg_student.get_delm_stud_qual_stat_rmday (sq.stud_id, q.qual_id, sq.qual_id_root)-Not Handled
-pkg_student.get_delm_stud_qual_stat_rmday (sq.stud_id, q.qual_id_sub, sq.qual_id_root)-Not Handled
Standard Script
select * from pa_stud_qual sq, pa_qual q left outer join
pkg_student_get_delm_stud_qual_stat_rmday_tab() stud_qual_remday on q.qual_id =
stud_qual_remday.qual_id and q.stud_id = stud_qual_remday.stud_id and q.qual_id_root =
stud_qual_remday.qual_id_root
18
Using a Function Wrapped with a System Function
NVL,SUBSTR,INSTR are normally used functions within which the get_delm_stud_qual_stat_rmday is used
Previous Script
SELECT DISTINCT
to_char(sysdate,'DD/MM/YYYY HH24:MI:SS') DATA_ESTRAZIONE,
q.qual_id AS qual_id,
sq.stud_id,
decode(SUBSTR(pkg_student.get_delm_stud_qual_stat_rmday(sq.stud_id, sq.qual_id, sq.qual_id),
1,1),'N','NO','Y','SI') AS COMPLETED
FROM pa_stud_qual sq,
pa_student s,
pa_qual q
WHERE sq.stud_id
= s.stud_id
AND sq.qual_id
= q.qual_id
/**and [security:pa_student s]*/
AND
TO_DATE(sq.LST_UPD_TSTMP, 'dd/mm/RR') <= TO_DATE('30/06/2016', 'dd/mm/RR')
Standard Script
SELECT DISTINCT
to_char(CURRENT_TIMESTAMP,'DD/MM/YYYY HH24:MI:SS') DATA_ESTRAZIONE,
q.qual_id AS qual_id,
sq.stud_id,
(case
when SUBSTR(stud_qual_remday.var, 1,1)='N'
then 'NO'
when SUBSTR(stud_qual_remday.var, 1,1)='Y'
then 'SI'
end) AS COMPLETED
FROM pa_stud_qual sq
left outer join pkg_student_get_delm_stud_qual_stat_rmday_tab() stud_qual_remday on sq.qual_id
= stud_qual_remday.qual_id and sq.stud_id = stud_qual_remday.stud_id and sq.qual_id =
stud_qual_remday.qual_id_root
, pa_student s,
pa_qual q
WHERE sq.stud_id
AND sq.qual_id
= s.stud_id
= q.qual_id
/**and [security:pa_student s]*/
AND to_timestamp(to_char(sq.LST_UPD_TSTMP, 'dd/mm/YYYY'),'dd/mm/YYYY') >
to_timestamp('30/06/2016', 'dd/mm/YYYY')
19
Using Functions Above Multiple Unions
Previous Script
SELECT inner.*,
pkg_student.get_delm_stud_qual_stat_rmday(inner.stud_id, inner.qual_id, inner.qual_id) AS
status_remday
FROM
(
SELECT *
FROM
(SELECT *
FROM
(SELECT st.stud_id,
st.super,Standard Script
select sqc.*,cpt.*,
Standard Script
SELECT inner.*,
SELECT innerHana7uobXetXQi.*,
stud_qual_remday.var AS status_remday
FROM
(.......
) innerHana7uobXetXQi
left outer join pkg_student_get_delm_stud_qual_stat_rmday_tab /*HANAVIEW_EXPRESSION ()
stud_qual_remday
*/
on innerHana7uobXetXQi.qual_id = stud_qual_remday.qual_id
and innerHana7uobXetXQi.stud_id = stud_qual_remday.stud_id
and innerHana7uobXetXQi.qual_id = stud_qual_remday.qual_id_root
) innerHana7uobXetXQi_1
System Tables
Using the following table will result in an error when executing reports:
ALL_TAB_COLUMNS , USER_TABLES ,USER_TAB_COLUMNS ,USER_TABLESPACES ,USER_TS_QUOTAS
,USER_CONSTRAINTS
20
Using a Column Alias
PA_, PV_ , PKG_, PH_ , PS_
The column alias should not be starting with the value column.
Using a Table Alias
PA_, PV_ , PKG_, PH_ , PS_
The table alias should not be starting with the value column.
Using a Column Alias with an Apostrophe
Do not use an apostrophe in a column alias. This breaks the schema object strategy in the converter and
the schema name may not appear in the query as expected.
Ex: Instructor’s name
Using a Numeric Function with SUBSTR
TO_NUMBER(SUBSTR(status_remday, INSTR(status_remday,'|',1)+1))
TO_NUMBER expects a number or null argument. If the SUBSTR function returns an empty string, the
query will fail.
Queries that Result in Out of Memory – Example 1:
Do not use projection SELECT statements within a projection SELECT statement.
Instead use a JOIN (FROM Clause) or a WITH clause.
Previous Script
SELECT
S.FNAME STUD_FNAME,
S.LNAME STUD_LNAME,
S.MI STUD_MI,
(SELECT COUNT(*) AS TotalSurveys
FROM PA_STUD_SURVEY pss,
PA_CPNT_SURVEY psc
WHERE psc.CPNT_SURVEY_ID = pss.CPNT_SURVEY_ID
AND psc.survey_id
= QS.survey_id
) TOTAL_SURVEY,
(SELECT COUNT(*) AS TotalSurveys
FROM PA_STUD_SURVEY pss,
PA_CPNT_SURVEY psc
WHERE psc.CPNT_SURVEY_ID = pss.CPNT_SURVEY_ID
AND psc.survey_id
= QS.survey_id
AND pss.survey_status_id = 'COMPLETED'
) COMPLETED_SURVEY,
21
SS.SCH_ID SCHDULE_OFFERING,
SR.STUD_COMMENTS STUDENT_COMMENTS,
FROM PA_QUESTIONNAIRE_SURVEY QS
LEFT OUTER JOIN PA_CPNT_SURVEY CS
ON QS.SURVEY_ID = CS.SURVEY_ID
RIGHT OUTER JOIN PA_STUD_SURVEY SS
ON CS.CPNT_SURVEY_ID=SS.CPNT_SURVEY_ID
Standard Script
WITH TOTAL_SURVEY_q1
as
(
SELECT count(*) cnt ,psc.survey_id
FROM PA_STUD_SURVEY pss,
PA_CPNT_SURVEY psc
WHERE psc.CPNT_SURVEY_ID = pss.CPNT_SURVEY_ID
group by psc.survey_id
),
COMPLETED_SURVEY_q2
as
(
SELECT COUNT(*) cnt ,psc.survey_id
FROM PA_STUD_SURVEY pss,
PA_CPNT_SURVEY psc
WHERE psc.CPNT_SURVEY_ID = pss.CPNT_SURVEY_ID
-- AND psc.survey_id
= QS.survey_id
AND pss.survey_status_id = 'COMPLETED'
group by psc.survey_id
)
SELECT
S.FNAME STUD_FNAME,
S.LNAME STUD_LNAME,
S.MI STUD_MI,
(SELECT cnt AS TotalSurveys
FROM TOTAL_SURVEY_q1 psc
WHERE survey_id
= QS.survey_id
) TOTAL_SURVEY,
(SELECT cnt AS TotalSurveys
FROM COMPLETED_SURVEY_q2 psc
WHERE psc.survey_id
= QS.survey_id
) COMPLETED_SURVEY,
SS.SCH_ID SCHDULE_OFFERING,
SR.STUD_COMMENTS STUDENT_COMMENTS
FROM PA_QUESTIONNAIRE_SURVEY QS
LEFT OUTER JOIN PA_CPNT_SURVEY CS
ON QS.SURVEY_ID = CS.SURVEY_ID
RIGHT OUTER JOIN PA_STUD_SURVEY SS
ON CS.CPNT_SURVEY_ID=SS.CPNT_SURVEY_ID
Queries that Result in Out of Memory – Example 2:
Previous Script
Select
(
22
select user_value from ph_stud_user where stud_id = ST.STUD_ID and col_num
and hist_create_tstmp = (
select max(hist_create_tstmp) from ph_stud_user where stud_id = ST.STUD_ID
hist_create_tstmp <=
(Select min(TX_DATE) from PA_FIN_TX where order_no = FOI.ORDER_NO)
)
)as "Division ID",
(
select user_value from ph_stud_user where stud_id = ST.STUD_ID and col_num
and hist_create_tstmp = (
select max(hist_create_tstmp) from ph_stud_user where stud_id = ST.STUD_ID
hist_create_tstmp <=
(Select min(TX_DATE) from PA_FIN_TX where order_no = FOI.ORDER_NO)
)
) as "Division Desc",
PU.USER_VALUE "Follow Up",
ORG_STRUC1.Team "Team ID",
OTeam.ORG_DESC "Team Name",
FOC.ACCT_ID "Receiver CC (Cost Centre)",
ST.FNAME "Attendee First Name",
ST.LNAME "Attendee Last Name"
From
PA_STUDENT ST,
PA_SHOPPING_ACCT SA,
PA_STUDENT_FIN_ACCT SF,
PA_ENROLL_SEAT ES,
PA_ENROLL_SLOT SL,
PA_FIN_ORDER_ITEM FOI,
PA_SCHED S,
PA_CPNT C,
= 10
and col_num = 30 and
= 30
and col_num = 30 and
Standard Script
Select
(
select user_value from ph_stud_user where stud_id = OUTER2.STUD_ID and col_num = 10
and hist_create_tstmp = OUTER2."Division ID2"
)as "Division ID",
(
select user_value from ph_stud_user where stud_id = OUTER2.STUD_ID and col_num = 30
and hist_create_tstmp = OUTER2."Division Desc2",
) as "Division Desc",
OUTER2."Follow Up",
OUTER2."Team ID",
OUTER2."Team Name",
OUTER2."Receiver CC (Cost Centre)",
OUTER2."Attendee First Name",
OUTER2."Attendee Last Name"
FROM
(
Select
(
select max(hist_create_tstmp) from ph_stud_user where stud_id = OUTER1.STUD_ID and col_num
= 30 and hist_create_tstmp <=
OUTER1."Division ID1"
)as "Division ID2",
23
(
select max(hist_create_tstmp) from ph_stud_user where stud_id = OUTER1.STUD_ID and col_num
= 30 and hist_create_tstmp <=
OUTER1."Division Desc1",
) as "Division Desc2",
OUTER1."Follow Up",
OUTER1."Team ID",
OUTER1."Team Name",
OUTER1."Receiver CC (Cost Centre)",
OUTER1."Attendee First Name",
OUTER1."Attendee Last Name"
from
(
Select
(
(Select min(TX_DATE) from PA_FIN_TX where order_no = FOI.ORDER_NO)
)as "Division ID1",
(
(Select min(TX_DATE) from PA_FIN_TX where order_no = FOI.ORDER_NO)
) as "Division Desc1",
PU.USER_VALUE "Follow Up",
ORG_STRUC1.Team "Team ID",
OTeam.ORG_DESC "Team Name",
FOC.ACCT_ID "Receiver CC (Cost Centre)",
ST.FNAME "Attendee First Name",
ST.LNAME "Attendee Last Name"
From
PA_STUDENT ST,
PA_SHOPPING_ACCT SA,
PA_STUDENT_FIN_ACCT SF,
PA_ENROLL_SEAT ES,
PA_ENROLL_SLOT SL,
PA_FIN_ORDER_ITEM FOI,
PA_SCHED S,
PA_CPNT C,
................
) OUTER1
) OUTER2
24
www.sap.com/contactsap
© 2018 SAP SE or an SAP affiliate company. All rights reserved.
No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP SE or an SAP affiliate company.
The information contained herein may be changed without prior notice. Some software products marketed by SAP SE and its distributors contain proprietary software components of other software vendors.
National product specifications may vary.
These materials are provided by SAP SE or an SAP affiliate company for informational purposes only, without representation or warranty of any kind, and SAP or its affiliated companies shall not be liable
for errors or omissions with respect to the materials. The only warranties for SAP or SAP affiliate company products and services are those that are set forth in the express warranty statements
accompanying such products and services, if any. Nothing herein should be construed as constituting an additional warranty.
In particular, SAP SE or its affiliated companies have no obligation to pursue any course of business outlined in this document or any related presentation, or to develop or release any functionality
mentioned therein. This document, or any related presentation, and SAP SE’s or its affiliated companies’ strategy and possible future developments, products, and/or platform directions and functionality are
all subject to change and may be changed by SAP SE or its affiliated companies at any time for any reason without notice. The information in this document is not a commitment, promise, or legal obligation
to deliver any material, code, or functionality. All forward-looking statements are subject to various risks and uncertainties that could cause actual results to differ materially from expectations. Readers are
cautioned not to place undue reliance on these forward-looking statements, and they should not be relied upon in making purchasing decisions.
SAP and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP SE (or an SAP affiliate company) in Germany and other
countries. All other product and service names mentioned are the trademarks of their respective companies. See http://www.sap.com/corporate-en/legal/copyright/index.epx for additional trademark
information and notices.
Download