Datastage Scribble Sheet: Various
Datastage Scribble Sheet: Various
Datastage Scribble Sheet: Various
Various
Allow DataStage to see a UniData account
Need to activate Uniserver on the UniData account (free licence). This allows Objectcall to work from
DataStage.
Useful hex numbers
An Oracle null is defined by a bit being set, and as such can not be tested for directly from DataStage.
However, you can use an NVL to set a null value in the Oracle stage to something else, and then use
that same value in the lookup derivation:
ODBC’s
Server details
From DataStage Manager, to enable a new ODBC driver need to update the following DataStage
config files: .odbc.ini uvodbc.config
Note that there can also exist a local uvodbc.config file for a project. If there isn’t DataStage uses the
default file.
09/12/21 Page 1 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
Can also set Unix variables and then use them in DataStage jobs (dsenv is read before every DataStage
job. Accessed through Job Control => Parameters => Add Environmet Variable (which also allows
creation of new environment variables)
File types 1 and 19 are not hashed, good for programs. Type 30 is Dynamic. Types 2 to 18 are hashed.
Dictionary level defaults to type 3, modulo 1, separation 2.
To create a dynamic file, which is type 30, a directory (folder) with a flat file for the dictionary:
CREATE.FILE {filename} DYNAMIC
or
CREATE.FILE {filename} 30 1 2
or
CREATE.FILE {filename} 19
At DOS, both type 19 and type 30 (directory) files appear as a <DIR>, the difference being that the
type 19 (and type 1) directory is empty, whereas the type 30 directory contains files called DATA.30
and OVER.30
To create a file in a different directory or path name, use DataStage or refer to JCFILE CREATE.FL
09/12/21 Page 2 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
09/12/21 Page 3 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
DataStage shortcut
<CTRL> E to edit the highlighted stage derivation
NEXTID = Arg1
IF UNASSIGNED(OLDPARAM) THEN
OLDPARAM = NEXTID
TOTCOUNT = 0
END
09/12/21 Page 4 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
END ELSE
OLDPARAM = NEXTID
TOTCOUNT = 1
END
Ans = TOTCOUNT
09/12/21 Page 5 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
09/12/21 Page 6 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
09/12/21 Page 7 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
<110> = ditto
<111> = text: "DISPLAY" v7.5
<113> = text: "zoned, default=0" v7.5
<114> = set to multi-valued zeros
<115> = ditto
<116> = ditto
DS_CONTAINERS
Similar to DS_JOBS but for containers
<5> = JOBNO, recs exist in DS_JOBOBJECTS as above
RT_STATUSnnnn where nnnn = JOBNO
Job status file, id is JobName.Instance and JobName.Instance.1
In the .1 record can change status – attribute <2> - that appears in Director (for instance if can
not clear status file normally)
3 – Aborted
2 – Finished
0 or 1 – Running?
See JCFILE JC_TRANS for routine to duplicate derivations and many other useful bits. Also see
JC_TRANSALL, JC_TABLES and JC_METADATA
CALL DSU.ExecDOS(TEXT,ERR) with both the DSU. at the front and the ERR argument – good
and useful example of this is JCFILE CREATE.FL to create files in a remote path name
These are included in the routine used to set / change a job’s parameters:
$INCLUDE DSINCLUDE DSD_STAGE.H
$INCLUDE DSINCLUDE JOBCONTROL.H
$INCLUDE DSINCLUDE DSD.H
$INCLUDE DSINCLUDE DSD_RTSTATUS.H
At top of routine:
Deffun FindMatchingContracts(InFile, OutFile, DBSOURCE) Calling "DSU.FindMatchingContracts"
Later in code:
VAR = FindMatchingContracts(InFile,OutFile,DBSOURCE)
09/12/21 Page 8 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
dsjob -run #MyParam# (I set this to -wait) DevScanDocsBuildTxtForBatch - this works locally,
but dsjob also allows a login to a remote server - dsjob -server servername -user username
-password password
Refer to DataStage Server Job Developer’s Guide manual for dsjob documentation.
The –wait waits for the job to finish. The –local is only really necessary if changing environment
variables. Other dsjob options are:
set BKDBASE=PRBK
set DSPROJECT=ProdProbis
set DAYNUM=%date:~4,2%
09/12/21 Page 9 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
For example (on Unix), write a script and run it using ftp to move files around:
* Now write the script to execute – note the “quote site…” bit to do a remote chmod on the file after putting it
ScriptName = "IUC090script"
Write Script On Fv, ScriptName Else
Call DSLogFatal("Unable to write file ":ScriptName:" to .",RoutineName)
End
DataStage Macros
The following can be used within the derivations of a transform to return the information:
09/12/21 Page 10 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
Equ DSJS.RUNNING To 0 ;* This is the only status that means the job is
actually running
Equ DSJS.RUNOK To 1 ;* Job finished a normal run with no warnings
Equ DSJS.RUNWARN To 2 ;* Job finished a normal run with warnings
Equ DSJS.RUNFAILED To 3 ;* Job finished a normal run with a fatal error
Equ DSJS.VALOK To 11 ;* Job finished a validation run with no warnings
Equ DSJS.VALWARN To 12 ;* Job finished a validation run with warnings
Equ DSJS.VALFAILED To 13 ;* Job failed a validation run
Equ DSJS.RESET To 21 ;* Job finished a reset run
Equ DSJS.CRASHED To 96 ;* Job has crashed
Equ DSJS.STOPPED To 97 ;* Job was stopped by operator intervention
(can't tell run type)
Equ DSJS.NOTRUNNABLE To 98 ;* Job has not been compiled
Equ DSJS.NOTRUNNING To 99 ;* Any other status
IF JOBNAME = -1 THEN
* Ignore jobs that are not compiled
END ELSE
BEGIN CASE
CASE STATUS = DSJS.RUNFAILED
TXT = "Job ":JOBNAME:" status Run Failed (Aborted)"
CASE STATUS = DSJS.VALFAILED
TXT = "Job ":JOBNAME:" status Validation Failed"
CASE STATUS = DSJS.CRASHED
TXT = "Job ":JOBNAME:" status Crashed"
CASE STATUS = DSJS.STOPPED
TXT = "Job ":JOBNAME:" status Stopped"
CASE STATUS = DSJS.NOTRUNNABLE
TXT = "Job ":JOBNAME:" status Not Runnable"
CASE 1
TXT = "Job ":JOBNAME:" okay - ":STATUS
* Call DSLogInfo(TXT,RoutineName)
TXT = ""
END CASE
Ensure job is in a runnable state from within Job Control (Batch job)
* Ensure job is in a runnable state
09/12/21 Page 11 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
NOTRUNNABLE = 98
RUNFAILED (Aborted) = 3
CRASHED = 96
Finished = 1
Compiled = 99
Reset = 21
09/12/21 Page 12 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
Note the addition of the second file name, B and C in lieu of the full file names, and the where
clause
Using an ODBC stage to access, select, look-up on a txt file (on NT)
This allows sql statements on a sequential (.csv or .txt) file!
Save the csv file as a tab delimited text file
Use Control Panel to set up an ODBC driver on the (NT) server:
o System DSN
o Microsoft text driver
o Select the directory
o .TAB
o define format
o tick Column Name Header
o select OEM box
o click on GUESS box (if change name click Modify)
o doing this will generate a Schema.ini file
o If ever need to modify anything delete this Schema.ini file first
DataStage Manager:
o Import table definitions from the driver just created
DataStage Job
o Use ODBC stage
o Quote = 000
o Load columns, remove prefixies in column derivations
Warning Messages
Warning message in log regarding Phantom processes
For example: DataStage Job 270 Phantom 1364
Program "JOB.1215067440.DT.1362629138.TRANS1": Line 301, Variable previously
undefined. Zero length string used.
The Job number is 270 meaning that under that project directory there will
be a subdirectory called RT_BP270. Under this directory will be the source
code for JOB.1215067440.DT.1362629138.TRANS1. Each transformer will have a
program. In this case you have a transformer called TRANS1. It should be
possible to work out line 301 by looking at the transformer.
09/12/21 Page 13 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
./DataStage/DSEngine/errlog
Normally happens if using user-defined SQL, stage can’t find the table name. Change the user-defined
SQL to be built normally, put the table name into the ‘build’ section, save the stage, then return it to
user-defined SQL
Due to trying to accumulate data in the SQL in the Oracle stage, using the GROUP BY command.
Might need to feed the relevant data into a hash file first. Amazingly this also works in a container, i.e.
the hash file is built once at the start of the process.
This is due to the Oracle table having a datatype different to that defined in the stage Columns. For
instance, the stage might say TIMESTAMP whereas the Oracle table says DATE.
This is caused by DataStage reading a file and the record is not on file. The fields used later in the
process then can contain an SQL null. To fix pass the relevant file fields through an IsNull test after
every look-up
NOTE: All fields in a Primary Key in Oracle are mandatory – i.e. can not have a
NULL primary key field
Message:
CustConvertRepeatRows.O_CIO2: [IBM][CLI Driver][AS] SQL0913N Unsuccessful execution
caused by deadlock or timeout. Reason code "TESTCONV1.CUSTO00004".
SQLSTATE=57033
09/12/21 Page 14 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
Message:
Buffer overflow
Normally caused by a field being too long for its target field
Message:
M0094NSRClaimPaddr..NSR_CLAIM.SourceFile: ds_udtopen() - Unable to connect to server
UniData Client error: call to UniOpenPos returned 20 - Client and server product identifiers
don't match: received The udt counter and returned counter
M0094NSRClaimPaddr..NSR_CLAIM.SourceFile: DSD.UDTOpen GCI $DS.UDTOpen error 24.
Message:
Unable to Compile and Catalog DSHELPER subroutine -
aaPopulateXrefFileCM..COMMON_LAND.in
To do with UniData – DSHELPER has to be globally catalogued in the UniData system, then available
from any account
Message:
DA1522_26000_ETL2TransformJob.1522.DA1522_Prepare_Trf.Data: ds_ipcflush() - Error in
mutex_unlock() - Operation not permitted.
To do with locking, maybe lock left at Universe level (LIST.READU) but no longer there at UNIX
level (not in ps –ef). This can happen if a job does “Attempting to Cleanup after ABORT raised in stage” but
there was no reason why it aborted.
Message:
Data has been truncated
To identify field that is too long change output to fixed-length flat file and run the job, then the log
identifies the column!
Killing a process
Find the pid of the process, possibly by doing a LIST.READU
Then kill it using LOGOUT –{pid}
LISTU – shows users logged on
UNLOCK ALL or other option – from UV account, clears all locks
UNLOCK USER 61234 ALL for one specific user (Userno column in LIST.READU)
Repeat commands:
09/12/21 Page 15 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
Get Unix to finish typing for you (it will fill the unique bit of the file name):
<ESC>\ and file name is completed automatically
The argument '{}' inserts each found file into the grep command line. The \; argument
indicates the exec command line has ended.
Display all hash files excluding dictionary levels and log files:
ls –l ./HashFiles/ | grep –v ‘_D’ | grep –v ‘LOG’ | pg
09/12/21 Page 16 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
ORACLE performance
For stats re processes that are running use, or pick out relevant columns:
SQL
Wildcard character is ‘%’ (matches zero or more characters). Underscore ‘_’ matches 1 character.
Also have the NOT operand.
Comparisons allowed are: =, <>, <, <=, >, >=
/* used to include comments on SQL query page */
Simple SQL commands:
SELECT TABLE_NAME FROM USER_TABLES;
DESC {tablename}; – show colums in the table
SELECT (*) FROM {tablename};
SELECT COL1, COL2, COL3 FROM {tablename};
SELECT NAME FROM SALESPREPS
WHERE REP_OFFICE IS {NOT} NULL;
SELECT NAME, SALES, QUOTA, (SALES – QUOTA) FROM SALESREPS
WHERE SALES < QUOTA;
SELECT A, B, C, AMOUNT FROM ORDERS
WHERE AMOUNT > 2500.00 AND ORDER_NUM > 200200
ORDER BY AMOUNT;
SELECT ORDER_NUM, AMOUNT FROM ORDERS
WHERE AMOUNT BETWEEN 20000.00 AND 29999.99
ORDER BY ORDER_NUM, AMOUNT;
SELECT ORDER_NUM, ORDER_DATE, AMOUNT FROM ORDERS
WHERE REP_OFFICE IN (11, 13, 22);
Select customer called Smithson … or Smithsen …
SELECT COMPANY, CREDIT_LIMIT FROM CUSTOMERS
WHERE COMPANY_NAME LIKE ‘Smiths_n %’;
Allocating table names a letter and using that:
SELECT C.Account_Number,C.Lessee_Name,…etc…,B.Insurance_Indicator
FROM STH_Customers C,STH_Bookings B WHERE C.Account_Number =
B.Account_Number;
09/12/21 Page 17 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
SELECT TABLEID,
TIMECREATED,
JOBID
FROM data_control_table
WHERE scheme = 'Aesis'
AND TRUNC(TIMECREATED) = TO_DATE ('08-DEC-03', 'DD-MON-YY')
ORDER BY timecreated,
tableid
Summarising data:
SELECT AVG(100 * (SALES / QUOTA)) FROM SALESREPS;
Average size of an order in the database:
SELECT AVG(AMOUNT) FROM ORDERS
WHERE CUST = 213423;
Total amount of orders by customer (group orders by customer and total):
SELECT CUST, SUM(AMOUNT) FROM ORDERS
GROUP BY CUST;
SELECT REP, CUST, SUM(AMOUNT) FROM ORDERS
GROUP BY REP, CUST;
Minimum and maximum size of an order in the database:
SELECT MIN(QUOTA), MAX(QUOTA) FROM SALESREPS;
Count how many orders in the database (counts number of rows):
SELECT COUNT(*) FROM ORDERS;
SELECT COUNT(AMOUNT) FROM ORDERS WHERE AMOUNT > 25000.00;
Count distinct number of titles:
SELECT COUNT(DISTINCT TITLE) FROM SALESREPS;
For 3 particular sinds count and group by year (APDATE=DD^MMM^YY):
SELECT SUBSTR(APDATE,8,2), COUNT(SUBSTR(APDATE,8,2)) FROM
COMPOSITE_FWPS_AGREEMENT WHERE SIND IN (8,12,29) GROUP BY
SUBSTR(APDATE,8,2);
Updating data in the database:
09/12/21 Page 18 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
Pure Iner Join A AND B Merges only those rows with the same key values in
both input files
Right and Left Only A NOR B Merges all rows from both files except those rows
with the same key values
Left Outer Join A Merges all rows from the first file (A) with rows from
the second file (B) with the same key
Right Outer Join B Merges all rows from the second file (B) with rows
from the first file (A) with the same key
Left Only A NOT B Merges all rows from the first file (A) except rows
with the same key in the second file (B)
Right Only B NOT A Merges all rows from the second file (B) except rows
with the same key in the first file (A)
NULL handling
In a WHERE clause any condition that does not explicitly mention NULL values automatically
fails if one of the values is NULL. Hence
SALMONELLA_STATUTORY_SPP_FLAG <> 'T' / 'F' will automatically yield FALSE if
SALMONELLA_STATUTORY_SPP_FLAG is a null. If you want to cater for nulls then you
should put:-
09/12/21 Page 19 of 20
/conversion/tmp/scratch/58361818.doc
DataStage Scribble Sheet
In 1, the GROUP BY function does include a grouping by the NULL value for any term, so the
NULL fields are included and counted.
If you want to include nulls in a different way you can also use the function
NVL(field_which_could_be_null, value_to_replace_NULL_with) e.g.
09/12/21 Page 20 of 20
/conversion/tmp/scratch/58361818.doc