Here’s another problem that I ran into …
COBOL wouldn’t run. Even the simple test didn’t work.
Here’s another problem that I ran into …
COBOL wouldn’t run. Even the simple test didn’t work.
I had an issue with starting a database a while back. Basically, I ran out of resources on the server, and I had to adjust the kernel parameters. Here are the details…
Error message:
ORA-27154: post/wait create failed ORA-27300: OS system dependent operation:semget failed with status: 28 ORA-27301: OS failure message: No space left on device ORA-27302: failure occurred at: sskgpcreates
I’ve been trying to monitor the archive log usage for our databases, and I came up with this little script. I thought I would share in case it would help anyone, but also, please correct me if there is a better way or you see anything wrong.
Here’s the basic version. You can change the database names in the for loop.
tmpfile=/tmp/$(whoami)sql.txt echo "DB_NAME FILE_TYPE PERCENT_SPACE_USED NUMBER_OF_FILES" > $tmpfile echo "------- -------------------- ------------------ ---------------" >> $tmpfile for e in FN91DMO FN91CFG FN91DEV FN91TST do export ORACLE_SID=$e sqlplus -s / as sysdba >> $tmpfile <<! set head off set feedback off select '$e' DB_NAME, FILE_TYPE, PERCENT_SPACE_USED, NUMBER_OF_FILES from v\$flash_recovery_area_usage where PERCENT_SPACE_USED > 0; exit; ! done sed '/^$/d' $tmpfile rm $tmpfile
This next version calls a script to get the database names. For example, I have the databases stored in an XML file, and I built a perl script that would read the XML file and print the database names.
tmpfile=/tmp/$(whoami)sql.txt echo "DB_NAME FILE_TYPE PERCENT_SPACE_USED NUMBER_OF_FILES" > $tmpfile echo "------- -------------------- ------------------ ---------------" >> $tmpfile for e in $(buildDBList) do export ORACLE_SID=$e sqlplus -s / as sysdba >> $tmpfile <<! set head off set feedback off select '$e' DB_NAME, FILE_TYPE, PERCENT_SPACE_USED, NUMBER_OF_FILES from v\$flash_recovery_area_usage where PERCENT_SPACE_USED > 0; exit; ! done sed '/^$/d' $tmpfile rm $tmpfile
Finally, this version calls a script to check the status of the database. If the database is down or temporarily off, it skips that database.
tmpfile=/tmp/$(whoami)sql.txt echo "DB_NAME FILE_TYPE PERCENT_SPACE_USED NUMBER_OF_FILES" > $tmpfile echo "------- -------------------- ------------------ ---------------" >> $tmpfile for e in $(buildDBList) do export ORACLE_SID=$e checkDBStatus $e 2>&1 > /dev/null if [ $? -eq 0 ]; then sqlplus -s / as sysdba >> $tmpfile <<! set head off set feedback off select '$e' DB_NAME, FILE_TYPE, PERCENT_SPACE_USED, NUMBER_OF_FILES from v\$flash_recovery_area_usage where PERCENT_SPACE_USED > 0; exit; ! fi done sed '/^$/d' $tmpfile rm $tmpfile
Here’s a common task: You need to create a database user with read only access. You have some power users who know how to use SQL, and they are allowed to see all of the data in the system. You can use these commands to create such a user (in Oracle):
create user PSRO identified by PSRO; grant create session, select any table, select any dictionary to PSRO;
Note: You can probably find this all over the web, but I wanted to capture it on my blog so that I could find the syntax easier.
Here’s a simple little trick for Application Engines that have Temporary Tables assigned.
When you have temporary tables, you don’t know for sure which Temporary Table it is using. You could write a quick select and change the number on the end until you find the one you are looking for, but here is a slightly quicker method.
Note: This is designed for Oracle, but you could easily change it up to work with SQL Server.
First, build a select statement that will list all of the tables. We’ll assume our Temporary Table Record is MY_TEMP_TAO. You can substitute with your specific record.
SELECT 'UNION SELECT ''' || TABLE_NAME || ''' TBL, A.* FROM SYSADM.' || TABLE_NAME || ' A' FROM DBA_TABLES WHERE table_name LIKE 'PS_MY_TEMP_TAO%';
Update (thanks to Nicolas): You can avoid having to remove the first UNION if you use something more like this:
SELECT 'SELECT ''' || TABLE_NAME || ''' TBL, A.* ' || 'FROM SYSADM.' || TABLE_NAME || ' A' || case when count(*)over()=rownum then ';' else ' UNION ' end FROM ALL_TABLES WHERE table_name LIKE 'PS_MY_TEMP_TAO%';
The output should look something like this:
UNION SELECT 'PS_MY_TEMP_TAO' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO A UNION SELECT 'PS_MY_TEMP_TAO1' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO1 A UNION SELECT 'PS_MY_TEMP_TAO2' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO2 A UNION SELECT 'PS_MY_TEMP_TAO3' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO3 A UNION SELECT 'PS_MY_TEMP_TAO4' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO4 A UNION SELECT 'PS_MY_TEMP_TAO5' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO5 A UNION SELECT 'PS_MY_TEMP_TAO6' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO6 A;
You just simply need to delete the first Union to make something like this:
SELECT 'PS_MY_TEMP_TAO' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO A UNION SELECT 'PS_MY_TEMP_TAO1' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO1 A UNION SELECT 'PS_MY_TEMP_TAO2' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO2 A UNION SELECT 'PS_MY_TEMP_TAO3' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO3 A UNION SELECT 'PS_MY_TEMP_TAO4' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO4 A UNION SELECT 'PS_MY_TEMP_TAO5' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO5 A UNION SELECT 'PS_MY_TEMP_TAO6' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO6 A;
If you know your temp table has the process instance as the key and you know the one you are looking for, you could do something like this:
SELECT * FROM ( SELECT 'PS_MY_TEMP_TAO' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO A UNION SELECT 'PS_MY_TEMP_TAO1' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO1 A UNION SELECT 'PS_MY_TEMP_TAO2' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO2 A UNION SELECT 'PS_MY_TEMP_TAO3' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO3 A UNION SELECT 'PS_MY_TEMP_TAO4' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO4 A UNION SELECT 'PS_MY_TEMP_TAO5' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO5 A UNION SELECT 'PS_MY_TEMP_TAO6' TBL, A.* FROM SYSADM.PS_MY_TEMP_TAO6 A; ) Z WHERE PROCESS_INSTANCE = 12345
Just a quick post to let you know the website move is complete. I’m sorry about any down time you may have experienced. Hopefully, I can get active again and start blogging again.
If you are interested in the details check out:
Ok, It is time to move the blog again! But, this time you shouldn’t have to change your bookmarks! I am just moving the website to new web host.
The transfer is supposed to be seamless, but I suspect you might see a little downtime over the next week as the domain re-registers and points to the new site. If it’s not working, please give me some time and check back.
I’ll update you on the other side!
As a follow-up to my previous post about using iReport, I wanted to write some code that would run the report. My goal is something that I can launch from PeopleTools.
Below is some Java that will execute the report and build a PDF output. This class takes the XML data file and the report designed by iReport and produces a PDF out of it.
package net.digitaleagle.psst0101; import java.io.File; import java.util.HashMap; import java.util.Locale; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRParameter; import net.sf.jasperreports.engine.JasperCompileManager; import net.sf.jasperreports.engine.JasperExportManager; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory; import net.sf.jasperreports.engine.util.FileResolver; import net.sf.jasperreports.engine.util.JRXmlUtils; import org.w3c.dom.Document; public class JasperInterface { private String dataPath; private String basePath; private String reportName; private String reportOutput; public JasperInterface(String dataPath, String basePath, String reportName, String reportOutput) { this.dataPath = dataPath; this.basePath = basePath; this.reportName = reportName; this.reportOutput = reportOutput; } public void run() throws JRException { Document data = JRXmlUtils.parse(dataPath); HashMap parms = new HashMap(); parms.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, data); parms.put(JRXPathQueryExecuterFactory.XML_DATE_PATTERN, "yyyy-MM-dd"); parms.put(JRXPathQueryExecuterFactory.XML_LOCALE, Locale.ENGLISH); parms.put(JRParameter.REPORT_LOCALE, Locale.US); FileResolver fileResolver = new FileResolver() { @Override public File resolveFile(String fileName) { return new File(basePath, fileName); } }; parms.put(JRParameter.REPORT_FILE_RESOLVER, fileResolver); JasperReport jr = JasperCompileManager.compileReport(basePath + reportName); JasperPrint pr = JasperFillManager.fillReport(jr, parms); JasperExportManager.exportReportToPdfFile(pr, reportOutput); } }
Here’s some code that can launch the report without needing the JasperReports classes in the classpath. I originally thought about just putting the jar files into the class directory in the PeopleSoft Home, but Jasper Reports has a number of Jar files. So, I created a class that had no dependencies on JasperReports. I tell it the location of the JasperReports installation, and it builds the necessary class path.
package net.digitaleagle.psst0101; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; public class JasperReportRunner { private String jasperPath; private String dataPath; private String basePath; private String reportName; private String reportOutput; /** * @param args */ public static void main(String[] args) { String jasperPath = args[0]; String dataPath = args[1]; String basePath = args[2]; String reportName = args[3]; String reportOutput = args[4]; JasperReportRunner jrr = new JasperReportRunner(jasperPath, dataPath, basePath, reportName, reportOutput); jrr.run(); } public JasperReportRunner(String jasperPath, String dataPath, String basePath, String reportName, String reportOutput) { this.jasperPath = jasperPath; this.dataPath = dataPath; this.basePath = basePath; this.reportName = reportName; this.reportOutput = reportOutput; } public void run() { ArrayList urls = new ArrayList(); File jasperDir = new File(jasperPath); addJars(urls, new File(jasperDir, "dist")); addJars(urls, new File(jasperDir, "lib")); URLClassLoader ucl = new URLClassLoader(urls.toArray(new URL[0])); Class jic; try { jic = ucl.loadClass(this.getClass().getPackage().getName() + ".JasperInterface"); } catch (ClassNotFoundException e) { System.err.println("Could not access JasperInterface class"); e.printStackTrace(); return; } Constructor c = jic.getConstructors()[0]; Object ji; try { ji = c.newInstance(dataPath, basePath, reportName, reportOutput); } catch (Exception e) { System.err.println("Error creating new instance of JasperInterface"); e.printStackTrace(); return; } Method method; try { method = jic.getMethod("run"); } catch (Exception e) { System.err.println("Could not get run method"); e.printStackTrace(); return; } try { method.invoke(ji); } catch (Exception e) { System.err.println("Could not get execute run method"); e.printStackTrace(); return; } } private void addJars(ArrayList urls, File jarDir) { if(!jarDir.exists()) { System.err.println("Could not find Jasper Jar files in directory: " + jarDir.getAbsolutePath()); System.err.println("Check installation directory"); return; } for(File jarFile : jarDir.listFiles()) { if(jarFile.isFile() && jarFile.getName().toLowerCase().endsWith(".jar")) { try { urls.add(jarFile.toURI().toURL()); } catch (MalformedURLException e) { System.err.println("Error loading jar for class path: " + jarFile.getAbsolutePath()); e.printStackTrace(); } } } } }
Resources
Because Oracle has stopped delivering Crystal Reports with PeopleSoft, I heard a few discussions about whether or not to license it for a new installation. So, it’s an perfect timing to explorer an alternative tool.
Let me introduce JasperReports. It is open-source, Java-based report generation tool. The reports are XML files, but they have a tool called iReport that, in my opinion, is very similar to Crystal Reports.
Here’s the descriptions from their website:
iReport:
iReport is the free, open source report designer for JasperReports. Create very sophisticated layouts containing charts, images, subreports, crosstabs and much more. Access your data through JDBC, TableModels, JavaBeans, XML, Hibernate, CSV, and custom sources. Then publish your reports as PDF, RTF, XML, XLS, CSV, HTML, XHTML, text, DOCX, or OpenOffice.
Jasper Reports:
JasperReports is the world’s most popular open source reporting engine. It is entirely written in Java and it is able to use data coming from any kind of data source and produce pixel-perfect documents that can be viewed, printed or exported in a variety of document formats including HTML, PDF, Excel, OpenOffice and Word.
So, as an introduction, let me give you a walk through introduction of using iReport to design a report based on a Query.
I had an issue with some indexes that would not create. The database complained that the table had duplicates in it that violated the index. For me, the table was PS_AUC_HDR, but these steps should work for any table. Maybe some of the techniques will be helpful too. Also, if you know a better way to take care of the problem, please comment.