Showing posts with label Oracle. Show all posts
Showing posts with label Oracle. Show all posts

Wednesday, October 1, 2008

Table Counts on a field accross the entire Database

Ever need to look for a value in a field across the entire DB? Have 10k+ Table that have your particular field? Here is a plsql package that I create to help in tracking where a person’s ID (emplid) shows up in the DB. Takes about 3 minutes to process 1 emplid.

 

Usage: select * from table(tablecounts_pkg.mbi_tablecounts('<<EMPLID>>') ) ;

 

 

CREATE OR REPLACE PACKAGE SYSADM.tablecounts_pkg

IS

     -- Looks for all PS tables (Joins on User_tables to make sure it is a table) and does a count on that table based on EMPLID.

   TYPE outrec_typ IS RECORD (

      var_table      VARCHAR2 (30),

      var_rowcount   NUMBER

   );

 

   TYPE outrecset IS TABLE OF outrec_typ;

 --Usage select * from table(tablecounts_pkg.tablecounts('1978614') ) ;

   FUNCTION tablecounts (emplid VARCHAR)

      RETURN outrecset PIPELINED;

    

END tablecounts_pkg;

/

 

CREATE OR REPLACE PACKAGE BODY SYSADM.tablecounts_pkg

IS

   FUNCTION tablecounts (emplid VARCHAR)

      RETURN outrecset PIPELINED

   IS

      out_rec           outrec_typ;

 

      CURSOR tablenames

      IS

         SELECT a.table_name

           FROM SYS.user_tab_cols a, user_tables b

          WHERE column_name = 'EMPLID' AND a.table_name LIKE 'PS%' AND a.table_name = b.table_name;

 

      table_row_count   NUMBER;

      stmt              VARCHAR (200);

   BEGIN

      FOR x IN tablenames

      LOOP

         stmt := 'select count(*) from ' || x.table_name || ' where emplid = ''' || emplid || '''';

 

         --DBMS_OUTPUT.put_line (stmt);

         EXECUTE IMMEDIATE stmt

                      INTO table_row_count;

 

         IF table_row_count > 0

         THEN

            out_rec.var_table := x.table_name;

            out_rec.var_rowcount := table_row_count;

            PIPE ROW (out_rec);

         END IF;

      END LOOP;

 

      RETURN;

   END;

END tablecounts_pkg;

/

Monday, September 15, 2008

CIs: Connecting to PeopleSoft Jolt sever from VB.net. Why & How. Part 4

[If you are looking to Load 100k+ rows into PeopleSoft quickly, this isn't the post for you! This is a multi post piece on Component Interfaces. Hopefully it is informative reading...]

Part 4

A nice thing about interactive mode is that is just that. If you set a field and that updates antoher, you can directly call that other field and the value is there. That is if InteractiveMode is turned on, of course.

Each level and scroll of the component buffer is setup as a collection that can be referenced directly or looped through as in the sample code. For each sub level0 collection there are methods for inserting and deleting items. To use 'Ci_collection.insertitem(x)' x equals Ci_collection.count.

In the sample Code you can see each level is in a For loop. This is good if you are reading out all the rows in the buffer, but for writing you want to jump to either insertingnewitem(collection.count) or oLvlTwo = oLvlTwoCollection.Item(5) unless you do need to cycle through them to find what you want to update etc. You don't need the 'set' statements in .Net. oLvlTwo = oLvlTwoCollection.Item(5) pulls item 5 from the collection and gives it to an object that allow access to that level's fields.

Another Key to CIs, especially in .Net is once you have saved or determined programatically that you don't need the CI anymore, cancel it. Use the .Cancel() function on the CI object. Each time you save, even if you are going to use the as CI again for a new transaction, cancel it and Get/Create it again. You can still read from it or change it in it current state, but once you want to move on to a new rowset etc, Cancel first.

One benifit of using CIs is that the user has to provide credentials, and have access in order to be able to use the CI. This means you are relying on out of the box functionality, which is always nice.

To bring this to a close, there is obviously a lot missing from these short posts, but the point was to point out that although Component Interfaces seem old technology and come with a bunch of over head, they can still be VERY useful when you need a custom solution to a problem and want to leverage the application tier.

Sunday, September 14, 2008

CIs: Connecting to PeopleSoft Jolt sever from VB.net. Why & How. Part 3


[If you are looking to Load 100k+ rows into PeopleSoft quickly, this isn't the post for you! This is a multi post piece on Component Interfaces. Hopefully it is informative reading...]
Part 3


The file is laid out in two Subs. ErrorHandler and main.

ErrorHandler is generic for all CIs. Call it often! One of the major issues I had to deal with was error handling. Wether you use PeopleCode or VB or Java, you must handle errors well. If a CI hits an error it freezes; just like in the web front end. Until you clear the messeges, the CI is unusable.

In using .Net, in the ErrorHandler sub there is a problem. The line:

oPSMessageCollection.DeleteAll

This clears all the messeges and thus allows the CI to continue. It returns a var bool type (Boolean) but the problem is that is in type format that .Net doesn't like. I have tried marshaling it Ctyping it  etc... to no avail. The only way I could maked it work as to late bind as an object and set the property.
 
Dim o As Object = oPSMessageCollection
      Try
        o.DeleteAll()
      Catch ex As Exception
msgbox("Problems clearing Msgs.")
       End Try

That was the source of a lot of greif in the begining... After I got that issue sorted out, CIs became an option.

The sample code is well documented and allows you to copy and paste a lot of stuff. 'Try' statements are handy for the major parts of Get / Find / Create, allowing you to retry and handle errors nicely. Notice the statements for writing data are commented out, and read only properties aren't available to be set.

The sample code also showing good practice in setting up the CI by setting the three modes for a component. InteractiveMode, GetHistoryItems and EditHistoryItems. If users don't need instant feed back for each item entered, you can increase performance by setting InteractiveMode = Flase as the app server will only process all the data items at Save time, therefore eliminating a lot of overhead.

Saturday, September 13, 2008

CIs: Connecting to PeopleSoft Jolt sever from VB.net. Why & How. Part 2

[If you are looking to Load 100k+ rows into PeopleSoft quickly, this isn't the post for you! This is a multi post piece on Component Interfaces. Hopefully it is informative reading...]

Part 2

Since to Topic of this post is CIs lets get started... (finally :)

To start using CIs we have to have our environment set up to handle using the COM object front end of the java classes that actually do the work. We have to have enviromental variables set:
If these already exist, obviously just add missing parts...

CLASSPATH=C:\PS\8.49\web\psjoa\psjoa.jar
PATH=C:\PS\8.49;C:\PS\8.49\jre\bin\client

C:\PS\8.49 is where my PeopleTools is located.

As for what is needed for a peopleTools CI only environmnet, you don't need to whole thing. Here are the files that are needed:Everything under .\jre and \webIn .\bin\client\winx86:
  • dbghelp.dll
  • msvcp71.dll
  • msvcr71.dll
  • psapiadapter.dll
  • psbtunicode.dll
  • pscmnutils.dll
  • pscompat.dll
  • pslibeay32.dll
  • pspetssl.dll
  • trio.dll
  • zlib1.dll
  • PeopleSoft_PeopleSoft.reg & PeopleSoft_PeopleSoft.tlb are what you get when you build the PeopleSoft APIs from appdesigner.

    Once the PeopleSoft_PeopleSoft.reg file is registered (More about cleaning up CI registry entries in a bit) you may need to restart to have the environmental variable available etc. (I've found that it does wonders, thanks M$). Add a reference to the Peoplesoft_peoplesoft.tlb to a .Net project. You can import the reference as to not have to type peoplesoft_peoplesoft all the time.
    In order to get familiar with the code, I'd like to suggest that you take a look at the demo code that you can generate by right clicking on your CI from app designer and selecting the generate visual basic template. This is in VB6-or-less layout in a .bas file.

    Stay tuned for part 3.

    Friday, September 12, 2008

    CIs: Connecting to PeopleSoft Jolt sever from VB.net. Why & How. Part 1

    [If you are looking to Load 100k+ rows into PeopleSoft quickly, this isn't the post for you! This is a multi post piece on Component Interfaces. Hopefully it is informative reading...]

    Part 1:

    There have been a lot of times when we have needed to mass load some sort of data. One of the main issues as always been load directly into PeopleSoft DB tables is just yucky... :) Some times unavoidable, but almost always yucky... I guess i should explain what i mean by yucky... The clearest example is person bio demo data. When you use 'add/update a person' to add a new person the emplid is give to you, the person's data is strewn over a plethora of tables and all the effective dating stuff is taken care of for you. Not to even touch on search match possibilities; cause we all love dupes so much...

    Moving data around between platforms is always a headache. Then there is the migraine called synchronizing data... anyway, say you have an application that really needs data moved from it to Oracle's PeopleSoft. You could write something to connect to both DB and just pass data back and forth, but you want a solution that is more flexible, able to be used by an end user (securing DB level access for end users, do i need to say more...) and you want to be able to leverage data validation from the application tier. Sounds great. You have two options: CI or Web service.

    As of 8.48, web services are a good option, but they are still lacking some (this could totally be from a lack of understanding from my part) and are a little ... um.. clunky?... when it comes to dealing with re-posts and data validation. They are great for posting small data objects from remote systems that you can almost be curtain the data is always good.

    I have come to really have an appreciation for CIs. At first I really didn't like them because of the fact that they are based on old COM objects, don't work too nicely with .Net (I now have some tricks... :), setting up the environment was a pain, maintaining distributions was painful too and they are inherently SLOW (slow-as-a-wet-week). After I overcame these little hurdles, or learnt to live with them, the results are quite workable.

    Oracle Data Reader to Data Table VB.Net

    One of the things that I don't like about Oracle's .Net Library is that sometimes you want more than the reader, but less than the DataAdapter.... So here is my little function to grab a reader and then return it as a data table. It returns nothing if there is nothing return


    Function GetReaderAsDataTable(ByVal sql As String, ByVal Envrionment As String, Optional ByRef OtherOraConnection As OracleConnection = Nothing) As DataTable
     Try
       Dim OutputDataTable As New DataTable
       Dim x As Integer
      
       Dim cmdfunc As New OracleCommand
      
       If OtherOraConnection Is Nothing Then
        Me.ConnectToOracle(Envrionment)
        cmdfunc.Connection = mbiUser_Admin.OracleFunctionlib.oraConnection
       Else
        cmdfunc.Connection = OtherOraConnection
       End If
      
       cmdfunc.CommandText = sql
       cmdfunc.CommandType = CommandType.Text
      
       Dim drFunc As OracleDataReader
       drFunc = cmdfunc.ExecuteReader
      
      
       If Not drFunc.HasRows Then
        Return Nothing
       Else
        Dim DataRowString(drFunc.FieldCount - 1)
        For x = 0 To drFunc.FieldCount - 1
         OutputDataTable.Columns.Add(drFunc.GetName(x), drFunc.GetFieldType(x))
        Next
        While drFunc.Read
         For x = 0 To drFunc.FieldCount - 1
          DataRowString(x) = drFunc(x)
         Next
         OutputDataTable.LoadDataRow(DataRowString, True)
        End While
      
        Return OutputDataTable
       End If
      
      Catch ex As Exception
       Try
        HttpContext.Current.Session("msg") = (ex.Message & vbLf & vbCr & sql)
       Catch ex1 As Exception
        'Not in a HTTP Session; you can do something with the msg if you want... like return it to the user would be nice... but with most of my stuff just knowing that the sql didn't return anything is good enough. Robust, no, but usable.
       End Try
      
       Return Nothing
      End Try
      
      
    End Function

    Thursday, May 1, 2008

    Oracle Data Reader as XML Document

    Sometime you just want to return some data from the DB to client in XML format. Here is my Function to return an XML doc.

    Public Function GetReaderAsXML(ByVal sql As String, ByVal Environment As String, Optional ByRef OtherOraConnection As OracleConnection = Nothing) As XmlDocument

    Dim cmdfunc As New OracleCommand

    If OtherOraConnection Is Nothing Then
    If Not oraConnection.State = ConnectionState.Open Then
    Me.ConnectToOracle(Environment)
    End If
    cmdfunc.Connection = oraConnection
    Else
    cmdfunc.Connection = OtherOraConnection
    End If

    cmdfunc.CommandText = sql
    cmdfunc.XmlCommandType = OracleXmlCommandType.Query
    cmdfunc.BindByName = True
    cmdfunc.XmlQueryProperties.MaxRows = -1

    Dim XmlReaderOut As System.Xml.XmlReader
    XmlReaderOut = cmdfunc.ExecuteXmlReader
    Dim XmlDocOut As New System.Xml.XmlDocument

    XmlDocOut.PreserveWhitespace = True
    XmlDocOut.Load(XmlReaderOut)

    Return XmlDocOut

    End Function
    Add to Google