Mainframe: JES2 and JES3 Control ‘/*’ Statements in Job Card

JES2+JES3+Mainframe

JES2+JES3+Mainframe

JES2,JES3 and JES statements:

Under JES2 and JES3, a job stream can also include JES2 or JES3 control statements that influence the way the Job Entry Subsystem processes your job.

In old projects, you may come across JES control statements in older job streams, and occasionally, they provide for a function that isn’t available in standard JCL.

Syntax for JES control statement;

/*identifier operation [parameters]

Frequently used JES2 commands in JOB cards:

/*$command-verb
Specifies JES2 operator commands. Must be placed before the JOB statement.

/*MESSAGE
Sends a message to the operator (see chapter 11).

/*NETACCT
Specifies the job account number.

/*NOTIFY
Notifies the specified user when the job is completed (same as the NOTIFY parameter on the JOB statement).

/*OUTPUT
Specifies SYSOUT processing options (see chapter 8).

/*ROUTE
Routes the job for execution or printing to a specific JES2 node.

/*SETUP
Instructs the operator to mount the specified tape volumes prior to job execution.

/*SIGNOFF
Ends a remote job session. May be placed anywhere in the job stream.

/*SIGNON
Begins a remote job entry session. Must be the first statement in the job stream.

/*XEQ
Routes the job to a specific JES2 node for execution.

/*XMIT
Transmits data to another JES2 node.

Mainframe: 3 Simple Ideas to Handle Cursor Position in CICS

Mainframe+Jobs+USA

Mainframe+Jobs+USA

These 3 techniques are so helpful for CICS-Mainframe programmers to implement handling cursor position.

  • Using IC:

First, if a map contains a single entry field, you can specify the IC option in the DFHMDF macro for that field.

For maps with more than one entry field, however, the IC technique isn’t flexible enough. So you’ll need to use one of the other two techniques: direct or symbolic cursor positioning.

Example:

CUSTNO DFHMDF POS=(2,26), X
LENGTH=6, X
ATTRB=(NORM,UNPROT,IC), X
COLOR=TURQUOISE, X
INITIAL=’______’

  • Direct Cursor Positioning:

To use direct cursor positioning, you include the CURSOR option on the SEND MAP command with a cursor position. Note that this cursor position is a displacement from the start of the screen, not a row/column address, so you have to calculate the value. Then, you can code the displacement directly in the CURSOR option, or you can move the value to a binary halfword field (PIC S9(4) COMP) that’s specified in the CURSOR option.

Example:

EXEC CICS
SEND MAP(‘MNTMAP1′)
MAPSET(‘MNTSET1′)
FROM(MNTMAP1O)
CURSOR(346)
END-EXEC.

Formula to find displacement:

The CURSOR value specifies a screen position that represents a displacement from the start of the screen. For a 24×80 screen, it must be a number from 0 to 1919, where 0 is row 1/column 1 and 1919 is row 24/column 80. To calculate the displacement for a screen position, use this formula:
(Row-number – 1) x 80 + (Column-number – 1) = Displacement

  • Symbolic Cursor:

Direct cursor positioning has two major drawbacks. First, cursor displacements are awkward to use. Second, and perhaps more important, direct cursor positioning ties your program to specific screen locations. So, if you change your mapset by moving a field from one screen location to another, you have to change your program as well.

Symbolic cursor positioning is much more flexible. With this technique, you move -1 to the corresponding length field in the symbolic map to tell CICS to move the cursor to that field. Then, you issue a SEND MAP command with the CURSOR option, but without a displacement value.

*Interview Question:

Note that if you move -1 to more than one length field, the cursor is positioned at the first field containing -1.

So, when you edit data entry fields, it’s common to move -1 to the length fields of all input fields that are invalid. That way, the cursor will be positioned at the start of the first field that’s in error.

Example:

MOVE –1 TO CUSTNO1L.

EXEC CICS
SEND MAP(‘MNTMAP1′)
MAPSET(‘MNTSET1′)
FROM(MNTMAP1O)
CURSOR
END-EXEC.

These COBOL File Status Codes Asked in Many Mainframe Interviews

Search+IT+JOBSThe below COBOL errors frequently being asked in many interviews, and occurring in day to day development of COBOL programs.

COBOL File Status Codes:

00- Successful

02-Duplicate alternate key

22-Duplicate Key

23-Record not found

24-Space not found to insert a record for KSDS or RRDS

34-Space not found for ESDS

46- Sequential READ, READ NEXT or READ PRIOR statement was attempted on a file open in the input or I-O mode and no valid next record had been established because the preceding START statement was unsuccessful.

>>>>>>[COBOL+MAINFRAME+JOBS]<<<<<<<

47-Read file not opened as INPUT or I/O

48-Write file not opened as OUTPUT/EXTEND/IO

39-Mismatch of logical record length

92-Logical errors

Examples for logical errors:

  • File locked
  • File already open
  • I-O to closed file
  • READ after end of file
  • CLOSE on unopened file

96-DD Not found

118-Verify performed successfully

Read more at IBM Material

Project Manager Responsibilities in Software Company (1 of 2)

ID-10042653Project Manager-Software

Project managers run the projects. Their role differs from that of technical managers, whose primary responsibility is maintaining the integrity of the systems.

How project managers learn skills

These managers have taken classes, read books, or attended seminars specifically dealing with the concepts of running a project. From this training they have learned the different parts of a project and how to put together a project plan to execute it.

They also understand tangible items such as critical paths, variances, scope creep, estimating, documentation, acquiring resources, setting up funding, budgeting, financial reporting, controlling when the project enters and ends a phase, communication plans, procurement, reporting project progress, and status.

Different Skills of Project Manager

  • Unlike technical managers, who are required to bring system, resource, and company knowledge, project managers are required to have knowledge only on how to run the project.
  • Each project a project manager runs will require different resources with different skills and knowledge because each project is unique. Resources are only assigned temporary to the project because they will only work on it for a short time. This means that project managers are not responsible for staff development.
  • To staff a project, these managers send a resource request to the area affected by the change. Who gets assigned and when the resource is available to work on the project are controlled not by the project managers but by the managers to whom the subordinates officially report. Project managers just take the resource names given to them and assign them to a task in the project plan.
  • Project managers’ responsibility to upper management is to report the project status.
  • Project managers gather the status information by talking to other project team members and checking the project plan.
  • From the project plan they can report the financial part of the project along with the completion percentage of the project. They also report and ask for help from upper management for any problems that are outside the control of the project. The most common issue is lack of available resources to do a project.
  • Departments that own the resources might decide that currently there are more important tasks for their staff than to work a project. Upper management needs to step in and help negotiate a solution. One solution could be that the department needs to release some resources to work on the project because it is a high priority. Another option is for upper management to give project managers approval to bring in outside contractors to do the project work.

Easytrieve Guide for Mainframe Programmers(3 of 20)

Hot+Mainframe+Jobs

Hot+Mainframe+Jobs

EZT+ LIBRARY

FILE STATEMENT

All files and their associated fields (including any Working Storage items) used in your EZT+ program MUST be described in the library section BEFORE they are used in your program.

The FILE STATEMENT is used to define the beginning of your FILE (or FILES)            and the field names you are going to be processing.

The FILE STATEMENT initiates your EZT+ logic and follows the / / SYSIN  JCL statement.

The syntax for the FILE STATEMENT is . . . . . . .

/ / SYSIN         DD    *

FILE           file-name  VS UPDATE

FILE:  This is a reserved keyword that marks the beginning of your

FILE                            DEFINITION.

file-name:  This is a 1 – 8 character name describing the file that you wish to                                               define.

The file-name used MUST be unique in your program.

The file-name MUST also correspond to the file as it is defined in the execution JCL.

VS:  indicates that this is a VSAM file

UPDATE:  indicates that the designated VSAM file can be updated.

NOTE: There are additional parameters available with the FILE STATEMENT, they will be discussed when they are applicable.

NOTE: See additional FILE definition requirements in the sections on       SUMMARY FILES and the SORT ACTIVITY.

 FIELD DEFINITION

An EZT+ field definition statement has four basic parts.  Each part is separated     by at least one space.  If more than one definition is on a line, they must be             separated by a period and a space.  Those basic parts are the FIELD NAME, the STARTING LOCATION, the FIELD LENGTH and the DATA FORMAT

FIELD NAME

*      A field name which is 1 – to – 40 characters long and unique in a                                                   particular file

STARTING LOCATION

*      The beginning location of the field relative to the first position of the                                           record (for working storage, a W or S is placed in this position)

*      Start-location can be explicitly defined relative to position one in the                                           record:

FILE  file-name

NAME                          1        17 (NAME begins in position 1)

ADDRESS     18        37 (ADDRESS begins in pos 18)

PAY-NET       55        10 (PAY-NET begins in pos 55)

  •   The start-location can be relatively defined as immediately following the end of the previously defined field:

FILE  file-name

FILLER1        *            5

NAME                        *          20              |   All field-names MUST

FILLER2        *            5               |   be defined when file

ADDRESS     *          20              |   is defined in this

FILLER3        *            5               |   manner.  This would include

PAY-NET       *          20                    FILLER also.

FIELD LENGTH

*      The length of the field in bytes

*      The length of the field has been added to our example below.

*      EZT+ permits the programmer to define a segment of a data item if they so desire, for instance; if they only wished to process fifteen (15) bytes of the NAME field they could define the length as 15, rather than 33 bytes.

FILE  file-name

NAME         17        15

ADDRESS  37        33

PAY-NET    90          4

DATA FORMAT

*      The type of data  (A,  N,  P,  U,  or B)

*  A  –  Alphabetic or alphanumeric

*  N  –  Zoned decimal

*  P  –   Packed decimal

*  U  –  Unsigned packed decimal

*  B  –  Binary

  •      The EZT+ programmer defines the DATA Format of the data item they are defining by adding the appropriate character AFTER the record length parameter.

FILE  file-name

NAME                     17        33        A

ADDRESS              37        33        A

PAY-NET                90          4        P

The maximum size that is permitted for each DATA FORMAT is shown below . . . . .

Data Format        Maximum Length                   Number of Decimal

Code                         (bytes)                                    Positions

A                              32,767                                     not valid

N                                     18                                     0  –  18

P                                      10                                     0  –  18

B                                       4                                     0  –  10

U                                       9                                     0  –  18

COBOL Data Division Clauses (1 of 3)

ID-100202161Many mainframe programmers not so clear about COBOL data division clauses. The below clauses extensively used in COBOL programmes. Also, the below are top COBOL interview questions.

The Data Division clauses are used to describe elementary and group data items. An elementary data item is a data item that is not further divided. COBOL provides many clauses to describe the characteristics of an elementary data item.

Group items cannot have PICTURE, SYNCHRONIZED, JUSTIFIED, or BLANK WHEN ZERO clauses.

REDEFINES

The REDEFINES clause lets you describe the same computer memory using different data descriptions. This clause can be used with both elementary and group data items.

data-name-1 REDEFINES data-name-2

The data-name-2 item must be a previously defined data item and must have the same level number as data-name-1. In addition, no entries with a lower-level number can occur between data-name-2 and data-name-1. In other words, data-name-1 must immediately follow the definition of data-name-2, except that multiple redefinitions of the same area are permitted. When you use multiple REDEFINES clauses, all the clauses must refer back to the original data-name that defined the area.

PICTURE

The PICTURE clause (together with the USAGE clause) defines the exact size, format, and type of data for an elementary item. Every elementary item, with a few exceptions, must have a PICTURE (or the abbreviation PIC) clause

03 FILLER PIC XXX

USAGE

The USAGE clause lets you specify the format of a data item in the computer’s memory to make most efficient usage of the computer’s memory space and arithmetic capabilities. The USAGE clause does not affect the use of an item (although some statements in the Procedure Division restrict some operands to certain USAGE clauses).

Interview question:

This clause can be used with both elementary and group data items.

USAGE IS :

  • Binary
  • Computational
  • Comp
  • DISPLAY
  • Index
  • Packed decimal

 

Sample COBOL DATE Program for Mainframe Projects

ID-100215509IDENTIFICATION DIVISION.

PROGRAM-ID. DAYS-BETWEEN.

ENVIRONMENT DIVISION.

DATA DIVISION.

WORKING-STORAGE SECTION.

01 DIFF-DAYS    PIC +++,+++,++9.

01 TOTAL-DAYS1  PIC S9(8) BINARY.

01 EDITED-DATE1 PIC X(20).

01 DATE1.

03 YY     PIC 99.

03 MM     PIC 99.

03 DD     PIC 99.

01 TOTAL-DAYS2  PIC S9(8) BINARY.

01 EDITED-DATE2 PIC X(20).

01 DATE2.

03 YY     PIC 99.

03 MM     PIC 99.

03 DD     PIC 99.

01 INPUT-DATE.

03 YY     PIC 99.

03 MM     PIC 99.

03 DD     PIC 99.

01 DATE-OK     PIC 9.

88 INVALID-DATE VALUE IS 1.

01 EDITED-DATE.

03 MM     PIC XXXB.

03 DD     PIC Z9,B.

03 YY     PIC 9(4).

01 TOTAL-DAYS   PIC S9(8) BINARY.

77 CTR          PIC S9(4) BINARY.

77 LEAP-YEAR    PIC S9(8) BINARY.

77 WORK-YEAR    PIC S9(4) BINARY.

77 REM          PIC S9(4) BINARY.

01 MMDD-TABLE.

03 DAYS     PIC X(24)

VALUE  “312831303130313130313031”.

03 MMDD     REDEFINES DAYS

PIC 99 OCCURS 12 TIMES.

01 MONTH-NAMES.

03 MONTHS   PIC X(36)

VALUE “JanFebMarAprMayJunJulAugSepOctNovDec”.

03 M-NAME   REDEFINES MONTHS

PIC XXX OCCURS 12 TIMES.

PROCEDURE DIVISION.

**Get first date

GET-FIRST-DATE.

DISPLAY “Enter first date (YYMMDD):”

ACCEPT DATE1.

MOVE DATE1 TO INPUT-DATE.

**Check date and compute number of days in first date

PERFORM DAYS-FROM-DATE THRU DAYS-FROM-DATE-EXIT.

IF INVALID-DATE

DISPLAY “Invalid Date!”

GO TO GET-FIRST-DATE.

MOVE EDITED-DATE TO EDITED-DATE1.

MOVE TOTAL-DAYS TO TOTAL-DAYS1.

GET-SECOND-DATE.

DISPLAY “Enter second date (YYMMDD):”

ACCEPT DATE2.

MOVE DATE2 TO INPUT-DATE.

**Compute number of days in second date

PERFORM DAYS-FROM-DATE THRU DAYS-FROM-DATE-EXIT.

IF INVALID-DATE

DISPLAY “Invalid Date!”

GO TO GET-SECOND-DATE.

MOVE EDITED-DATE TO EDITED-DATE2.

MOVE TOTAL-DAYS TO TOTAL-DAYS2.

SUBTRACT TOTAL-DAYS1 FROM TOTAL-DAYS2 GIVING DIFF-DAYS

DISPLAY “Date 1: “, EDITED-DATE1

DISPLAY “Date 2: “, EDITED-DATE2

DISPLAY “Difference in Days: “ DIFF-DAYS.

TERM-PROC.

EXIT PROGRAM.

**Check date is valid and compute the days since 01/01/1900

DAYS-FROM-DATE.

**Check that INPUT-DATE is legal

MOVE 0 TO DATE-OK.

IF YY OF INPUT-DATE IS NOT NUMERIC OR

MM OF INPUT-DATE IS NOT NUMERIC OR

DD OF INPUT-DATE IS NOT NUMERIC OR

MM OF INPUT-DATE IS LESS THAN 1 OR

MM OF INPUT-DATE IS GREATER THAN 12 OR

DD OF INPUT-DATE IS LESS THAN 1

MOVE 1 TO DATE-OK,

GO TO DAYS-FROM-DATE-EXIT.

**Compute the days as years * 365

COMPUTE TOTAL-DAYS = YY OF INPUT-DATE * 365.

**Then add 1 for each leap year

COMPUTE LEAP-YEAR  = (YY OF INPUT-DATE – 1) / 4.

COMPUTE TOTAL-DAYS = TOTAL-DAYS + LEAP-YEAR.

**Compute the number of days in February for the final year

DIVIDE YY OF INPUT-DATE BY 4 GIVING WORK-YEAR REMAINDER REM.

IF REM = 0 THEN

MOVE 29 TO MMDD(2)

ELSE

MOVE 28 TO MMDD(2).

**Check that days in month is legal

IF DD OF INPUT-DATE IS GREATER THAN MMDD(MM OF INPUT-DATE)

MOVE 1 TO DATE-OK,

GO TO DAYS-FROM-DATE-EXIT.

**Add number of days in each month up to the last

PERFORM VARYING CTR FROM 1 BY 1 UNTIL CTR = MM OF INPUT-DATE

COMPUTE TOTAL-DAYS = TOTAL-DAYS + MMDD(CTR)

END-PERFORM.

**Add the days in the last month

ADD DD OF INPUT-DATE TO TOTAL-DAYS

**Produce an edited form of the input date

MOVE DD OF INPUT-DATE TO DD OF EDITED-DATE.

ADD 1900, YY OF INPUT-DATE GIVING YY OF EDITED-DATE.

DAYS-FROM-DATE-EXIT.

EXIT.

END PROGRAM DAYS-BETWEEN.

Endevor Presentation for Mainframe Programmers

Endevor+Mainframe

Endevor+Mainframe

Endevor is a source code management and release management tool for mainframe computers running z/OS .It is part of a family of administration tools by CA Technologies (formerly Computer Associates), which is used to maintain software applications and track their versions.

The word ENDEVOR is an acronym which originally stood for Environment for Developers and Operations but is now the formal product name for CA’s flagship mainframe Application Lifecycle Management source control product. It also competes against another CA source code management tool, Panvalet (Ref: wiki)

The presentation covers the following topics:

  1. How to invokeENDEVOR
    • ENDEVOR
    • Quick EDIT
    • Parallel Development Manager
    • Bulletin System
  2. ENDEVOR
    • Default Settings
    • Display Elements
  3. Quick Edit
    • Environment
    • System
    • Sub System
    • Element
    • Type
    • Build Using Map
    • Return First Found
    • CCID
    • Display
      • Master
      • History
      • Summary
    • Compile/Generate
    • Sign-In/Sign-Out
    • Move

Download Endevor Tutorial:

Endevor_for_Mainframe_Programmers

 

Easytrieve Guide for Mainframe Programmers (2 of 20)

30+High+Paying+Jobs

30+High+Paying+Jobs

EZT+ SYNTAX

EZT+ and its free-form ENGLISH language structure make it easy for you to develop an efficient and flexible style of programming. To avoid fundamental programming errors you should follow these simple EZT+ syntax rules.

 STATEMENT AREA

             All EZT+ source statements are records of 80 characters.

             Column 1 – 72 are reserved for your EZT+ statements.

 It is recommended (just as with COBOL) to indent your EZT+ logical statements in order to increase the readability of your program.

 MULTIPLE STATEMENTS

             EZT+ allows the programmer to code several commands on one line.

 When coding several commands on one line you should use the period to delimit these commands.

 O/C programming standards strongly discourage the use of multiple commands     on one line – – this will NOT add to the readability of your program logic.

 COMMENTS

             EZT+ allows for comments to be placed within the logic of your program.

             Comments in an EZT+ program are recognized in several ways . . . . . . .

             *    The first non-blank character of a state is an asterisk () – – this can be in                                              any column

             * *   A statement containing ALL blanks

 NOTE: Comments can occur ANYWHERE in your EZT+ logic except within a              continued statement.

 CONTINUATION

 Continuation of an EZT+ statement is done by coding a plus-sign (+) or hyphen     (-) as the last non-blank character on a statement. The choice of continuation            characters (+/-) is important only when continuing a line in the middle of a word.

             For more information on continuation characters, see the SPECIAL            CHARACTERS discussion in the next topic.

 KEYWORDS

             EZT+ keywords can be used in the same way as they are used in a COBOL  program.

             Some keywords are reserved words and other keywords are non-reserved.

             A non-reserved keyword can be used as a field-name.

Reserved keywords CANNOT be used as field-names and when used as such will cause EZT+ processing errors.

MULTIPLE PARAMETERS

             Any time multiple parameters are coded in an EZT+ statement they MUST be  enclosed in parentheses.

 FIELD NAMES

 Field names are used to identify data items that reside on an input/output file or in Working Storage.

             Fields names are composed of a combination of NOT more than forty (40)             characters chosen from the following . . . . . . . . .

             * *   alphabetic characters (A – Z) in upper or lower case

             * *   decimal digits (0 – 9)

             * *   all special characters (except delimiters)

             Syntax rules regarding field names are . . . . . .

             * *   First character MUST be alphabetic or numeric

             * *   The name MUST contain at least one alphabetic or special character to                        distinguish the field name from a number

             * *   All field names MUST be unique (unless qualified)

 * * Qualified names are defined in the following way . . . . . . . .

FILEA : INSDNAME

WORK : INSDNAME

 The qualified name consists of the QUALIFYING word (FILEA or WORK) followed by a colon (:) and the field name in question.

 LABELS   

            Labels are used to specify JOBS, REPORTS, PROCEDURES or   PARAGRAPHS.

             Labels can be up to forty (40) characters long.

             They can contain any character other than a delimiter.

 Valid characters are any alphabetic (A – Z) or numeric digit (0 – 9) – – but they can NOT be all numbers.

 LITERALS

             Literals can be alphabetic or numeric.

             Alphabetic . . . . . . .

                     * *   They must be enclosed in single quotes

                     * *   They can contain anywhere from 1 – 254 characters

                     * *   They can contain ONLY EBCDIC characters

             Numeric . . . . . . . .

                     * *   They can contain up to eighteen (18) numeric digits

                     * *   A +/- sign prior to the value can be used to indicate the algebraic value

                     * *   A single decimal point can be used to indicate the specific fractional

                           value

             Hexadecimal . . . . . . .

                     They are used to code EBCDIC values containing characters that are NOT                 available on standard data entry keyboards.

                     You should code a HEXADECIMAL literal as follows . . . . . . .

                                                 X ‘ 4040 ‘

                    EZT+ compresses the pair of digits within the apostrophes into one (1)                                    character.

                     Valid characters in a HEXADECIMAL literal are 0 – 9 and A – F.

 SPECIAL CHARACTERS

 The following characters have special meaning to EZT+. They are always used according to these rules.

 *          (period) – The period terminates a statement. Although you can put more than one            statement on a line, in practice, each statement has it’s own line.

 *          (space) – The space, or blank, is the basic delimiter in each statement. Multiple blanks are read as one. For example:

                                     REGION 1 1 A

                                     REGION                    1 1 A

                            are the same to EZT+.

 (comma) – The comma can be used for readability. The comma means nothing to EZT+ so you still must use the required space delimiter between words.

  • For example:

                                     REGION, 1, 1, 1   — is valid

                                     REGION,1,1,A — is NOT valid

 (apostrophe) – The apostrophe encloses all alphabetic literals. This makes it             impossible to mistake a field name for a literal.

   Example:

                                     TITLE 1 ‘SAMPLE REPORT’

 *   + (plus) and – (hyphen) – Both plus and the hyphen are used to continue a                                   statement. They must be the last non-blank character on the line. The plus (+) implies that the statement continues at the first non-blank character of the next line. The hyphen (-) implies the statement continues on the first position of the next line.

                                     For example:   TITLE 1 ‘SAMPLE REP+

                                                                   ORT ‘

                                    prints               SAMPLE REPORT

                                    but:                  TITLE 1 ‘SAMPLE REP-

                                                                   ORT’

                                    prints               SAMPLE REP       ORT

 *          ( )   (parentheses) – Parentheses enclose multiple parameters. They also override the arithmetic order of operations and logical IF/AND/OR operations to force execution in a specified order

 *          *     (asterisk)   – The asterisk begins a comment statement. It must be the first character in the statement.

 For example:

                                     DEPT 1 1 N.         *THIS IS A COMMENT

 The first statement on this line defines the field DEPT. It ends with a period. The asterisk begins the second statement, a comment.

 NOTE: Spaces, apostrophes, periods, commas, parentheses and colons are

DELIMITERS and can NOT be used in LABELS and/or data names.

DB2- Use of ‘COALESCE’ Function (2 of 2)

ID-100221259Usage of COALESCE function, and detailed explanation.

SELECT bird_name, AVG(COALESCE(found_tally, 0))
FROM Samples AS SA
LEFT OUTER JOIN
SampleGroups AS SG
ON SA.sample_id = SG.sample_id
AND SA.bird_name = :my_bird_name
AND group_id = :my_group
GROUP BY bird_name;

Explanation:

The COALESCE function will inspect its parameter list and return the first non-NULL value, so this converts the AVG() parameter from NULL to zero. Most people seem to have trouble with the idea that an aggregate can handle an expression, not just a single column, as a parameter.

The other good trick in this solution is doing a LEFT OUTER JOIN on two columns instead of just one. This is very handy because the primary key of a table is not always just one column.