Hi Scott,
I was recently troubleshooting why PERS_REFRESH never populated a specific employee data and found the following peoplecode that populates PERSONAL_DATA record in HR. This will give you some insights.
method UpdatePersonalData
/+ &EMPLID as String +/
Local date &DTCHK;
Local Record &Rec_INSTALL_PERSON;
Local Rowset &PER_RS, &NAME_RS, &ADDRH_rS, &ADDRO_RS, &PDE_RS, &USF_rS;
Local Rowset &CAN_RS, &ESP_RS, &DEU_RS, &SA_RS, &USA_RS, &JPN_RS, &ITA_RS, &FRA_RS;
Local Rowset &PD_RS, &PP_RS, &SMOK_RS;
Local Record &PER_REC, &NAME_REC, &ADDRH_REC, &ADDRO_REC, &PDE_REC, &USF_REC;
Local Record &CAN_REC, &ESP_REC, &DEU_REC, &SA_REC, &USA_REC, &JPN_REC, &ITA_REC, &FRA_REC;
Local Record &PD_REC, &PP_REC, &SMOK_REC;
/****************************************************/
If &Rec_INSTALL_PERSON = Null Then
&Rec_INSTALL_PERSON = CreateRecord(Record.PERSON_DT_SETUP);
&Rec_INSTALL_PERSON.SelectByKey();
End-If;
/* Delete the current entry in PS_PERSONAL_DATA */
SQLExec("Delete from PS_PERSONAL_DATA where EMPLID = :1", &EMPLID);
/* Get the PERSON, NAMES, and PERS_DATA_EFFDT data */
/* PERSON, NAMES, PERS_DATA_EFFDT always exist */
&PER_RS = CreateRowset(Record.PERSON);
&PER_RS.Fill("where EMPLID = :1", &EMPLID);
&PER_REC = &PER_RS.GetRow(1).GetRecord(1);
&NAME_RS = CreateRowset(Record.NAMES);
&NAME_RS.Fill("Where FILL.EMPLID = :1 and FILL.NAME_TYPE = 'PRI' and FILL.EFFDT = (SELECT MAX(A.EFFDT) FROM PS_NAMES A WHERE A.EMPLID = FILL.EMPLID AND A.NAME_TYPE = FILL.NAME_TYPE AND A.EFFDT <= %datein(:2))", &EMPLID, %Date);
&NAME_REC = &NAME_RS.GetRow(1).GetRecord(1);
&DTCHK = %Date;
&PDE_RS = CreateRowset(Record.PERS_DATA_EFFDT);
&PDE_RS.Fill("Where EMPLID = :1 and EFFDT = (Select max(EFFDT) from PS_PERS_DATA_EFFDT PDE where PDE.EMPLID = Fill.EMPLID and EFFDT <= %Datein(:2) )", &EMPLID, &DTCHK);
&PDE_REC = &PDE_RS.GetRow(1).GetRecord(1);
/* Set the values in PERSONAL_DATA */
&PD_REC = CreateRecord(Record.PERSONAL_DATA);
&PD_REC.EMPLID.Value = &EMPLID;
&PER_REC.CopyFieldsTo(&PD_REC);
&NAME_REC.CopyFieldsTo(&PD_REC);
&PDE_REC.CopyFieldsTo(&PD_REC);
/* Records that do not always exist */
/*** PERSON_ADDRESS - Home */
If All(&Rec_INSTALL_PERSON.ADDRESS_TYPE.Value) Then
&ADDRH_rS = CreateRowset(Record.PERSON_ADDRESS);
&ADDRH_rS.Fill("Where EMPLID = :1 and ADDRESS_TYPE = :2 ", &EMPLID, &Rec_INSTALL_PERSON.ADDRESS_TYPE.Value);
&ADDRH_REC = &ADDRH_rS.GetRow(1).GetRecord(1);
If All(&ADDRH_REC.EMPLID.Value) Then
&ADDRH_REC.CopyFieldsTo(&PD_REC);
End-If;
End-If;
/*** PERSON_ADDRESS - Other */
If All(&Rec_INSTALL_PERSON.ADDRESS_TYPE_OTH.Value) Then
&ADDRO_RS = CreateRowset(Record.PD_ADDRESS_VW);
&ADDRO_RS.Fill("Where EMPLID = :1 and ADDRESS_TYPE = :2 ", &EMPLID, &Rec_INSTALL_PERSON.ADDRESS_TYPE_OTH.Value);
&ADDRO_REC = &ADDRO_RS.GetRow(1).GetRecord(1);
If All(&ADDRO_REC.EMPLID.Value) Then
&ADDRO_REC.CopyFieldsTo(&PD_REC);
End-If;
End-If;
/*** PERSON_PHONE */
If &Rec_INSTALL_PERSON.PHONE_FLG.Value = "Y" Then
&PP_RS = CreateRowset(Record.PERSON_PHONE);
&PP_RS.Fill("Where EMPLID = :1 ", &EMPLID);
&PP_REC = &PP_RS.GetRow(1).GetRecord(1);
If All(&PP_REC.EMPLID.Value) Then
&PP_REC.CopyFieldsTo(&PD_REC);
End-If;
End-If;
/*** PERS_SMOKER */
If &Rec_INSTALL_PERSON.SMOKER_FLG.Value = "Y" Then
&SMOK_RS = CreateRowset(Record.PERS_SMOKER_VW);
&SMOK_RS.Fill("Where EMPLID = :1 ", &EMPLID);
&SMOK_REC = &SMOK_RS.GetRow(1).GetRecord(1);
If All(&SMOK_REC.EMPLID.Value) Then
&SMOK_REC.CopyFieldsTo(&PD_REC);
End-If;
End-If;
/*** Country Extensions */
If &Rec_INSTALL_PERSON.COUNTRY_FLG.Value = "Y" Then
&USA_RS = CreateRowset(Record.PERS_DATA_USA);
&USA_RS.Fill("Where EMPLID = :1 and EFFDT = (Select max(EFFDT) from PS_PERS_DATA_USA PDE where PDE.EMPLID = Fill.EMPLID and EFFDT <= %Datein(:2))", &EMPLID, &DTCHK);
&CAN_RS = CreateRowset(Record.PERS_DATA_CAN);
&CAN_RS.Fill("Where EMPLID = :1 and EFFDT = (Select max(EFFDT) from PS_PERS_DATA_CAN PDE where PDE.EMPLID = Fill.EMPLID and EFFDT <= %Datein(:2))", &EMPLID, &DTCHK);
&ESP_RS = CreateRowset(Record.PERS_DATA_ESP);
&ESP_RS.Fill("Where EMPLID = :1 and EFFDT = (Select max(EFFDT) from PS_PERS_DATA_ESP PDE where PDE.EMPLID = Fill.EMPLID and EFFDT <= %Datein(:2))", &EMPLID, &DTCHK);
&DEU_RS = CreateRowset(Record.PERS_DATA_DEU);
&DEU_RS.Fill("Where EMPLID = :1 and EFFDT = (Select max(EFFDT) from PS_PERS_DATA_DEU PDE where PDE.EMPLID = Fill.EMPLID and EFFDT <= %Datein(:2))", &EMPLID, &DTCHK);
&JPN_RS = CreateRowset(Record.PERS_DATA_JPN);
&JPN_RS.Fill("Where EMPLID = :1 and EFFDT = (Select max(EFFDT) from PS_PERS_DATA_JPN PDE where PDE.EMPLID = Fill.EMPLID and EFFDT <= %Datein(:2))", &EMPLID, &DTCHK);
&ITA_RS = CreateRowset(Record.PERS_DATA_ITA);
&ITA_RS.Fill("Where EMPLID = :1 and EFFDT = (Select max(EFFDT) from PS_PERS_DATA_ITA PDE where PDE.EMPLID = Fill.EMPLID and EFFDT <= %Datein(:2))", &EMPLID, &DTCHK);
&FRA_RS = CreateRowset(Record.PERS_DATA_FRA);
&FRA_RS.Fill("Where EMPLID = :1 and EFFDT = (Select max(EFFDT) from PS_PERS_DATA_FRA PDE where PDE.EMPLID = Fill.EMPLID and EFFDT <= %Datein(:2))", &EMPLID, &DTCHK);
&ESP_REC = &ESP_RS.GetRow(1).GetRecord(1);
&DEU_REC = &DEU_RS.GetRow(1).GetRecord(1);
&FRA_REC = &FRA_RS.GetRow(1).GetRecord(1);
&JPN_REC = &JPN_RS.GetRow(1).GetRecord(1);
&ITA_REC = &ITA_RS.GetRow(1).GetRecord(1);
&USA_REC = &USA_RS.GetRow(1).GetRecord(1);
&CAN_REC = &CAN_RS.GetRow(1).GetRecord(1);
If All(&ESP_REC.EMPLID.Value) Then
&ESP_REC.CopyFieldsTo(&PD_REC);
End-If;
If All(&DEU_REC.EMPLID.Value) Then
&DEU_REC.CopyFieldsTo(&PD_REC);
End-If;
If All(&FRA_REC.EMPLID.Value) Then
&FRA_REC.CopyFieldsTo(&PD_REC);
End-If;
If All(&JPN_REC.EMPLID.Value) Then
&JPN_REC.CopyFieldsTo(&PD_REC);
End-If;
If All(&ITA_REC.EMPLID.Value) Then
&ITA_REC.CopyFieldsTo(&PD_REC);
End-If;
If All(&USA_REC.EMPLID.Value) Then
&USA_REC.CopyFieldsTo(&PD_REC);
End-If;
If All(&CAN_REC.EMPLID.Value) Then
&CAN_REC.CopyFieldsTo(&PD_REC);
End-If;
End-If;
/** USF Extension */
If &Rec_INSTALL_PERSON.USF_FLG.Value = "Y" Then
&USF_rS = CreateRowset(Record.PERS_DATA_USF);
&USF_rS.Fill("Where EMPLID = :1 and EFFDT = (Select max(EFFDT) from PS_PERS_DATA_USF PDE where PDE.EMPLID = Fill.EMPLID and EFFDT <= %Datein(:2))", &EMPLID, &DTCHK);
&USF_REC = &USF_rS.GetRow(1).GetRecord(1);
If All(&USF_REC.EMPLID.Value) Then
&USF_REC.CopyFieldsTo(&PD_REC);
End-If;
End-If;
/** Campus Solutions Extension */
If &Rec_INSTALL_PERSON.SA_FLG.Value = "Y" Then
&SA_RS = CreateRowset(Record.PERSON_SA);
&SA_RS.Fill("Where EMPLID = :1", &EMPLID);
&SA_REC = &SA_RS.GetRow(1).GetRecord(1);
If All(&SA_REC.EMPLID.Value) Then
&SA_REC.CopyFieldsTo(&PD_REC);
End-If;
End-If;
/* set last update time stamp */
&PD_REC.LASTUPDDTTM.Value = %Datetime;
/************/
/* Insert */
/************/
&PD_REC.Insert();
end-method;
------------------------------
Khaliq Bandagi
PeopleSoft Developer
Long Island University
------------------------------
Message from the HEUG Marketplace:
------------------------------
Find, Review, and Engage with Higher Education-focused solution providers, products, and services using the HEUG Marketplace.
------------------------------
Original Message:
Sent: 11-25-2025 04:42 PM
From: Scott Frey
Subject: PERSONAL_DATA: need mapping to source-fields/records
Thanks Scott.
The Oracle docs don't indicate whether there is a difference between HCM and CS when it comes to the PERS_REFRESH app engine. My assumption is that they are the same.
The Oracle docs also don't mention if PERS_REFRESH is configurable. I was assuming it wasn't and that the field mapping would be the same for all institutions.
Can anyone offer additional insight?
------------------------------
Scott Frey
Senior Data Analyst - Human Resource Information Systems
University of Colorado System
------------------------------
Message from the HEUG Marketplace:
------------------------------
Find, Review, and Engage with Higher Education-focused solution providers, products, and services using the HEUG Marketplace.
Original Message:
Sent: 11-25-2025 03:35 PM
From: Scott Douglas
Subject: PERSONAL_DATA: need mapping to source-fields/records
I don't have mapping for you, but PERSONAL_DATA is populated by application engine PERS_REFRESH, at least on the Campus Solutions side. I imagine it's the same in HCM. We run that refresh on a daily recurrence. If you don't have app designer access, a developer at your institution may be able to help you understand the logic behind it. My recollection is that it's a fairly complicated program, but it's been a while since I've looked at it.
------------------------------
Scott Douglas
Sr. Business Systems Analyst, Student Information Systems
Azusa Pacific University
Original Message:
Sent: 11-24-2025 10:38 AM
From: Scott Frey
Subject: PERSONAL_DATA: need mapping to source-fields/records
Does anyone have documentation, or method for discovering/documenting how and where each field in the PERSONAL_DATA record in Oracle HCM is sourced, without guessing?
Oracle indicates that PERSONAL_DATA is not (or at least is no longer) a parent-record itself. Rather, it is a "transaction record", i.e. an Oracle-delivered "view record" that is updated by a process. All of the fields are thus mapped back to actual parent-records.
I NEED THAT MAPPING.
While I no longer use PERSONAL_DATA in my queries, others do. I need to document exactly what data one of those queries is returning.
Thanks for your help,
------------------------------
Scott Frey
Senior Data Analyst - Human Resource Information Systems
University of Colorado System
------------------------------
Message from the HEUG Marketplace:
------------------------------
Find, Review, and Engage with Higher Education-focused solution providers, products, and services using the HEUG Marketplace.
------------------------------