Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions precompilers/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Precompiler Examples

This directory contains sample programs illustrating the use of Oracle Precompilers (Pro*C and Pro*COBOL).
It also includes makefiles for building and compiling these samples into executables.

## Prerequisites

### Oracle Packages / Components

If you are using the Oracle Instant Client, install the following packages for your platform:

- **Basic**
- **SDK**
- **Precompiler**

### Compilers

- A **C/C++ compiler** is required for the Pro*C samples.
- A **COBOL compiler** is required for the Pro*COBOL samples.

### Minimum Required Version

The minimum required **Oracle Database** and **Oracle Client** versions are **19c** in both cases.

## Included Files

| File Name | Description |
|-----------------------|-----------------------------------------------------------------------------------------------|
| [`procdemo.pc`](./procdemo.pc) | Sample Pro*C program demonstrating basic database operations using Oracle Precompiler. |
| [`procobdemo.pco`](./procobdemo.pco) | Sample Pro*COBOL program illustrating database interaction using Oracle Precompiler. |
| [`makefile_proc.mk`](./makefile_proc.mk) | Makefile for compiling the Pro*C example, managing dependencies, and generating the executable. |
| [`makefile_procob.mk`](./makefile_procob.mk) | Makefile for compiling the Pro*COBOL example, handling build processes, and producing the executable. |

## How to Compile and Run

To build the sample programs:

- Use `make -f makefile_proc.mk` for **Pro*C** samples.
- Use `make -f makefile_procob.mk` for **Pro*COBOL** samples.

Refer to the respective makefiles for more detailed instructions on compilation and execution steps.
123 changes: 123 additions & 0 deletions precompilers/makefile_proc.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
###############################################################################
# Make file for PROC demos
###############################################################################
# Usage :
# For compiling proc demos
# make -f makefile_proc.mk
#
# For precompiling, compiling & linking the procdemo.pc file
# make -f makefile_proc.mk build EXE=procdemo OBJS=procdemo.o
#
# In general, for any proc program
# make -f makefile_proc.mk build EXE=<exename> OBJS="<list of dependent objs>"
#
# To make use of any PROC options during precompilation,
# make -f makefile_proc.mk build PROCFLAGS="<list of proc options>"
# EXE=<exename> OBJS="<list of dependent objs>"
#
# NOTES:
# 1. Please change "cc/CC" and the "InstantClient directories" to point to
# appropiate locations on your machine before using this makefile.
# 2. In case of RPM installation, please change the following variables
# as mentioned below:
# PROC=/usr/lib/oracle/VV.v/client/bin/proc
# CCINCLUDES=$(I_SYM)/usr/include/oracle/VV.v/client
# PRECOMPPUBH=/usr/include/oracle/VV.v/client
# ICLIBHOME=/usr/lib/oracle/VV.v/client/lib/
# Legend:
# VV - Major Oracle version number
# v - Minor Oracle version number
# (Ex: For the release 11.2, VV = 11 and v = 2)
#
###############################################################################


CC=/usr/bin/gcc
cc=/usr/bin/gcc

# InstantClient Directories.
ICSDKHOME=../
ICLIBHOME=../../

MKLINK=ln
REMOVE=rm -rf
CLNCACHE=cleancache
CACHEDIR=SunWS_cachea
MAKE=make
MAKEFILE=makefile_proc.mk
PROCDEMO=procdemo

PROC=$(ICSDKHOME)/proc
SO_EXT=.so
I_SYM=-I

CCINCLUDES= $(I_SYM)$(ICSDKHOME)/include

# Pre-compiler Flags.
PRECOMPPUBH=$(ICSDKHOME)include

# Compiler Flags.
OPTIMIZE=-O2
LDPATHFLAG=-L
SPFLAGS=-DLINUX -D_GNU_SOURCE -D_LARGEFILE64_SOURCE=1 -D_LARGEFILE_SOURCE=1 -DSLTS_ENABLE -DSLMXMX_ENABLE -D_REENTRANT -DNS_THREADS
CCFLAGS= -fPIC -DPRECOMP
LDFLAGS=-g
LPFLAGS=
GFLAG=
CDEBUG=
USRFLAGS=
ICLIBPATH=$(LDPATHFLAG)$(ICLIBHOME)
PFLAGS=$(CCINCLUDES) $(SPFLAGS) $(LPFLAGS)
CFLAGS=$(GFLAG) $(OPTIMIZE) $(CDEBUG) $(CCFLAGS) $(PFLAGS) $(USRFLAGS)

# Libraries.
PROLDLIBS=$(LDCLIENTLIBS) $(THREADLIBS)
LDCLIENTLIBS=$(ICLIBPATH) $(LLIBCLNTSH) $(LDLIBS)
LLIBCLNTSH=$(LDLIBFLAG)$(LIBCLNTSHNAME)
LDLIBFLAG=-l
LIBCLNTCORENAME=clntshcore
LIBCLNTSHNAME=clntsh
LDLIBS=$(EXSYSLIBS) $(MATHLIB) $(USRLIBS)
EXSYSLIBS=-ldl
MATHLIB=-lm
THREADLIBS=-lpthread

C2O=$(CC) $(CFLAGS) -c $*.c
PCC2C=$(PROC) $(PROCFLAGS) iname=$(PCCSRC)
DEMO_PROC_BUILD=$(CC) -o $(EXE) $(OBJS) $(LDFLAGS) $(PROLDLIBS)

#-----------------------------------------------------------------------------
# Targets for building the proc sample programs.
all: clean $(PROCDEMO)

$(PROCDEMO):
$(MAKE) -f $(MAKEFILE) build OBJS=$@.o EXE=$@

build: $(CLNCACHE) $(OBJS)
$(DEMO_PROC_BUILD)

#-----------------------------------------------------------------------------
# Here are some rules for converting .pc -> .c -> .o
.SUFFIXES: .pc .c .o

pc1:
$(PCC2C)

.pc.c:
$(MAKE) -f $(MAKEFILE) PROCFLAGS="$(PROCFLAGS)" PCCSRC=$* I_SYM=include= pc1

.pc.o:
$(MAKE) -f $(MAKEFILE) PROCFLAGS="$(PROCFLAGS)" PCCSRC=$* I_SYM=include= pc1
$(C2O)

.c.o:
$(C2O)

#-----------------------------------------------------------------------------
# Clean up all executables, *.o and generated *.c files
clean: $(CLNCACHE)
$(REMOVE) $(PROCDEMO) $(PROCDEMO).o $(PROCDEMO).c $(PROCDEMO).lis

cleancache:
$(REMOVE) $(CACHEDIR)

96 changes: 96 additions & 0 deletions precompilers/makefile_procob.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
###############################################################################
# Make file for PROCOB demos
###############################################################################
# Usage :
# For compiling procob demos
# make -f makefile_procob.mk
#
# For precompiling, compiling & linking the procobdemo.pco file
# make -f makefile_procob.mk build EXE=procobdemo COBS=procobdemo.cob
#
# In general, for any procob program
# make -f makefile_procob.mk build EXE=<exename> COBS="<list of dependent cobs>"
# To make use of any PROCOB options during precompilation,
# make -f makefile_procob.mk build PROCOBFLAGS="<list of procob options>"
# EXE=<exename> COBS="<list of dependent cobs>"
#
# NOTES:
# 1. Please change "COB" and the "InstantClient directories" to point to
# appropiate locations on your machine before using this makefile.
# 2. In case of RPM installation, please change the following variables
# as mentioned below:
# PROCOB=/usr/lib/oracle/VV.v/client/bin/procob
# ICLIBHOME=/usr/lib/oracle/VV.v/client/lib/
# Legend:
# VV - Major Oracle version number
# v - Minor Oracle version number
# (Ex: For the release 18.1, VV = 12 and v = 1)
#
###############################################################################

COB=cob

# InstantClient Directories.
ICSDKHOME=../
ICLIBHOME=../../

MKLINK=ln
REMOVE=rm -rf
CLNCACHE=cleancache
CACHEDIR=SunWS_cachea
MAKE=make
MAKEFILE=makefile_procob.mk
PROCOBDEMO=procobdemo

PROCOB=$(ICSDKHOME)/procob
ICLIBPATH=$(LDPATHFLAG)$(ICLIBHOME)
SO_EXT=.so
COBFLAGS=-C IBMCOMP -C NESTCALL -t -x
LDPATHFLAG=-L
COBSQLINTF=$(ICLIBHOME)cobsqlintf.o
LDLIBS=$(EXSYSLIBS) $(MATHLIB) $(USRLIBS)
EXSYSLIBS=-ldl
MATHLIB=-lm
COBOL_PROLDLIBS=$(SHARED_CLIENTLIBS) $(LDLIBS)
SHARED_CLIENTLIBS=$(LLIBCLNTSH) $(LDFLAGS)
LLIBCLNTSH=$(LDLIBFLAG)$(LIBCLNTSHNAME)
LDLIBFLAG=-l
LIBCLNTCORENAME=clntshcore
LIBCLNTSHNAME=clntsh
LDFLAGS=-g

DEMO_PROCOB_BUILD=$(COB) $(COBFLAGS) -o $(EXE) $(COBS) $(ICLIBPATH) $(COBSQLINTF) $(COBOL_PROLDLIBS)

#-----------------------------------------------------------------------------
# Targets for building the procob sample programs.
#
# The target 'build' puts together an executable $(EXE) from the cobol
# sources in $(COBS) and the libraries in $(COBOL_PROLDLIBS).
# The rules to make .cob files from .pco files are later in this file.
#
all: clean $(PROCOBDEMO)

$(PROCOBDEMO):
$(MAKE) -f $(MAKEFILE) build COBS=$@.cob EXE=$@

build: $(CLNCACHE) $(COBS)
$(DEMO_PROCOB_BUILD)

#-----------------------------------------------------------------------------
# Here are some rules for converting .pco -> .cob -> .o and for .cob -> .gnt.
#
.SUFFIXES: .cob .cbl .o .pco $(GNT)

.pco.cob:
$(PROCOB) $(PROCOBFLAGS) iname=$*.pco

.cob$(GNT):
$(COB2GNT)

#-----------------------------------------------------------------------------
# Clean up all executables, *.o and generated *.cob files
clean: $(CLNCACHE)
$(REMOVE) $(PROCOBDEMO) $(PROCOBDEMO).o $(PROCOBDEMO).cob $(PROCDEMO).lis $(PROCOBDEMO).int $(PROCOBDEMO).idy

cleancache:
$(REMOVE) $(CACHEDIR)
125 changes: 125 additions & 0 deletions precompilers/procdemo.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* Copyright (c) 2025, Oracle and/or its affiliates.*/
/* All rights reserved.*/

/* NAME
* procdemo.pc - Pro*C demo program
*
* DESCRIPTION
* This program connects to ORACLE, declares and opens a cursor,
* fetches the names, salaries, and commissions of all
* salespeople, displays the results, then closes the cursor.
*
*/

#include <stdio.h>
#include <string.h>
#include <sqlca.h>
#include <stdlib.h>
#include <sqlda.h>
#include <sqlcpr.h>

#define UNAME_PWD_LEN 256

/*
* Use the precompiler typedef'ing capability to create
* null-terminated strings for the authentication host
* variables. (This isn't really necessary--plain char *'s
* would work as well. This is just for illustration.)
*/
typedef char asciiz[UNAME_PWD_LEN];

EXEC SQL TYPE asciiz IS CHARZ(UNAME_PWD_LEN) REFERENCE;
asciiz username;
asciiz password;

struct emp_info
{
asciiz emp_name;
float salary;
float commission;
};

void sql_error(msg)
char *msg;
{
char err_msg[512];
size_t buf_len, msg_len;

EXEC SQL WHENEVER SQLERROR CONTINUE;

printf("\n%s\n", msg);

/* Call sqlglm() to get the complete text of the
* error message.
*/
buf_len = sizeof (err_msg);
sqlglm(err_msg, &buf_len, &msg_len);
printf("%.*s\n", msg_len, err_msg);

EXEC SQL ROLLBACK RELEASE;
exit(EXIT_FAILURE);
}

void main()
{
struct emp_info *emp_rec_ptr;

/* Allocate memory for emp_info struct. */
if ((emp_rec_ptr =
(struct emp_info *) malloc(sizeof(struct emp_info))) == 0)
{
fprintf(stderr, "Memory allocation error.\n");
exit(EXIT_FAILURE);
}

/* application user to set the database credentials here */
/* CAUTION: Username and password buffers are 256 characters. */
/* Do not paste credentials longer than 256 characters. */

strcpy(username, "<username>");
strcpy(password, "<password>");

EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--");

EXEC SQL CONNECT :username IDENTIFIED BY :password;
printf("\nConnected to ORACLE as user: %s\n", username);

/* Declare the cursor. All static SQL explicit cursors
* contain SELECT commands. 'salespeople' is a SQL identifier,
* not a (C) host variable.
*/
EXEC SQL DECLARE salespeople CURSOR FOR
SELECT ENAME, SAL, COMM
FROM EMP
WHERE JOB LIKE 'SALES%';

/* Open the cursor. */
EXEC SQL OPEN salespeople;

/* Get ready to print results. */
printf("\n\nThe company's salespeople are--\n\n");
printf("Salesperson Salary Commission\n");
printf("----------- ------ ----------\n");

/* Loop, fetching all salesperson's statistics.
* Cause the program to break the loop when no more
* data can be retrieved on the cursor.
*/
EXEC SQL WHENEVER NOT FOUND DO break;

for (;;)
{
EXEC SQL FETCH salespeople INTO :emp_rec_ptr;
printf("%s %9.2f %12.2f\n", emp_rec_ptr->emp_name,
emp_rec_ptr->salary, emp_rec_ptr->commission);
}

/* Close the cursor. */
EXEC SQL CLOSE salespeople;

printf("\nGOOD-BYE!!\n\n");

EXEC SQL COMMIT WORK RELEASE;
exit(EXIT_SUCCESS);
}

Loading