I have been trying to simplify my descriptions of the issue and the database
structure. My database is a Progress database which I am linking to through
ODBC. I'm not sure how much information you want but I will supply the SQL
translation of the Progress schema for a number of tables below. What I have
been refering to as the prov table is called crmProv and is an interfile
between crmop and the four hierarchical tables of site, operation, suboper
and lot (collectively known as the provenience tables). The crmprov table is
a poor solution to address a problem stemming from a lack of strong rules
around the use of the provenience tables. Crmop has foreign keys for two of
the provenience tables so in order for crmprov to handle alternative linkings
between crmop and provenience duplicate provenience fields had to be created
(with different names) to carry the foreign keys found in crmop.
CREATE TABLE crmprov (
crmsitenum integer not null,
crmsitecode varchar (1) not null,
crmopcode integer not null,
crmresnum integer null,
sitenum integer not null,
sitecode varchar (1) not null,
opcode integer null,
sopcode varchar (1) null,
lotnumber integer null
)
go
CREATE INDEX crmprov##crm ON crmprov (crmsitecode, crmsitenum, crmopcode,
crmresnum)
go
CREATE INDEX crmprov##prov ON crmprov (sitecode, sitenum, opcode, sopcode,
lotnumber)
CREATE TABLE photo (
sitenum integer not null,
sitecode varchar (1) not null,
filmtype varchar (1) not null,
photonumber integer not null,
opcode integer not null,
sopcode varchar (1) null,
lotnumber integer null,
personcode integer null,
regioncode varchar (1) not null,
shotwhen datetime null,
tagnum integer null,
raphoto tinyint null,
doccode varchar (15) null,
loccode varchar (50) null,
duploccode varchar (20) null,
aspect varchar (10) null,
caption3 varchar (150) null
)
go
CREATE INDEX photo##document ON photo (doccode)
go
CREATE INDEX photo##lot ON photo (sitecode, sitenum, opcode, sopcode,
lotnumber)
go
CREATE UNIQUE INDEX photo##negativenum ON photo (sitecode, sitenum,
filmtype, regioncode, photonumber)
go
CREATE INDEX photo##ranum ON photo (regioncode, filmtype, photonumber)
go
CREATE INDEX photo##raphoto ON photo (raphoto)
go
CREATE INDEX photo##timber ON photo (sitecode, sitenum, tagnum)
go
CREATE INDEX photo##worker ON photo (regioncode, personcode)
CREATE TABLE crmop (
sitenum integer not null,
sitecode varchar (1) not null,
opcode integer null,
ntsnum varchar (6) null,
sitetype varchar (40) null,
latitude varchar (6) null,
longitude varchar (7) null,
utmgrid varchar (5) null,
utmeast decimal(4,1) null,
utmnorth decimal(4,1) null,
legal varchar (30) null,
othermap varchar (30) null,
airphotos varchar (15) null,
access_##1 varchar (50) null,
access_##2 varchar (50) null,
access_##3 varchar (50) null,
access_##4 varchar (50) null,
access_##5 varchar (50) null,
owner varchar (50) null,
siteslope integer null,
elevasl integer null,
areasqm integer null,
aspect varchar (10) null,
bordennum varchar (30) null,
sitename varchar (40) null,
nsdimens integer null,
ewdimens integer null,
majordrain varchar (30) null,
minordrain varchar (30) null,
comments##1 varchar (50) null,
comments##2 varchar (50) null,
comments##3 varchar (50) null,
comments##4 varchar (50) null,
comments##5 varchar (50) null,
comments##6 varchar (50) null,
comments##7 varchar (50) null,
comments##8 varchar (50) null,
comments##9 varchar (50) null,
comments##10 varchar (50) null,
comments##11 varchar (50) null,
comments##12 varchar (50) null,
comments##13 varchar (50) null,
comments##14 varchar (50) null,
comments##15 varchar (50) null,
opentext##1 varchar (30) null,
opentext##2 varchar (30) null,
opentext##3 varchar (30) null,
opentext##4 varchar (30) null,
opentext##5 varchar (30) null,
opennum##1 integer null,
opennum##2 integer null,
opennum##3 integer null,
opennum##4 integer null,
opennum##5 integer null,
parkcode varchar (3) not null,
diameter integer null,
manageflag tinyint null,
ntsyear integer null
)
go
CREATE UNIQUE INDEX crmop##crmop ON crmop (sitecode, sitenum, opcode)
go
CREATE INDEX crmop##park ON crmop (parkcode)
CREATE TABLE site (
sitenum integer not null,
sitecode varchar (1) not null,
sitename varchar (40) null,
bordennum varchar (30) null,
parkcode varchar (3) null,
nexttimber integer null,
regioncode varchar (1) not null,
nextagg integer null,
print_ tinyint null,
datumloc varchar (50) null
)
go
CREATE INDEX site##park ON site (parkcode)
go
CREATE INDEX site##print_ ON site (print_, sitecode, sitenum)
go
CREATE INDEX site##region ON site (regioncode, sitecode, sitenum)
go
CREATE UNIQUE INDEX site##site ON site (sitecode, sitenum)
CREATE TABLE operation (
sitenum integer not null,
sitecode varchar (1) not null,
opcode integer not null,
bordennum varchar (30) null,
opname varchar (40) null,
opdesc varchar (40) null,
print_ tinyint null
)
go
CREATE UNIQUE INDEX operation##operation ON operation (sitecode, sitenum,
opcode)
go
CREATE INDEX operation##print_ ON operation (print_, sitecode, sitenum,
opcode)
CREATE TABLE suboper (
sitenum integer not null,
sitecode varchar (1) not null,
opcode integer not null,
sopcode varchar (1) not null,
soplocation varchar (50) null,
sopdimens varchar (25) null,
exdesc varchar (25) null,
numoflots integer null,
print_ tinyint null
)
go
CREATE INDEX suboper##print_ ON suboper (print_, sitecode, sitenum, opcode,
sopcode)
go
CREATE UNIQUE INDEX suboper##suboper ON suboper (sitecode, sitenum, opcode,
sopcode)
CREATE TABLE lot (
sitenum integer not null,
sitecode varchar (1) not null,
opcode integer not null,
sopcode varchar (1) not null,
lotnumber integer not null,
coordinates##1 decimal(6,2) null,
coordinates##2 decimal(6,2) null,
coordinates##3 decimal(6,2) null,
coordinates##4 decimal(6,2) null,
coordinates##5 decimal(6,2) null,
coordinates##6 decimal(6,2) null,
coordinates##7 decimal(6,2) null,
coordinates##8 decimal(6,2) null,
coordinates##9 decimal(6,2) null,
coordinates##10 decimal(6,2) null,
coordinates##11 decimal(6,2) null,
nextfind integer null,
lotfeature integer null,
lotdate datetime null,
print_ tinyint null,
comments##1 varchar (40) null,
comments##2 varchar (40) null,
comments##3 varchar (40) null,
comments##4 varchar (40) null,
comments##5 varchar (40) null
)
go
CREATE UNIQUE INDEX lot##lotindex ON lot (sitecode, sitenum, opcode,
sopcode, lotnumber)
go
CREATE INDEX lot##print_ ON lot (print_, sitecode, sitenum, opcode, sopcode,
lotnumber)
I will include the Progress procedure I am using to achieve the results.
While you may not be familiar with Progress the language is quite easy to
understand and you should probably be able figure out more easily what it is
I am after from reading the code. It may not be the best implementation but
it is working.
In SQL is it possible to include some conditional statements within Select
(e.g. IIF, CASE) to determine the level of provenience recorded in the photo
record and to direct the join to one of four instances of the crmProv table
each with different join critera?
Here is the Progress procedure that outputs the data I need:
OUTPUT TO u:\datafile\crmPhoto1.txt.
FIND park WHERE parkcode = "H56" NO-LOCK.
FOR EACH site OF park no-lock, EACH photo OF site NO-LOCK
BREAK BY photo.siteCode BY photo.siteNum BY photo.filmType BY photo.photoNum:
FIND FIRST crmProv WHERE
crmProv.siteNum = photo.siteNum AND
crmProv.siteCode = photo.siteCode AND
crmProv.opCode = photo.opCode AND
crmProv.sopCode = photo.sopCode AND
crmProv.lotNum = photo.lotNum
AND crmResNum = 0
NO-LOCK NO-ERROR.
IF AVAILABLE crmprov THEN DO:
FOR EACH crmProv WHERE
crmProv.siteNum = photo.siteNum AND
crmProv.siteCode = photo.siteCode AND
crmProv.opCode = photo.opCode AND
crmProv.sopCode = photo.sopCode AND
crmProv.lotNum = photo.lotNum
AND crmResNum = 0
:
PUT UNFORMATTED photo.siteNum "~t" photo.siteCode "~t"
photo.opCode "~t"
photo.sopCode "~t" photo.lotNum "~t"
string(photo.siteNum) + photo.siteCode + "-" +
string(photo.photoNum) +
filmType "~t" crmProv.siteNum "~t" crmProv.siteCode "~t"
crmProv.opCode "~t" crmProv.sopCode "~t" crmProv.lotNum "~t".
IF crmProv.crmResNum > 0 THEN PUT UNFORMATTED
string(crmProv.crmsiteNum) + crmProv.crmsiteCode +
string(crmProv.crmopCode) + "-" + string(crmProv.crmresNum) "~n".
ELSE PUT UNFORMATTED
string(crmProv.crmsiteNum) + crmProv.crmsiteCode +
string(crmProv.crmopCode) "~n".
END.
NEXT.
END.
ELSE FIND FIRST crmProv WHERE
crmProv.siteNum = photo.siteNum AND
crmProv.siteCode = photo.siteCode AND
crmProv.opCode = photo.opCode AND
crmProv.sopCode = photo.sopCode AND
crmProv.lotNum = 0
AND crmResNum = 0
NO-LOCK NO-ERROR.
IF AVAILABLE crmprov THEN DO:
FOR EACH crmProv WHERE
crmProv.siteNum = photo.siteNum AND
crmProv.siteCode = photo.siteCode AND
crmProv.opCode = photo.opCode AND
crmProv.sopCode = photo.sopCode AND
crmProv.lotNum = 0
AND crmResNum = 0
:
PUT UNFORMATTED photo.siteNum "~t" photo.siteCode "~t"
photo.opCode "~t"
photo.sopCode "~t" photo.lotNum "~t"
string(photo.siteNum) + photo.siteCode + "-" +
string(photo.photoNum) +
filmType "~t" crmProv.siteNum "~t" crmProv.siteCode "~t"
crmProv.opCode "~t" crmProv.sopCode "~t" crmProv.lotNum "~t".
IF crmProv.crmResNum > 0 THEN PUT UNFORMATTED
string(crmProv.crmsiteNum) + crmProv.crmsiteCode +
string(crmProv.crmopCode) + "-" + string(crmProv.crmresNum)
"~n".
ELSE PUT UNFORMATTED
string(crmProv.crmsiteNum) + crmProv.crmsiteCode +
string(crmProv.crmopCode) "~n".
END.
NEXT.
END.
ELSE FIND FIRST crmProv WHERE
crmProv.siteNum = photo.siteNum AND
crmProv.siteCode = photo.siteCode AND
crmProv.opCode = photo.opCode AND
crmProv.sopCode = "" AND
crmProv.lotNum = 0
AND crmResNum = 0
NO-LOCK NO-ERROR.
IF AVAILABLE crmprov THEN DO:
FOR EACH crmProv WHERE
crmProv.siteNum = photo.siteNum AND
crmProv.siteCode = photo.siteCode AND
crmProv.opCode = photo.opCode AND
crmProv.sopCode = "" AND
crmProv.lotNum = 0
AND crmResNum = 0
:
PUT UNFORMATTED photo.siteNum "~t" photo.siteCode "~t"
photo.opCode "~t"
photo.sopCode "~t" photo.lotNum "~t"
string(photo.siteNum) + photo.siteCode + "-" +
string(photo.photoNum) +
filmType "~t" crmProv.siteNum "~t" crmProv.siteCode "~t"
crmProv.opCode "~t" crmProv.sopCode "~t" crmProv.lotNum "~t".
IF crmProv.crmResNum > 0 THEN PUT UNFORMATTED
string(crmProv.crmsiteNum) + crmProv.crmsiteCode +
string(crmProv.crmopCode) + "-" + string(crmProv.crmresNum)
"~n".
ELSE PUT UNFORMATTED
string(crmProv.crmsiteNum) + crmProv.crmsiteCode +
string(crmProv.crmopCode) "~n".
END.
NEXT.
END.
ELSE FIND FIRST crmProv WHERE
crmProv.siteNum = photo.siteNum AND
crmProv.siteCode = photo.siteCode AND
crmProv.opCode = 0 AND
crmProv.sopCode = "" AND
crmProv.lotNum = 0
AND crmResNum = 0
NO-LOCK NO-ERROR.
IF AVAILABLE crmprov THEN DO:
FOR EACH crmProv WHERE
crmProv.siteNum = photo.siteNum AND
crmProv.siteCode = photo.siteCode AND
crmProv.opCode = 0 AND
crmProv.sopCode = "" AND
crmProv.lotNum = 0
AND crmResNum = 0
:
PUT UNFORMATTED photo.siteNum "~t" photo.siteCode "~t"
photo.opCode "~t"
photo.sopCode "~t" photo.lotNum "~t"
string(photo.siteNum) + photo.siteCode + "-" +
string(photo.photoNum) +
filmType "~t" crmProv.siteNum "~t" crmProv.siteCode "~t"
crmProv.opCode "~t" crmProv.sopCode "~t" crmProv.lotNum "~t".
IF crmProv.crmResNum > 0 THEN PUT UNFORMATTED
string(crmProv.crmsiteNum) + crmProv.crmsiteCode +
string(crmProv.crmopCode) + "-" + string(crmProv.crmresNum)
"~n".
ELSE PUT UNFORMATTED
string(crmProv.crmsiteNum) + crmProv.crmsiteCode +
string(crmProv.crmopCode) "~n".
END.
NEXT.
END.
ELSE PUT UNFORMATTED photo.siteNum "~t" photo.siteCode "~t" photo.opCode
"~t"
photo.sopCode "~t" photo.lotNum "~t"
string(photo.siteNum) + photo.siteCode + "-" + string(photo.photoNum) +
filmType "~t~t~t~t~t~t" string(photo.siteNum) + photo.siteCode +
string(photo.opCode) "~n".
END.
thanks,
Paul