The other day, I had trouble logging into Application Designer at a new location. Basically, changing the cache directory is what solved my problem, but here are the details.
Tag: Post Needs to Move
These posts still need to move from Wordpress.com
HCM9.0: Reclaiming Index Space
Analysis
Determining largest indexes by blocks
select index_name, leaf_blocks, num_rows
from dba_indexes
where owner = 'SYSADM'
and leaf_blocks is not null
order by leaf_blocks desc;
Determining indexes with the most free space
I found that the index with the most free space only had 32M free.
select a.owner, a.index_name, a.leaf_blocks, a.num_rows, b.tablespace_name,
b.blocks, b.blocks - a.leaf_blocks free_blocks,
(b.blocks - a.leaf_blocks) * to_number(p.value) / 1024 freespace_k
from dba_indexes a, dba_segments b, v$parameter p
where p.name = 'db_block_size'
and a.owner not in ('SYS', 'SYSTEM')
and a.index_type <> 'BITMAP'
and a.leaf_blocks is not null
and a.owner = b.owner
and a.index_name = b.segment_name
order by free_blocks desc;
Determining index space used by empty tables
One thing I noticed in the previous selection is that a number of indexes were on tables that had no rows, but the index had 128K allocated to them. I found that 21606 indexes matched this scenario totaling about 21G of unused space!
select count(*), sum(b.blocks), sum(b.blocks) * max(to_number(p.value)) / 1024 total_kilobytes
from dba_indexes a, dba_segments b, v$parameter p
where a.index_type <> 'BITMAP"
and a.owner = b.owner
and a.index_name = b.segment_name
and a.leaf_blocks = 0
and a.num_rows = 0
and b.blocks = 128;
Finding the PeopleSoft record name for the Oracle index name
In order to be able to put all of these changes into a PeopleSoft Project, I need to be able to tie the index to a PeopleSoft record. Here is an example join for dba_indexes and PSRECDEFN:
select o.index_name, o.table_name, r.recname
from dba_indexes o, psrecdefn r
where (r.sqltablename = o.table_name or (r.sqltablename = ' ' and o.table_anme = 'PS_' || r.recname))
and rownum < 5;
Creating a Project
I wanted to make PeopleSoft do most of the leg work, and so, my next step was to create a project in Application Designer. This way Application Designer will create all of the project header rows in the database (ex: PSPROJECTDEFN, etc.). I had to add the record for the first index just to be able to save the project. I did all this part manually in Application Designer.
I saved my project as SP_INDEX_REBUILD, but you can choose whatever name you would like. Just make sure that you change the name in the SQL below to the name that you choose.
You can use the first row in the project item table as a template for inserting the rest.
select * from psprojectitem
where projectname = 'SP_INDEX_REBUILD';
So, to insert the rest of the tables into the project, I used the statement in the database:
insert into psprojectitem
select distinct 'SP_INDEX_REBUILD', 0, 1, r.recname, 0, ' ', 0, ' ', 0, ' ', 0, 0, 0, 0, 1, 0
from dba_indexes a, dba_segments b, v$parameter p, psrecdefn r
where (r.sqltablename = a.table_name or (r.sqltablename = ' ' and a.table_name = 'PS_' || r.recname))
and p.name = 'db_block_size'
and a.index_type <> 'BITMAP'
and a.owner = b.owner
and a.index_name = b.segment_name
and a.leaf_blocks = 0
and a.num_rows = 0
and b.blocks = 128
and not exists (select 'x' from psprojectitem where projectname = 'SP_INDEX_REBUILD' and objectvalue1 = r.recname);
Warning: this statement did take some time to run. You may want to see if you can optimize it a little. It took about 20 minutes to complete.
Before I could see the new records attached to the project in Application Designer I had to clear the cache in Configuration Manager.
Inserting Rows for DDL
insert into psidxddlparm
select distinct recname, indexid, 2, 0, 'INIT', 0
from pskeydefn k, psprojectitem p
where k.recname = p.objectvalue1
and p.projectname = 'SP_INDEX_REBUILD'
and not exists (select 'x' from psidxddlparm i
where recname = i.recname
and indexid = i.indexid
and platformid = 2
and parmname = 'INIT');
Updating the rest of the rows
update psidxddlparm
set parmvalue = 0
where recname in (select objectvalue1
from psprojectitem
where objectvalue1 = recname);
Updating the Indexes
I cleared the cache to make sure that Application Designer recognized the new changes that I made in the database.
Then, just changing the indexes is not enough the make Application Designer realize that there is something that needs to be rebuilt. So, you have to change the build properties. On the Alter tab, make sure to “Alter even if no changes”. Then, build the project. I had to use the Alter tables options and not just the Create Indexes option to get it to build.
Added line to init.ora
db_2k_cache_size = 10M
If you don’t add this like, you will get the error message: “ORA-29339: tablespace block size 2048 does not match configure block sizes”.
Creating the new tablespace
create tablespace sp_empty_index
datafile ‘e:\oradata\HCM90\SP_EMPTY_INDEX.DBF’
size 10m
blocksize 2k
extent management local autoallocate
segment space management auto;
ALTER DATABASE DATAFILE ‘e:\oradata\HCM90\SP_EMPTY_INDEX.DBF’
AUTOEXTEND ON NEXT 5M MAXSIZE UNLIMITED;
insert into psidxddlparm
select distinct recname, indexid, 2, 0, ‘INDEXSPC’, ‘sp_empty_index’
from pskeydefn k, psprojectitem p
where k.recname = p.objectvalue1
and p.projectname = ‘SP_INDEX_REBUILD’
and not exists (select ‘x’ from psidxddlparm i
where k.recname = i.recname
and k.indexid = i.indexid
and i.platformid = 2
and i.parmname = ‘INDEXSPC’);
update psidxddlparm
set parmvalue = ‘sp_empty_index’
where recname in (select objectvalue1
from psprojectitem
where objectvalue1 = recname)
and platformid = 2
and parmname = ‘INDEXSPC’;
select ‘alter index sysadm.’ || indexname || ‘ rebuild tablespace sp_empty_index;’
from (select distinct ‘PS’ || indexid || recname as indexname
from pskeydefn
where recname in (select objectvalue1
from psprojectitem
where objectvalue1 = recname)) a;
Reclaiming Space for the File System
I used the notes I made for resizing the database to get the free space to the file system.
PSINDEX was 47.89% free — 13.28G free.
Resources
DBAZine.com: Indexes – Part 2: Is This Index the Right Size?
Troubleshooting: Shift Not Found
Problem
Message: “The shift displayed below was not found”
This problem exists in the demo system for the company DC and paygroup LE2. It could exist in other scenarios, too.
Solution
A row must exist where the SETID matches with the Set Control Value is the PAYGROUP
and the Shift matches the “Message Data” (the shift that it is saying that it is missing)
So, select in the PS_SET_CNTRL_REC where the set control value is your paygroup and the record is the SHIFT_TBL to get the appropriate SETID for the shift you should add.
SELECT * FROM PS_SET_CNTRL_REC WHERE SETCNTRLVALUE = 'LE2' AND RECNAME = 'SHIFT_TBL'
Misc Info
When running payroll:
Set Up HRMS > Product Related > Payroll for North America > Compensation and Earnings > Shift Table
Record/Table: SHIFT_TBL
Set Up HRMS > Product Related > Payroll for North America > Compensation and Earnings > Earnings Table
Resources
Page Update
I have created a list of PeopleTools tables as a quick reference. Please let me know if you want any additional tables or if any of the information is wrong/incomplete.
HCM9.0: Resizing the Virtual Hard Drive
Once I reclaimed the hard drive space from my database, I had to shrink the hard drive in order to get my image smaller. Here is what I did.
Shrinking the Partition
I used a version of Linux called Knoppix. You can download it from here.
I never actually burned the image to CD. I just opened the properties of the CD drive in the virtual machine (while it was shutdown) and told it to use the iso image that I downloaded instead of the physical drive.
Determining the how small you can shrink the drive:
sudo ntfsresize --info /dev/sda1
Changing the size of the drive (test)
sudo ntfsresize --no-action --size=42831122432 /dev/sda1
Changing the size of the drive
sudo ntfsresize --size=42831122432 /dev/sda1
Changing the size of the partition
sudo fdisk /dev/sda
- m for help
- p for print (note the partition number and type/id)
- d for delete
- n for new partition (choose primary and same partition number and desired size +###M)
- t for changing the partition type/id
- p for print ( verify everything is the correct)
- w for write
Shrinking an Unshrinkable Hard Drive
The only way that you can get a smaller hard drive if you can’t shrink the drive is to copy the data to a new virtual drive.
Copy the partition table.
sudo dd if=/dev/sda of=/dev/sdb bs=512 count=1
Copy the partition itself.
sudo dd if=/dev/sda1 of/dev/sdb1
Note: I had to reboot between copying the partition table and the actual partition.
Shrinking a Shrinkable Hard Drive
Shutdown the virtual machine.
From a command window run:
"C:\Program Files\VMware\VMware Server\vmware-mount " m: c:\VirtualMachines\HCM90\Database.vmdk
"C:\Program Files\VMware\VMware Server\vmware-vdiskmanager.exe" -p m:
"C:\Program Files\VMware\VMware Server\vmware-mount " m: /d
"C:\Program Files\VMware\VMware Server\vmware-vdiskmanager.exe" -k WindowsServer2003Standard.vmd
Note: to expand, you would use the -x option
"C:\Program Files\VMware\VMware Server\vmware-vdiskmanager.exe" -x 30Gb WindowsServer2003Standard.vmdk
HCM9.0: Automatic Windows Login for VMWare
You would never want to do this in the corporate world, but with a test VMWare instance, it makes sense. I am already logging into the host machine, and so, why should I log into the VMWare machine again each time that I boot it.
So. I used the link below to have the machine automatically login when it boots:
How to turn on automatic logon in Windows XP
It did work for Windows Server 2003. I used the registry method, but I opened the dialog with the Start > Run … control userpasswords2, and it looked like it would have worked as well.
Response: Array Class Generic Sort
Here is my attempt at providing details in response to an article by ChiliJoe called PeopleCode Array Class’ Generic Sort.
Basically, ChiliJoe is referring to a vague example in PeopleBooks that says, “For example, suppose you want to provide a more generic sort, with comparison function at the end of it.” This is in the section: “When Would You Use Application Classes?“.
The key to this example is that you have to write the sort by extending the array class. Here is an attempt at writing an example:
HCM9.0: Compiling COBOL
Here are the commands that I executed in a command window. Adjust the paths as necessary.
set PS_HOME=c:\pshome\hcm90
set PATH=%ps_home%\src\cbl\win32;%path%
set COBROOT="c:\program files\micro focus\net express\base"
cd %PS_HOME%\setup
cblbld c: \temp\compile
(make sure you have a space between the c: and the \temp\compile)
Here is the output:
ASCII Cobol Compilations Proceeding
Creating Directory c:\temp\compile
Logging progress to file c:\temp\compile\CBLBLD.LOG
COBOL compiler found in “c:\program files\micro focus\net express\base”
The system cannot find the path specified.
Target directory (c:\pshome\hcm90\CBLBINA) exists and is writable
Copying source files …
Building the COBOL targets …
……
That is all there is to it!
HCM9.0: Init Ora File
Here is my Init Ora file for the database of my VMWare image. Hope this helps if you are attempting something similar. This is what I finally got to work during installation.
DB_NAME = hcm90
DB_FILES = 1021
CONTROL_FILES = (E:\oradata\hcm90\CONTROL01.CTL,
E:\oradata\hcm90\CONTROL02.CTL,
E:\oradata\hcm90\CONTROL03.CTL)
OPEN_CURSORS = 255
db_block_size = 8192
UNDO_MANAGEMENT = AUTO
shared_pool_size = 72265318
Note: I am still trying to get the shared pool size to a good number. I have lowered it considerably, but before I post that, I need to work out the kinks. I had to have the shared pool size at 72,265,318 in order to get it to install. When I had it set lower, I got an error message about memory.
Response: Private/Instance Variables
ChiliJoe posted in Access to Instance Variables within the Same Class that an instance can change the value of another instance’s private variable.
At first, this sounds like it doesn’t make sense — an instance shouldn’t be able to access something private to another instance. But, in my opinion, the private is to protect it from code that may not understand or may violate rules the class depends on. From that point of view, it does make sense. Whoever wrote the code for the class knows what the value should be, and therefore, can be trusted to change it. Therefore, it can change any instance’s private variable as long as it is the same class. Whoever wrote the other class may not even be able to look at the code to see if they are going to mess things up, and therefore, cannot access the variable.
I think the PeopleSoft names make it confusing. Instead of calling it private, PeopleCode calls it instance, which would lead you to think that only that instance could access it. Actually, it is private to the class, not the instance.
So, to take the challenge, I translated ChiliJoe’s code to Java just to see if it works the same in Java. It does:
package com.skp.peoplecodejavacompare;
public class Example {
private Example newInstance;
private int num = 0;
public void createNewInstance() {
newInstance = new Example();
}
public int incrementNewInstanceNum() {
newInstance.num++;
return newInstance.num;
}
public int incrementThisInstanceNum() {
num++;
return num;
}
public void incrementPassedNum(Example passed) {
passed.num ++;
}
public int getThisInstanceNum() {
return num;
}
public static void main(String[] args) {
Example test1 = new Example();
test1.createNewInstance();
System.out.println(“incrementNewInstanceNum returns “ + test1.incrementNewInstanceNum());
System.out.println(“getThisInstanceNum returns “ + test1.getThisInstanceNum());
System.out.println(“incrementThisInstanceNum returns “ + test1.incrementThisInstanceNum());
System.out.println(“incrementNewInstanceNum returns “ + test1.incrementNewInstanceNum());
Example test2 = new Example();
System.out.println(“test2.getThisInstanceNum returns “ + test2.getThisInstanceNum());
test1.incrementPassedNum(test2);
System.out.println(“test2.getThisInstanceNum returns “ + test2.getThisInstanceNum());
}
}
Output:
incrementNewInstanceNum returns 1
getThisInstanceNum returns 0
incrementThisInstanceNum returns 1
incrementNewInstanceNum returns 2
test2.getThisInstanceNum returns 0
test2.getThisInstanceNum returns 1