MS Access: fancy InStr function

I want to compare the installed packages between a couple of Linux servers. Obviously, using a database comes to mind. And my Office Pro includes a pretty good database: MS Access.

The problem

I have tables with a list of Linux packages installed on several servers, one table per server. I want a table with all the packages common to all servers, and for each package (ex: audit-libs-python-1.8-2.el5), the package root (audit-libs-python) and the version (1.8-2.el5).


Step 1: selecting the common packages



SELECT DISTINCT Srv1.Package
FROM Srv1, Srv2, Srv3, Srv4
WHERE Srv1.Package = Srv2.Package
and Srv2.Package = Srv3.Package
and Srv3.Package = Srv4.Package;


Step 2: extracting the package root and version

Package versions are not always written in a similar way. Some examples:
Package                Root        Version
anacron-2.3-45.el5     anacron     2.3-45.el5
aspell-en-6.0-3        aspell-en   6.0-3
bzip2-1.0.3-6.el5_5    bzip2       1.0.3-6.el5_5
db4-4.3.29-10.el5_5.2  db4         4.3.29-10.el5_5.2


However, the version starts with an hyphen (-) followed by a digit (0 to 9). Unfortunately, MS Access doesn't allow the use of Regex (regular expressions).
To overcome this, I replaced all digits by a special character (#) and then searched for the position of "-#"; the substring before this position is the package root, the one after is the version.


SELECT Package,
left(Package,instr(Package,"-")+
 instr(
  Replace(
   Replace(
    Replace(
     Replace(
      Replace(
       Replace(
        Replace(
         Replace(
          Replace(
           Replace(
mid(Package,instr(Package,"-")),"9","#"),
          "8","#"),
         "7","#"),
        "6","#"),
       "5","#"),
      "4","#"),
     "3","#"),
    "2","#"),
   "1","#"),
  "0","#"),
 "-#")-2) as PackageRoot,

mid(Package,instr(Package,"-")+
 instr(
  Replace(
   Replace(
    Replace(
     Replace(
      Replace(
       Replace(
        Replace(
         Replace(
          Replace(
           Replace(mid(Package,instr(Package,"-")),"9","#"),
          "8","#"),
         "7","#"),
        "6","#"),
       "5","#"),
      "4","#"),
     "3","#"),
    "2","#"),
   "1","#"),
  "0","#"), "-#")) as PackageVersion


FROM [Common packages];


Sure that writing a VBA function might do the trick as well, but I wanted a SQL version.

Comments

Popular Posts