Escape characters for SQLLoader

9. February 2010 18:49 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)

 

The LINC/EAE migration tool can automatically generate reports that can be used to extract your data from DMSII to your target database, for example Oracle.
In this scenarios the Oracle SQL Loader tool is used. However you might problems loading the data because the string values can contain the same characters you are using to enclose them.

Let’s see an example, taken from an oracle forum:

C:\ora>type buyer.ctl
LOAD DATA
INFILE 'buyer.data'
truncate into table BUYER
FIELDS TERMINATED BY ',' optionally enclosed by '"' TRAILING NULLCOLS
(
buyer_code,
BUYER_NAME
)
 

And suppose you have data like:

1,"XYZ IND"
2,"ABC"
3,"XYZ ABC"
4,"Your "offspring""
5,"ATUL"

How can you “escape” the enclosing characters. Well I found the answer in another forum:

If two delimiter characters are encountered next to each other, a single occurrence of the delimiter character is used in the data value. For example, 'DON''T' is stored as DON'T. However, if the field consists of just two delimiter characters, its value is null.

So just use something like:

 

1,"XYZ IND"
2,"ABC"
3,"XYZ ABC"
4,"Your ""offspring"""
5,"ATUL"

Easy way to see the Explain Plan in Oracle

3. February 2010 13:07 by Mrojas in Oracle  //  Tags: , , , ,   //   Comments (0)

 

Linc\EAE used profiles for their queries. Well the profile information is used by our migration tool to generate indexes.
In Java is easy to intercept all SQL statements used by the translated application and analyze them.

To analyse how a query is executed you have to study its explain plan. For go here an excellent guide on EXPLAIN PLAN.

After you read that page, you will find useful the following function, that will shorten the lines that you have to type to see the explain plan:

create OR REPLACE function  ShowPlan return sys_refcursor
  as
      c_test sys_refcursor;
BEGIN
  open c_test for select 
  substr (lpad(' ', level-1) || operation || ' (' || options || ')',1,30 ) "Operation", 
  object_name "Object"
  from 
  sys.plan_table$ start with id = 0 connect by prior id=parent_id;
  return c_test;
END;
SQL>
explain plan for select * from MY_TABLE
SQL> variable rc refcursor
SQL> exec :rc := testfunc()

PL/SQL procedure successfully completed.

SQL> print rc
Operation                      Object
------------------------------ ------------------------------
SELECT STATEMENT ()
 TABLE ACCESS (FULL)           MY_TABLE

Get Table Owner in Oracle

3. February 2010 12:40 by Mrojas in General  //  Tags: , , , , ,   //   Comments (0)

 

When we migrate from LINC/EAE to Oracle, the migration tool generates an schema an tables form the original ISPECS.
I came across with the problem that I had been playing around with a test database and I didn’t know who was the owner of the table.

Well just as a reminder this is what is needed:

select owner, table_name, tablespace_name   from dba_tables   where table_name='YOUR_TABLE';
This will return something as:
 

OWNER                    TABLE_NAME  TABLESPACE_NAME
------------------------------ ------------------------ ------------------------------
THE_OWNER               MY_TABLE       USERS

Get Java Version for Oracle Stored Procedures

1. February 2010 06:17 by Mrojas in General  //  Tags: , , ,   //   Comments (0)

If you have to write stored procedures for oracle is important
to notice which Java version is supported by your Oracle Database,

A common technique is create a JAVA stored procedure for that:

1. Create a function with an ORACLE SQL statement like:

CREATE OR REPLACE FUNCTION getJavaProperty(myprop IN VARCHAR2)
RETURN VARCHAR2 IS LANGUAGE JAVA
name ‘java.lang.System.getProperty(java.lang.String) return java.lang.String’;

 

2. Once you created the function you can use it to get the version:

SELECT getJavaProperty(‘java.version’) from dual;

You can see in the attached version that for my Oracle Database 10.1.0.4.2 the Java version is 1.4.2_04 :)

image

File Previewers for Outlook

26. January 2010 09:56 by Mrojas in General  //  Tags:   //   Comments (0)

As I developer I usually receive emails with .zip attachments and .xml attachments. When I’m looking for an old email I hate that I have to open the attachment just to see if it has the files I’m looking.

image

Why isn’t there a built-in preview functionality for .xml and .ZIP files?

So I thought, I’m a developer I can build one. And I found an excellent article about the File Previewers in Outlook 2007 and Windows 7 by Stephen Toub.

I just updated the project files to VS 2008 and removed the dependencies to VJ# replacing them by the SharpZipLib library.

image 

And it works well and does not require you to install anything else!

 

Below you can see an example of Zip File preview

image

And and example of XML File Preview

image

I think is an excellent article and I can know write my own previewers every time I need them.

 

Download the code from CODE HERE

Download the installer from INSTALLER HERE

Get Exact Text Width C#

15. December 2009 08:13 by Mrojas in WinForms  //  Tags: , , , , , , , , ,   //   Comments (0)

 I was recently trying to get the exact width of a string. And I found that the Graphics.MeasureString does not give an exact result.

I finally found Pierre Arnaud

post in Code Project, which gave me a good explaination and solution of what was happening.

You can see in the image Pierre put in his post:

 That Graphics.measurestring will return a size that might be bigger that the actual drawn size, this is due some GDI+ details that he explains in that post.

I really like the second proposed solution:

static public int MeasureDisplayStringWidth(Graphics graphics, string text,Font font)
{
    System.Drawing.StringFormat format  = new System.Drawing.StringFormat ();
    System.Drawing.RectangleF   rect    = new System.Drawing.RectangleF(0, 0,1000, 1000);
    System.Drawing.CharacterRange[] ranges  = { new System.Drawing.CharacterRange(0, text.Length) };
    System.Drawing.Region[]         regions = new System.Drawing.Region[1];

    format.SetMeasurableCharacterRanges (ranges);
    regions = graphics.MeasureCharacterRanges (text, font, rect, format);
    rect    = regions[0].GetBounds (graphics);

    return (int)(rect.Right + 1.0f);
}

 

 

ActiveX Server Migration to .NET

14. December 2009 08:01 by Mrojas in General  //  Tags: , , , , , , , , , ,   //   Comments (0)

 In VB6 ActiveX-EXEs or ActiveX OLE Server where used for several reasons. Sometimes it was performance (because it allowed you to run your code in another process) and sometimes as way to share resources between several applications, like connection information, database connections, mainframe info, etc.

During migration some of this ActiveX-Exes can be migrated as simple Assembly DLLs, but other require more attention. Specially if they have global variables that hold state shared by several programs.

In that is your case what are your options then?

1. Convert those ActiveX-Exes to Windows Services.

This option is simple. You modify your migrated assembly to work as a Windows Service. The easier way to do that is:

a) Start Microsoft Visual Studio 2005\2008

b) Go to File\New…\Project… and Select Windows Service

That will generated code like:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
namespace WindowsService1
{
   public partial class Service1 : ServiceBase
   {
      public Service1()    InitializeComponent();    }
     
protected override void OnStart(string[] args)    {   }
     
protected override void OnStop()    {   }
   }
}

c) Add a reference to the Remoting Assemblies: System.Runtime.Remoting;

d) Modify the previous code:

Add two using statements like:

using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting;

Add a simple event log for tracing:

 

private static EventLog evt = new EventLog(“Application”);
private static string SVC_NAME = “ActiveX Server Example Svc”;

 And modify the OnStart and OnStop methods to look like:

  protected override void OnStart(string[] args)
{
    HttpChannel chnl = new HttpChannel(1234);
   
ChannelServices.RegisterChannel(chnl,true );
   
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyClass), “MyClass.soap”, WellKnownObjectMode.Singleton);
   evt.WriteEntry(SVC_NAME + ” Started”);

}

protected override void OnStop() { evt.WriteEntry(SVC_NAME +” Stoppped”); }

Also make sure that MyClass extends MarshalByRefClass

2. Convert those ActiveX-Exes using the Artinsoft ActiveX migration helpers.

 Sometimes, you need your migrated application to replicate some of the original ActiveX EXE \OLE DLL VB6 characteristics. For example you need your ActiveX-EXE to start just when the first instance is created and to resemble the VB6 logic for Process creation\destruction.

For that purpose Artinsoft has created some helpers that our migration tool is able to automatically use in the generated code if it detects that this functionality is needed.

The code will then be changed from:

Dim myInstance As New MyProject.MyClass

To the following Helper method:

myInstance = MyProjectFactory.Create< MyProject.MyClass>(myInstance);

 And destroy calls can be changed to the following Helper method:

 myInstance= MyProjectFactory.Dispose<MyProject.MyClass >( myInstance); 

The migration tool will modify your ActiveX-EXEs or OLE Servers to be Windows EXE and the helper will then locate the assembly that contains the desired Class, create an instance and initilize a Remoting channel to the desired classes. Settings as SingleUse and MultiUse are also taken care by the helpers.

3. Other possible alternatives are using WFC and COM+ that I will comment in another post.

 

 

 

 

Return argument has an invalid type

10. December 2009 07:39 by Mrojas in General  //  Tags: , , , , ,   //   Comments (0)

When you develop applications with remoting, or in some COM + Remoting scenarios, you could start founding very interesting exceptions.

We had a very unconfortable one. We had an ActiveX that is used in an intranet Web Page, that uses remoting to instanciate some classes in the local network.

When we runned outside of the IE, everything seem to work, but running in IE it produced an exception like:

Error : Return argument has an invalid type.
Type  : System.InvalidCastException
Source: mscorlib
Source: at System.Runtime.Remoting.Proxies.RealProxy.ValidateReturnArg(Object arg, Type paramType)
at System.Runtime.Remoting.Proxies.RealProxy.PropagateOutParameters(IMessage msg, Object[] outArgs, Object returnValue)
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

Why??? Well what happens is simple, it is having an assembly resolution problem, it is not being able to resolve the type.

We solve the problem adding something like:

1. Find a place in your code to add an event like this (it could be in the Main of your program for example):

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
 
2. Add a handler like this: 

static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
  
System.Reflection.Assembly assembly = null; 
   try
   {
        
assembly = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName(args.Name));
   }
   catch (Exception ex)
  
      
System.Diagnostics.Trace.WriteLine(
            string.Format(“Problem with resolution of {0} : {1} {2}”, args.Name, ex.Message, ex.StackTrace));
   }
   return assembly;
}

Well, this worked for us, and I hope that helps you out.

 

Code compiles but System.IO.FileNotFound Exception is thrown

2. October 2009 10:04 by Mrojas in General  //  Tags: , , , , , , ,   //   Comments (0)

We have seen a situation that can be a little annoying.
I usually find that situation in ASP.NET projects, but it can also happen in Winforms.

The issue is like this:

  • You have a VStudio Solution
  • You have added all the needed references
  • All your code compiles

 

BUT

When you run the application it terminates at a certain point with a
FileNotFound exception indicating that the assembly blablabla  or one of its
dependencies could not be loaded.

 

Whats hapenning!!!

Do this:

1) Look at the bin\debug or bin\release and make sure that the assembly is in those directories.

2) If the assembly is not there, then go to the project references in the solution explorer, right click and select properties and set the Copy Local Setting

 

image

Mapping VBRUN.RasterOpConstants

1. October 2009 05:44 by Mrojas in General  //  Tags: , , , , ,   //   Comments (0)

 

vb Constant Decimal Value Hex Value .NET
vbDstInvert 5570569 H550009
System.Drawing.CopyPixelOperation.DestinationInvert
vbMergeCopy 12583114 HC000CA
System.Drawing.CopyPixelOperation.MergeCopy
vbMergePaint 12255782 HBB0226
System.Drawing.CopyPixelOperation.MergePaint
vbNotSrcCopy 3342344 H330008
System.Drawing.CopyPixelOperation.NotSourceCopy
vbNotSrcErase 1114278 H1100A6
System.Drawing.CopyPixelOperation.NotSourceErase
vbPatCopy 15728673 HF00021
System.Drawing.CopyPixelOperation.PatCopy
vbPatInvert 5898313 H5A0049
System.Drawing.CopyPixelOperation.PatInvert
vbPatPaint 16452105 HFB0A09
System.Drawing.CopyPixelOperation.PatPaint
vbSrcAnd 8913094 H8800C6
System.Drawing.CopyPixelOperation.SourceAnd
vbSrcCopy 13369376 HCC0020
System.Drawing.CopyPixelOperation.SourceCopy
vbSrcErase 4457256 H440328
System.Drawing.CopyPixelOperation.SourceErase
vbSrcInvert 6684742 H660046
System.Drawing.CopyPixelOperation.SourceInvert
vbSrcPaint 15597702 HEE0086
System.Drawing.CopyPixelOperation.SourcePaint