Download Oracle to IBM Informix Server Porting Guide

Document related concepts

Microsoft Jet Database Engine wikipedia , lookup

Database wikipedia , lookup

Entity–attribute–value model wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

Open Database Connectivity wikipedia , lookup

Clusterpoint wikipedia , lookup

Extensible Storage Engine wikipedia , lookup

SQL wikipedia , lookup

Relational model wikipedia , lookup

Database model wikipedia , lookup

Oracle Database wikipedia , lookup

PL/SQL wikipedia , lookup

Transcript
IBM Software Group
IBM Information Management
Oracle to IBM Informix Server
Porting Guide
A discussion of porting issues and
Informix Server 11
Prepared By:
Business Partner Technical Enablement
Competitive Technologies and Enablement
IBM Data Servers, IBM Software Group
June 2012
Version 1.6
1
IBM Software Group
IBM Information Management
© Copyright IBM Corporation 2012. All Rights Reserved.
Trademarks
IBM, AIX, DB2, DB2 Universal Database, Informix, and iSeries are trademarks of the International
Business Machines Corporation in the United States, other countries or both. UNIX and Unixbased trademarks and logos are trademarks or registered trademarks of The Open Group. Intel
and Intel-based trademarks and logos are trademarks or registered trademarks of Intel
Corporation. Windows is a trademark of Microsoft Corporation in the United States, and other
countries, or both. Linux is a registered trademark of Linus Torvalds in the United States, other
countries, or both. Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other
company, product or service names may be the trademarks or service marks of others.
Disclaimer
References in this publication to IBM products or services do not imply that IBM intends to make
them available in all countries in which IBM operates.
The following paragraph does not apply to the United Kingdom or any other country where such
provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES
CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
PARTICULAR PURPOSE.
Some states do not allow disclaimer of express or implied warranties in certain transactions,
therefore, this statement may not apply to you.
The use of this information or the implementation of any of these techniques is your responsibility
and depends on your ability to evaluate and integrate them into your operational environment.
While each item may have been reviewed by IBM for accuracy in a specific situation, there is no
guarantee that the same or similar results will be obtained elsewhere. Customers attempting to
adapt these techniques to their own environments do so at their own risk.
This information could include technical inaccuracies or typographical errors. Changes are
periodically made to the information herein; these changes will be incorporated in new editions of
the publication. IBM may make improvements and/or changes in the product(s) and/or the
program(s) described in this publication at any time without notice.
Information concerning non-IBM products was obtained from the suppliers of those products, their
published announcements or other publicly available sources. IBM has not tested those products
and cannot confirm the accuracy of performance, compatibility or any other claims related to nonIBM products. Questions on the capabilities of non-IBM products should be addressed to the
suppliers of those products.
The information in this white paper is provided AS IS without warranty. Such information was
obtained from publicly available sources, is current as of December 2011, and is subject to
change. Any performance data included in the paper was obtained in the specific operating
environment and is provided as an illustration. Performance in other operating environments may
vary. More specific information about the capabilities of products described should be obtained
from the suppliers of those products.
Version 1.6
2
IBM Software Group
IBM Information Management
Document History
Revision History
Authoring
Original Document (May 2000)
Glen Black, Frank Martino & Tim Tobey
Informix Software Incorporated, Partner Engineering Organization
Revisions for Informix Dynamic Server.2000, Version 6 (July 2000)
Tim Tobey
Informix Software Incorporated, Partner Engineering Organization
Updated to IBM Informix Dynamic Server Database Version 9, Release 4. (February 2004)
Christine Normile
Informix Dynamic Server Product Manager
IBM Software Group, Information Management
Updated material for Sequence Objects (December 2004)
Sam Marino
DB2 Business Partner Technical Enablement
IBM Information Management Solutions, IBM Software Group
Updated to IBM Informix Dynamic Server Database Version 10.00 (January 2006)
Sam Marino
Business Partner Technical Enablement – Data Services
IBM Information Management, IBM Software Group
Updated to IBM Informix Dynamic Server Database Version 11.10 (December 2007)
Sam Marino
IBM Business Partner Technical Enablement – Data Services
IBM Information Management, IBM Software Group
Updated material for delimited identifiers, metadata extraction, type conversion, and
miscellaneous (June 2012)
Chris Golledge
IBM Information Management, IBM Software Group
Contributions
Technical Reviewers
Keshava Murthy
IBM Informix Database Server Development
IBM Software Group, Information Management
Lakshman Sakaray
IBM Database Migration Toolkit
IBM Software Group, Information Management
Version 1.6
3
IBM Software Group
IBM Information Management
Table of Contents
CHAPTER 1:
INTRODUCTION ............................................................................................ 8
PURPOSE ........................................................................................................................................ 8
PRODUCT OVERVIEW ....................................................................................................................... 8
ORGANIZATION................................................................................................................................ 8
CONVENTIONS ................................................................................................................................ 9
CHAPTER 2:
DEFINING THE PROBLEM SPACE ............................................................ 11
EXTRACTING THE OBJECTS TO BE MIGRATED .................................................................................. 11
Working With Oracle Dump Files ............................................................................................ 11
CHAPTER 3:
DATA DEFINITION LANGUAGE ................................................................. 15
IDENTIFIERS .................................................................................................................................. 15
Delimited identifiers ................................................................................................................. 15
Explicit versus implicit schema/owner names ......................................................................... 17
Reserved words or keywords .................................................................................................. 18
Summary ................................................................................................................................. 19
DATABASES .................................................................................................................................. 19
Databases, database names and instances ........................................................................... 19
ANSI vs. non-ANSI .................................................................................................................. 20
TABLESPACES AND DBSPACES ....................................................................................................... 20
TABLES......................................................................................................................................... 21
Attributes and general syntax .................................................................................................. 21
Lock mode ............................................................................................................................... 21
Storage .................................................................................................................................... 21
Constraints .............................................................................................................................. 22
ALTER TABLE......................................................................................................................... 22
Data Partitioning ...................................................................................................................... 23
DATA TYPES.................................................................................................................................. 25
Numeric ................................................................................................................................... 25
CHAR, VARCHAR and LVARCHAR ....................................................................................... 26
Date and Time ......................................................................................................................... 27
Interval ..................................................................................................................................... 27
Raw data and Large Objects ................................................................................................... 28
ROWID .................................................................................................................................... 28
User-defined types .................................................................................................................. 29
Complex data types ................................................................................................................. 30
SEQUENCE OBJECTS ..................................................................................................................... 30
Oracle sequences.................................................................................................................... 30
Informix sequences ................................................................................................................. 30
INDEXES ....................................................................................................................................... 30
Composite indexes .................................................................................................................. 30
Maximum key size ................................................................................................................... 31
Index fragmentation ................................................................................................................. 31
General index information ....................................................................................................... 31
VIEWS .......................................................................................................................................... 32
STORED PROCEDURES AND TRIGGERS ........................................................................................... 32
ORACLE EXTENSIONS .................................................................................................................... 33
CHAPTER 4:
DATA MANIPULATION LANGUAGE .......................................................... 34
SQL ............................................................................................................................................. 34
Labels using keywords ............................................................................................................ 34
Inequality operations ............................................................................................................... 34
Selects ..................................................................................................................................... 34
Optimizer directives ................................................................................................................. 34
Version 1.6
4
IBM Software Group
IBM Information Management
External optimizer directives .................................................................................................... 35
Inserts ...................................................................................................................................... 36
Temporary tables..................................................................................................................... 36
Outer joins ............................................................................................................................... 36
Sorts ........................................................................................................................................ 36
Exceptions ............................................................................................................................... 37
Correlation names ................................................................................................................... 37
Aliases ..................................................................................................................................... 37
Hierarchical queries ................................................................................................................. 37
Truncate .................................................................................................................................. 39
HOST VARIABLES........................................................................................................................... 40
DATE AND TIME FUNCTIONS ........................................................................................................... 41
SYSDATE ................................................................................................................................ 41
Number formats ....................................................................................................................... 41
Date formats ............................................................................................................................ 42
The RR date format element ................................................................................................... 43
USER-DEFINED ROUTINES .............................................................................................................. 43
COMPATIBLE SQL FUNCTIONS ....................................................................................................... 43
AGGREGATE FUNCTIONS ................................................................................................................ 43
MATHEMATICAL FUNCTIONS ........................................................................................................... 44
STRING FUNCTIONS ....................................................................................................................... 44
LENGTH .................................................................................................................................. 44
LTRIM and RTRIM .................................................................................................................. 44
Oracle Extensions ................................................................................................................... 44
OTHER ORACLE FUNCTIONS .......................................................................................................... 44
MACROS ....................................................................................................................................... 45
%ISOPEN and %NOT FOUND ............................................................................................... 45
%ROWTYPE ........................................................................................................................... 45
%TYPE .................................................................................................................................... 45
PSEUDO-COLUMNS ........................................................................................................................ 45
LEVEL ..................................................................................................................................... 46
ROWID .................................................................................................................................... 46
ROWNUM................................................................................................................................ 46
UPDATE USING CURSORS............................................................................................................... 49
SYSTEM TABLES ............................................................................................................................ 50
STORED PROCEDURES .................................................................................................................. 50
Size limit .................................................................................................................................. 50
Parameter limit ........................................................................................................................ 50
Packages ................................................................................................................................. 51
Routines .................................................................................................................................. 51
Exceptions ............................................................................................................................... 51
Error handling .......................................................................................................................... 52
Cursors .................................................................................................................................... 52
Variable declaration and assignment ...................................................................................... 53
Boolean ................................................................................................................................... 53
Binary data types ..................................................................................................................... 53
Dynamic SQL .......................................................................................................................... 53
Compiler .................................................................................................................................. 53
TRIGGERS..................................................................................................................................... 54
CONSTRAINTS ............................................................................................................................... 55
DUAL TABLE................................................................................................................................. 55
CHAPTER 5:
EMBEDDED SQL......................................................................................... 57
HOST VARIABLES ........................................................................................................................... 57
Declaration override ................................................................................................................ 57
Arrays ...................................................................................................................................... 57
Formatting ............................................................................................................................... 58
SQL STRUCTURES ........................................................................................................................ 59
Version 1.6
5
IBM Software Group
IBM Information Management
SQLCA .................................................................................................................................... 59
SQLDA .................................................................................................................................... 60
ORACA .................................................................................................................................... 61
PRE-COMPILER OPTIONS................................................................................................................ 61
EMBEDDED PL/SQL ...................................................................................................................... 61
ORACLE CALL INTERFACE .............................................................................................................. 61
Database library calls .............................................................................................................. 62
Global area processing............................................................................................................ 62
Fetch cycle .............................................................................................................................. 62
RAW binary data type processing ........................................................................................... 62
Parameter bindings ................................................................................................................. 62
EMBEDDED SQL FOR C ................................................................................................................. 63
VARCHAR ............................................................................................................................... 63
Host variables .......................................................................................................................... 63
EMBEDDED SQL FOR COBOL ....................................................................................................... 63
VARCHAR ............................................................................................................................... 63
Level 88 ................................................................................................................................... 64
SQLDA .................................................................................................................................... 64
REDEFINES ............................................................................................................................ 64
Tips .......................................................................................................................................... 64
ODBC .......................................................................................................................................... 64
CHAPTER 6:
APPLICATION ARCHITECTURE ................................................................ 65
TRANSACTION PROCESSING ........................................................................................................... 65
Autonomous Transaction......................................................................................................... 66
Savepoints ............................................................................................................................... 67
CONCURRENCY ............................................................................................................................. 67
Row Level Locking .................................................................................................................. 67
Transaction Isolation Level ...................................................................................................... 68
CHAPTER 7:
SECURITY ................................................................................................... 70
USER AUTHENTICATION ................................................................................................................. 70
Operating system security ....................................................................................................... 70
Non-operating system security ................................................................................................ 70
ROLE BASED AUTHORITY ............................................................................................................... 71
COLUMN-LEVEL ENCRYPTION ......................................................................................................... 71
Passwords and hints ............................................................................................................... 71
Encrypting a column ................................................................................................................ 72
Querying an encrypted column................................................................................................ 72
Performance impact of encryption ........................................................................................... 73
Storage considerations ............................................................................................................ 73
Compliance regulations ........................................................................................................... 73
CHAPTER 8:
ENVIRONMENT ........................................................................................... 74
SCRIPTS ....................................................................................................................................... 74
SQL script substitution variables ............................................................................................. 74
UTILITIES ...................................................................................................................................... 75
SYSTEM CATALOG ......................................................................................................................... 75
CHAPTER 9:
USING BLADELETS .................................................................................... 76
W HAT IS A BLADELET? .................................................................................................................. 76
INFORMIX EXEC BLADELET FOR DYNAMIC SQL ............................................................................... 77
SQLLIB DATABLADE MODULE (SQLLIBC.1.1 / SQLLIBJ.1.1) ............................................................ 78
A P P E N D I X A:
PLANNING GUIDE ..................................................................................... 79
A P P E N D I X B:
SYNTAX COMPARISON ............................................................................ 82
Version 1.6
6
IBM Software Group
IBM Information Management
A P P E N D I X C:
DATABASE CONCEPTS ........................................................................... 84
A P P E N D I X D:
SAMPLE CODE .......................................................................................... 85
DATE ARITHMETIC ......................................................................................................................... 88
UNITS Keyword ....................................................................................................................... 88
Using EXTEND function .......................................................................................................... 88
STRING REPRESENTATION OF DATE AND TIME ................................................................................. 88
Day and date ........................................................................................................................... 88
Abbreviation of day of week .................................................................................................... 88
USING AN INFORMIX COLLECTION DATA TYPE .................................................................................. 89
A collection data type as a VARRAY ....................................................................................... 89
Using MULTISET and ROW to replace PL/SQL TABLE and RECORD types ........................ 91
A P P E N D I X E:
COUNTING SYSTEM OBJECTS ............................................................... 93
USING THE SYSTEM CATALOG ........................................................................................................ 93
System catalog ........................................................................................................................ 93
USING SQL CODE ......................................................................................................................... 94
Built-in function references ...................................................................................................... 94
Object types and counts .......................................................................................................... 95
A P P E N D I X F:
DATA TYPE MAPPING .............................................................................. 97
DOUBLE ................................................................................................................................ 101
VARCHAR ............................................................................................................................. 101
NUMBER ............................................................................................................................... 101
National language types ........................................................................................................ 102
ROWID .................................................................................................................................. 102
%TYPE .................................................................................................................................. 102
%ROWTYPE ......................................................................................................................... 102
FLOAT ................................................................................................................................... 102
XMLType ............................................................................................................................... 103
Version 1.6
7
IBM Software Group
CHAPTER 1:
IBM Information Management
Introduction
This document is a technical document describing the differences between Oracle and Informix®
Dynamic Server (IDS) functionality and syntax. . This porting guide details differences between
Oracle’s 10g release 1 (10.1) and 10g release 2 (10.2) and Informix Dynamic Server (version
11.10). In addition, it can be a useful reference for all migrations between the two database
servers regardless of version. In addition to DDL, DML and overall SQL syntax, this document
explores the differences between Oracle and Informix with regards to object technology through
the use of large objects, user defined types, and user defined routines. It also looks at the
differences between Oracle’s table partitioning and Informix’s table fragmentation. Part of the
explanation is a discussion on what needs to be changed to make an application running on an
Oracle database run on an Informix database. If there is more than one way to port some piece of
functionality, alternatives and recommendations are also discussed.
This document is intended to be a living document. Missing items, better ways of implementing
Oracle functionality in Informix other than what is documented here, examples to better illustrate a
point, and other suggestions should be sent to Chris Golledge ([email protected]) so they
may be included with future revisions.
Purpose
This document should be used as a guide to assist in porting applications that run on an Oracle
database server to run on an Informix database server. Regardless of whether a porting effort will
be completely manual or if tools will be utilized, this document can provide value. Obviously, if the
port is performed manually, this guide will provide the most value. If the port will utilize tools, then
analysis can be performed using this guide to determine how much of the application the tools will
convert, and how much must be converted manually. In any case, this guide is intended to be
used to both visualize the scope of a porting effort and to aid in the porting effort by addressing
the technical issues.
This document will be refined based on users’ experiences to identify as many of the porting
issues as possible at the beginning of a project.
Product overview
IBM Informix Server provides high performance and scalability with legendary reliability and
nearly hands-free administration of databases of all size. IDS is industry proven on UNIX, Linux,
or Windows platforms with online transaction processing (OLTP) systems, data marts, data
warehouses, and e-business applications.
The IDS 11 release features significant additions over prior versions. It supports the servicesoriented architecture (SOA) model for application integration and offers many new features for
data replication, continuous availability and “hands free” database administration.
Organization
This document is broken into sections to logically discuss the different database concepts. Some
of the sections may contain the same sub-sections; for example, stored procedures and triggers
Version 1.6
8
IBM Software Group
IBM Information Management
are discussed in the DDL and DML sections. This allows separate discussions on the issues
facing the same item in each area. For example, the issues surrounding creating a stored
procedure are discussed in the DDL section, and the issues surrounding the stored procedure
language are discussed in the DML section.
Among the other references, the “Planning Guide” appendix contains a quick reference of most of
the differences between Oracle and Informix along with the degree of difficulty to port each
difference. This reference is intended for use in the planning process to illustrate the scope and
the effort required to perform the porting project. Some of the stored procedure logic used to
convert Oracle functions is included in the appendix ”Sample code”.
Conventions
The conventions used in this document include:
Courier Text
Distinguishes a logic example
from regular text.
Example
Illustrates a point. In most cases an Oracle example will be
followed by an Informix example.
Italicized Text
Signifies a substitution; in other words, substitutes for the
italicized word, the actual object the word is describing, for
example: table_name, column_name, and so on.
UPPER CASE TEXT
Signifies database vendor reserved words or statements such as
INTEGER, CREATE TABLE, and so on
Bold example text
highlights the item that is being explained.
Version 1.6
9
IBM Software Group
Version 1.6
IBM Information Management
10
IBM Software Group
CHAPTER 2:
IBM Information Management
Defining the Problem
Space
It is important to define the set of objects to be migrated, and it is better if effort is put into this
prior to beginning the actual migration. This is true if you are the responsible for both the database
in general and its migration from one supporting DBMS to another, but it is particularly true that
there be a clear agreement on the scope of what is to be migrated if the migration is to be
performed by a party other than the one with long term responsibility for the database. Defining
the scope will involve extracting a representation of the objects to be migrated out of the Oracle
system catalogs and representing them in some format that can be manipulated into constructs
that can be used in Informix.
Extracting the objects to be migrated
It is possible to represent the objects in more than one language. Using the SQL language is the
most common method, and it will be the only one discussed at length in this document (in its
current revision). However, it is also possible to express database objects in XML, SQL has the
advantage that the standard, common grammars are widely understood in the context of defining
tables, indexes, etc. XML would have an advantage of not requiring parsing that is sensitive to the
minor differences in ways of expressing essentially the same object.
Working With Oracle Dump Files
rd
There exist 3 -party tools for reading system catalogs, but it is doubtful that any can read the
Oracle catalogs more reliably than Oracle’s own tools. There are two, incompatible, export and
import tool sets used by Oracle. The older tools are imp and exp and the newer ones are impdp
and expdp, where '..dp' stands for Data Pump. Oracle has encouraged the use of the newer tools
instead of the older ones since the newer ones were introduced at version 10. Nonetheless, there
are many Oracle users still using imp and exp.
In the discussions below, only the metadata will be extracted into a dump file. That is because any
data in the dump file will be in a proprietary format, and very likely some of the data will have to go
through a type conversion process before being loaded into an Informix system. Oracle exported
data generally cannot be used to load a database in Informix.
Export and Import
If someone has given you a dump file created with the older export tool, there exist tools such as
The DDL Wizard, by Net 2000 Limited, which can be used to extract viable DDL. The contents of
the dump file contain the SQL for re-creating the database, but they are not in a readily usable
format. The older export and import tools are also more sensitive to the layout of the tablespaces
than impdb. The ability to extract DDL from the dump file in a usable form, segmented by
whatever grouping you choose, is limited compared to what can be achieved through the Data
Pump versions..
Version 1.6
11
IBM Software Group
IBM Information Management
It may be tempting to feed the dump file into the IBM Migration Toolkit (MTK) or other tool that
works on SQL flat files. This will not work. MTK works on flat text SQL files, and the dump file is
binary. If you open it up, you can see what may be a large number of SQL statements, but there
are also binary codes within the same file. That binary data will prevent MTK from being able to
process it.
Getting SQL statements
If you want to get the SQL statements out of the dump file, as they would be executed on the
server, there is an option available from the import tool itself, 'show=y'.
imp 'myID/myPWD as sysdba' file=myFile.dmp
full=yes show=y > dmp_show.txt
This will produce a file which contains the statements, but they are wrapped in quotes. The
contents will look something like:
"ALTER SESSION SET CURRENT_SCHEMA= "SYSTEM""
"CREATE UNDO TABLESPACE "TBSPC1" BLOCKSIZE 8192 DATAFILE 'D:\ORACLE\ORADA"
"TA\SCHEMA1\CHUNK.DBF' SIZE 387973120
AUTOEXTEND ON NEXT 5242880 MAXS"
"IZE 32767M EXTENT MANAGEMENT LOCAL "
which makes them strings instead of SQL statements. Fixing this is a two-step process
-- removes quotes from the start of lines
sed 's/^ "//g' dmp_show.txt > step1.txt
-- removes quotes from the end of lines
sed 's/"$//g' step1.txt > dmp_step2.sql
The statements are still not correctly formatted because they have been truncated to a fixed
length and line-endings inserted. However, at this point it is possible to get a count of how many of
each object type there is using the script in the appendix “Getting an initial count of database
objects”.
Data Pump Export and Import
These newer tools provide better performance and more capabilities than their predecessors.
Please refer to documentation on Oracle for a complete description; searches for “Data Pump
Import” and “Data Pump Export” should return relevant results quickly. Below is enough
information to get started on defining and extracting the objects to be migrated.
Metadata can be filtered through the use of the export mode clause, and INCLUDE and
EXCLUDE parameters. However, any dependent object of an included or excluded object is
likewise included or excluded. For example, if you include an index, then the table associated with
the index will also be included, and if you exclude a table, then any associated indexes will also be
excluded.
The SQL that will generate all the objects in the dump file can be created by the impdp command
with the SQLFILE parameter. If the output file is very large, you might want to break it into smaller
pieces. There are a couple of ways to do this, and the one that is best for you somewhat depends
Version 1.6
12
IBM Software Group
IBM Information Management
on how you intend to proceed with the conversion. Data definition language (DDL) SQL for all the
objects can be put into one file, or the INCLUDE or EXCLUDE parameters can be added to direct
Data Pump to filter on the types of objects. If you put all the objects into one file, then you can
break that into smaller files by object type fairly easily because the objects are sorted by type in
the SQL file. So, it is just a matter of cutting the file into smaller pieces. This method may be
preferred because it allows for you to do things like, create all tables, load the data, and then
create the indexes and triggers. If the data set is large, creating the indexes after loading the data
can yield substantial performance improvements. However, this is less useful if you want to
convert sets of objects according to dependencies; in which case the filtering option is likely to be
more useful.
Just to illustrate a difference between these two methods, in one customer case, the metadata
dump file was about 18MB, and putting all objects in one SQL file resulted in a file that was about
15MB. The table definitions occupied a little under 300KB of the 15MB. The output file generated
by filtering on objects of type TABLE was just over 1MB. The addition content was mostly GRANT,
INDEX, and TRIGGER creation statements. There were no differences in the CREATE TABLE
statements themselves.
Examples
Prerequisite
The Data Pump tools require the use of an Oracle DIRECTORY object. This is basically a
mapping between a name that exists within the DBMS and a system path. It can be a tripping
point, but it provides an abstraction layer that, for instance, allows the same commands to work
across systems with different disk layouts or different operating systems.
Creating a DIRECTORY on a Windows system from SQLPlus:
SQL>connect / as sysdba;
SQL>CREATE OR REPLACE DIRECTORY dumpDir AS 'c:\temp';
Note: Make sure this directory is not read-only. There also could be problems if the directory is a
network drive on Windows; these can be related to there being different users between the Oracle
executable and the current user, and those users having different permissions on the network
drive.
SQL>GRANT read, write ON DIRECTORY dumpDir TO userID;
Creating a dump file of the entire database:
expdp 'userName/userPwd as sysdba' FULL=Y dumpfile=DB_full.dmp
LOGFILE=LG_expdp.log CONTENT=METADATA_ONLY DIRECTORY=dumpDir
Creating a dump file of just one schema:
expdp 'userName/userPwd as sysdba' SCHEMAS=hr DIRECTORY=dumpDir
DUMPFILE=hr .dmp LOGFILE=hr .log CONTENT=METADATA_ONLY
Creating a dump of just the tables and their dependents:
expdp 'userName/userPwd as sysdba' SCHEMAS=hr INCLUDE=TABLE
DIRECTORY=dumpDir DUMPFILE=hr.dmp LOGFILE=hr.log
CONTENT=METADATA_ONLY
Creating a dump of just one table:
expdp 'userName/userPwd as sysdba' SCHEMAS=hr
INCLUDE=TABLE:\"LIKE \'COUNTRIES\'\" DIRECTORY=dumpDir
DUMPFILE=hr.dmp LOGFILE=hr.log CONTENT=METADATA_ONLY
Version 1.6
13
IBM Software Group
IBM Information Management
Creatinge an SQL file from a dump file:
impdp 'userName/userPwd as sysdba' DIRECTORY=dumpDir
DUMPFILE=hr.dmp SQLFILE=dumpDir:hr.sql
The INCLUDE and EXCLUDE options are also valid when used with impdb; so, it may be easier
to get a complete dump of everything to be migrated, then use these options to create
subsets of objects it smaller SQL files, than it would be to create separate dump files. It is
easier to divide objects than to merge them together if they are not divided initially as
wanted.
There is a caveat when using this impdp to generate an SQL file; the object names will all be
delimited identifiers. Example:
CREATE TABLE "HR"."COUNTRIES"...
Because of differences between how Informix handles these and how Oracle handles these,
case-sensitivity issues could occur. See the chapter on “Delimited Identifiers”, and, in particular,
the description of default shift problems. If it can be determined that there are no name collisions
if regular identifiers are used, removing the quotation marks as part of the conversion might avoid
many problems. In other words, if there are no objects whose names only differ in case, like foo
and FOO, then changing every occurrence of “FOO” to FOO in the DDL could eliminate casesensitivity issues in the application DML. It depends on if the application code uses the delimited
form of the name predominantly or not.
Version 1.6
14
IBM Software Group
IBM Information Management
Data Definition
Language
CHAPTER 3:
Identifiers
An identifier specifies the simple name of a database object such as a table name, column name,
index name, view name, stored procedure name, and so on. The maximum length of an Oracle
identifier is 30 characters and can contain letters, numbers, “_”, “$”, and “#”, although Oracle
highly recommends that “$” and “#” should not be used. In contrast, Informix identifiers have a
maximum length of 128 characters and may contain letters, numbers, “_” and “$” (as long as “$” is
not the first character). See the Delimited Identifiers section below for information.
This means that all Oracle identifiers containing a “#” anywhere in the identifier or a “$” as
the first character must be replaced or modified to remove those characters from the
identifier.
Delimited identifiers
Delimited identifiers are also known as quoted identifiers and sometimes as escaped identifiers.
They have been part of the SQL standard since SQL/92, but existed in various database
management systems (DBMS) prior to that time. In a nutshell, they are a way to preserve case
sensitivity in object names as well as to allow objects to have names outside of the conventions of
SQL regular identifiers. Prior to the behavior of identifiers in general being standardized, different
DBMS vendors implemented different means of achieving case-insensitivity for object names;
some converted all regular identifiers to uppercase, and some converted regular identifiers to
lowercase. By SQL/99 the concept of case normal form was standardized to mean, simply stated,
that if there exists an uppercase equivalent of any character in a name, then the uppercase
version is stored in the system catalogs and used for comparison purposes. See the SQL/99
standard, chapter 5, section 2, and in particular, items 21 and 22, for a formal description of case
normal form and how it applies to identifier comparisons.
Delimited identifiers can be used to specify names for database objects that are otherwise
identical to SQL reserved keywords, such as TABLE, WHERE, DECLARE, and so on. The only
database object for which delimited identifiers cannot be used is a database name.
Database administrators and application programmers do not always communicate to each other
with 100% efficiency, and there is no guarantee that within either of these pools, every member
codes by the standard practice of the other members. After describing how delimited identifiers
work in Informix, there will be a description of how any inconsistency of usage and the differences
between Oracle and Informix can introduce some migration hurdles.
DELIMIDENT Environment Variable
To use delimited identifiers with Informix, you must set the DELIMIDENT environment variable.
While DELIMIDENT is set , strings enclosed in quotation marks ( “ ) are treated as identifiers of
database objects, and strings enclosed in apostrophes ( ’ ) are treated as literal strings. If the
Version 1.6
15
IBM Software Group
IBM Information Management
DELIMIDENT environment variable is not set, strings enclosed in quotation marks are also
treated as literal strings.
When you set the DELIMIDENT environment variable, you cannot use quotation marks ( ” ) to
delimit literal strings. If DELIMIDENT is set, the database server interprets all strings enclosed in
quotation marks as SQL identifiers, not string literals. Commonly within Informix systems,
DELIMIDENT is set or not on the client side, according to the design of the application. However,
if you are converting a database and all applications accessing it from a system where every
occurrence of quotation marks (“objectName”) indicates an identifier and not a string literal, you
may want to consider setting it in the server environment in order to avoid any inconsistency
between clients where it is set and where it might not be.
Using Quotes in Strings The apostrophe ( ’ ) has no special significance in string literals
delimited by quotation marks. Conversely, double quote ( ″ ) has no special significance in strings
delimited by apostrophes. For example, these strings are valid: "Nancy’s puppy jumped the fence"
’Billy told his kitten, "No!" ’ A string delimited by quotation marks can include a double quote
character by preceding it with another double quote, as the following string shows: "Enter ""y"" to
select this row." When the DELIMIDENT environment variable is set, quotation marks can only
delimit identifiers, not strings.
Use of Uppercase Characters You can specify the name of a database object with uppercase
characters, but the Informix server shifts these to lowercase characters unless the DELIMIDENT
environment variable is set and the name of the database object is enclosed in quotation marks.
In this case, the database server treats the name of the database object as a delimited identifier
and preserves the uppercase characters in the name.
Delimited Identifiers By default, the character set of a valid SQL identifier is restricted to letters,
digits, underscore, and dollar-sign symbols. If you set the DELIMIDENT environment variable,
however, SQL identifiers can also include additional characters from the codeset implied by the
setting of the DB_LOCALE environment variable. See the Identifier section of the Informix Guide
to SQL: Syntax for more information.
Storage Object Names In Informix, delimited identifiers can be used to specify nonalphanumeric characters in the names of database objects. However, delimited identifiers can not
be used to specify non-alpha characters in the names of storage objects such as dbspaces and
blobspaces.
To use delimited identifiers, DELIMIDENT must be set both at compile and run times. For
example, to set DELIMIDENT environment variable with sh or ksh, issue the following at the
command line prompt:
export DELIMIDENT=
Note: You do not need to assign a value to the environment variable, and counter-intuitively,
setting DELIMIDENT=n has the same effect as DELIMIDENT=y. Also, in a Windows environment:
set DELIMIDENT=
effectively undefines the variable.
Default shift problems
Any direct access of system catalog information involving names will cause problems when
migrating from a system, like Oracle, where system catalog names are stored in uppercase to a
system, like Informix, where the catalog names are stored in lowercase. For example:
CREATE TABLE foo (c1 int);
Version 1.6
16
IBM Software Group
IBM Information Management
Within Oracle, the following will return information about the table:
select * from sys.all_objects where object_name = 'FOO';
and the following will not:
select * from sys.all_objects where object_name = 'foo';
Conversely, in Informix:
select * from systables where tabname = 'foo';
will be successful, and the same with 'FOO' will not be.
A similar, if not more common, problem can occur when the table has been created without the
name being delimited, but is sometimes delimited when accessed by the application. Per the
standard, foo == FOO == “FOO”, but in Informix, foo == FOO == “foo”. In Oracle, the following
SELECT statement will be successful:
SELECT * FROM “FOO”;
but within Informix, this will result in an error, “206: The specified table (FOO) is not in the
database.”
Likewise, if the name is delimited in its definition, such as
CREATE TABLE "SCHEMA1"."TABLE1"...
this creates a table that can be referenced in Oracle without the name being delimited. The
statements
SELECT * FROM schema1.table1;
and
SELECT * FROM SCHEMA1.TABLE1;
will be successful in the Oracle system, but will fail in the Informix one.
In theory, whether on object name is delimited or not should be the same in the database and at
every occurrence within the application, but this is not always the case. It may be beneficial to
examine whether delimited identifiers or regular identifiers are most commonly used in application
code, and use whichever is most common as a naming convention when translating the DDL.
Explicit versus implicit schema/owner names
Another complication to keep in mind is that when the log mode is ANSI, implicit and explicit
owner names are treated differently between the Oracle and Informix servers. In Oracle, there is
no difference in the case handling of an implicit owner name and an explicit one. For example, if
connected to Oracle as scott the following CREATE TABLE statements
create table foo1(c1 int);
create table scott.foo2(c1 int);
create table SCOTT.foo3(c1 int);
all result in tables owned by SCOTT. The following select statements, in various forms that may
be in application code, will all run without error.
select * from foo1;
select * from scott.foo1;
Version 1.6
17
IBM Software Group
IBM Information Management
select * from SCOTT.foo1;
select * from foo2;
select * from scott.foo2;
select * from SCOTT.foo2;
select * from foo3;
select * from scott.foo3;
select * from SCOTT.foo3;
These statements will also run without error within a non-ANSI mode Informix database, but not
all of them will run successfully within an ANSI mode database. This is because Informix does not
uniformly fold the case of owner names, and handles implicit names differently from explicit
names; so, there will always be some combination of DDL and DML usage patterns that work
within an Oracle system that do not work in an Informix one. You can set ANSIOWNER before
starting your Informix server, but that will merely change which combinations do not work. You
may want to examine usage patterns within the applications and choose a naming convention
when translating the DDL that matches the most common naming convention used in the
applications.
Note: This behavior of Informix forces a tradeoff between using an ANSI mode database, which
most closely matches the transaction behavior of Oracle, and a non-ANSI mode database, which
has the least mismatch in identifier case sensitivity.
Reserved words or keywords
Oracle and Informix both allow identifiers to be reserved words as long as they are delimited.
However, Oracle and Informix reserved words differ. In addition, both systems have keywords,
like FROM, that are not always reserved in the sense that using them as an identifier will always
generate a syntax error. There should be few problems with reserved words or keywords if
identifiers that are delimited in the original database remain delimited in the destination database.
The appendix Keywords of SQL for IBM Informix in the Guide to SQL: Syntax contains more
information about Informix keywords. Also, one word, non-delimited identifiers should be verified
against the Informix reserved words list to ensure that they do not need to be delimited or
renamed.
Although almost any word can be used as an identifier in Informix, syntactic ambiguities can result
from using reserved words as identifiers in SQL statements. Delimited identifiers provide a way to
use a reserved word as an identifier without causing syntactic ambiguities. However, doing this
changes a case-insensitive name into a case-sensitive one, and that means that every reference
to the object has to be checked for issues related to case-sensitivity. Essentially, this is not much
less work than changing the name of the object because, in essence, it is changing the name of
the object.
Examples
The following example shows how to create an Informix table with a case sensitive table name:
CREATE TABLE "My_Customers" (…)
The following example shows how to create a table whose name includes a space character. If
the table name were not in quotation marks ("), a space character or any other non-alpha
character, except an underscore ( _ ) or dollar sign ($) (see special conditions above), could be
used in the name.
CREATE TABLE "My
Version 1.6
Customers" (…)
18
IBM Software Group
IBM Information Management
The following example shows how to create a table that uses a keyword as the table name:
CREATE TABLE "TABLE" (…)
To include a double-quote (") within a delimited identifier, the double-quote (") must be preceded
with another double-quote ("), as shown in the following example:
CREATE TABLE "My""Good""Data" (…)
Summary
The main points to keep in mind when deciding about any questions on how identifiers should be
translated are:



Oracle always has delimited identifiers enabled, and Informix does not.
Oracle folds regular identifiers to uppercase, and Informix folds to lowercase.
Informix has behavioral differences between an ANSI mode database and a non-ANSI
mode one.
It is beneficial to consider the most common usage patterns within the existing application code
prior to deciding default identifier translation patterns.
Databases
Databases, database names and instances
Oracle and Informix implement databases and instances differently. Oracle considers a database
to be a set of data files, control file(s) and log files, while an instance is a set of background
processes and memory structures accessing database data. Oracle instances are also known as
servers. Each Oracle instance or server runs against one database, but through the use of Oracle
Parallel Server, a database may have multiple instances accessing it. An Oracle database is
named at initialization and the name has a limit of 8 ASCII characters.
Informix databases are defined as “a collection of information contained in tables that are useful to
a particular organization or used for a specific purpose”. Informix database names may be up to
128 characters in length. An Informix instance is a set of processes, memory and disk allocations
that manage data and will contain at least two and in most cases many databases. Informix
instances are also referred to as servers. Informix databases may share disk allocations
(dbspaces) with other databases within an Informix instance. Oracle databases cannot share disk
allocations (tablespaces).
Informix databases should be created in a dbspace other than the root dbspace. The root
dbspace holds data for the system, configuration information for the engine, and so on. If userdefined objects are created in this dbspace, then the dbspace may become unmanageably large,
and during backup, the system information may also get backed up unnecessarily.
The CREATE DATABASE statements of Informix and Oracle have differences which may require
modification to routines responsible for database creation. Informix will accept the same minimal
syntax required by Oracle (e.g. CREATE DATABASE myDB) however issuing the command will
implicitly accept the creation of a database without transaction logging enabled and establish the
default location for all database objects as the instance’s default storage location. The instance’s
default storage location, or “root” dbspace, should not contain user-defined objects. The root
dbspace holds data for the system and some configuration information for the engine. If user-
Version 1.6
19
IBM Software Group
IBM Information Management
defined objects are created in this dbspace it may become unmanageable and result in the
system contending with user objects for the available space.
ANSI vs. non-ANSI
Informix supports both ANSI and non-ANSI databases. Informix non-ANSI databases are most
common, but there are some advantages of ANSI databases when porting from Oracle:



Oracle’s transaction behavior is more or less like that of an ANSI database. Applications
ported on Oracle are always in a transaction. In Oracle and ANSI databases, transactions
begin implicitly with the first of a series of SQL statements and will end immediately after
a commit or rollback statement. Therefore, unlike a non-ANSI database, a COMMIT
WORK statement does not need to be preceded with a BEGIN WORK statement.
In ANSI databases, database object references must be prefixed by the owner’s name,
unless the owner is the one referencing the object. If Oracle applications reference
database objects with a both parts of the object name, prefixing the object name with
schema, using an ANSI database may ease modifications necessary when porting to
Informix.
The “‘grant to PUBLIC”’ concept provide by Informix database security does not apply to
ANSI databases. Every database object is private and privileges must be explicitly
granted to each user.
If an Informix ESQL/C or 4GL application was developed to run on a non-ANSI Informix database
(including BEGIN WORK statements), the application could run on an ANSI Informix database in
one of two ways:


By placing the BEGIN WORK statement in a pre-processor directive, such as IFDEF
object_name, and omitting the proper preprocessor compile options, such as -D
object_name
By compiling the application normally and ignoring the resulting warning messages
Additionally, the LOG MODE ANSI clause must be added to the CREATE DATABASE
statements. ANSI mode databases cannot have buffered logging.
Applications written to use an open API, like ODBC or JDBC, are compiled without awareness of
the database and these APIs are written with the intent to abstract specific database behavior. For
instance, in one of these, the application developer would call a function to begin or end a
transaction rather than execute a BEGIN and COMMIT or ROLLBACK. The API would execute
these statements internally, or not, as necessary for the database connection.
See the Transaction Processing section in Application Architecture for more information on how
an application running on a non-ANSI Informix database can simulate Oracle transaction
behavior.
Tablespaces and dbspaces
Oracle tablespace names need to be replaced with Informix dbspace names. Unlike the Oracle
tablespace, the Informix dbspace cannot be created using DDL (SQL) scripts. It must be created
using the Informix onspaces utility before any DDL (SQL) scripts are executed. Therefore,
Oracle’s CREATE TABLESPACE statements should be removed from the DDL (SQL) scripts.
The user interface for accomplishing these tasks is onmonitor. The command line utility is
onspaces. Therefore, the onspaces commands can be placed in shell or batch scripts. After
successfully executing the onspaces commands, the DDL (SQL) scripts may be called through
the same shell or batch scripts. For example:
Version 1.6
20
IBM Software Group
IBM Information Management
onspaces …
onspaces …
…
dbaccess database_name DDL_script_file_name
dbaccess database_name DDL_script_file_name
…
Tables
Attributes and general syntax
When creating tables, the Oracle CREATE TABLE statement must be converted to Informix,
taking advantage of the Informix options IN, EXTENT, NEXT, and LOCK MODE.
 IN specifies the dbspace in which the table will reside.
 EXTENT specifies the amount of space that will initially be allocated to the table (16K default
on most platforms).
 NEXT specifies the amount of space that will be allocated when additional space is needed
(16K default on most platforms.
Lock mode
LOCK MODE specifies whether to use row or page locks for the table. In Oracle, the default is
row level locking; in Informix the default setting is page level locking. However it can be
changed by using one of the following methods: (resolved in the following order of precedence)
1. LOCK MODE specified using an attribute of the CREATE TABLE or ALTER TABLE
command syntax
2. IFX_DEF_TABLE_LOCKMODE environment variable setting
3. DEF_TABLE_LOCKMODE parameter setting in the ONCONFIG file
NOTE: If the DEF_TABLE_LOCKMODE parameter cannot be found in the ONCONFIG file it can
be added to make the specification for every database within the instance. The Informix instance
must be restarted for this parameter to take effect. The new “default” LOCK MODE will apply to all
tables created after the parameter has been changed. To change the LOCK MODE of existing
objects use the ALTER TABLE statement.
Storage
The Oracle STORAGE INITIAL and STORAGE NEXT clauses must be changed to the Informix
EXTENT SIZE and NEXT SIZE clauses, respectively. In Oracle the STORAGE clause options
MINEXTENTS, MAXEXTENTS and PCTINCREASE should be removed. For example:
Oracle:
CREATE TABLE dept(
deptno
NUMBER(2),
dname
VARCHAR2(14),
loc
VARCHAR2(13)
)
STORAGE (INITIAL 100K NEXT 50K MINEXTENTS 1 MAXEXTENTS 50
PCTINCREASE 5);
Informix:
CREATE TABLE dept (
deptno
SMALLINT,
dname
VARCHAR(14),
loc
VARCHAR(13)
);
Version 1.6
21
IBM Software Group
IBM Information Management
EXTENT SIZE 200 NEXT SIZE 50;
When an Oracle CREATE TABLE statement does not include a STORAGE clause, the table will
be created using the tablespace STORAGE clause by default. If an Oracle tablespace is created
specifying a STORAGE INITIAL of 100KB and a STORAGE NEXT of 50KB, then all tables
created within that tablespace will have a default value of STORAGE INITIAL 100KB and
STORAGE NEXT 50KB. Oracle tables cannot be created with smaller STORAGE clause values
than the tablespace default they are created in.
Informix dbspaces do not have storage clauses attached to them. As stated earlier, the default
Informix EXTENT and NEXT sizes are 16KB on most platforms. The minimum EXTENT and
NEXT sizes are 4 times the page size.
Constraints
The Oracle constraint syntax must be changed to the Informix syntax for primary keys, foreign
keys, unique, and so on. For example:
Oracle:
CONSTRAINT PK_NUMBER PRIMARY KEY(CUST_NUM)
CONSTRAINT CK_EMP_CODE CHECK (EMP_CODE > 100)
Informix:
PRIMARY KEY(CUST_NUM) CONSTRAINT PK_NUMBER
CHECK (EMP_CODE > 100) CONSTRAINT CK_EMP_CODE
An Oracle check constraint statement may contain functions that are not available in Informix. In
this circumstance it may be necessary to code the combination of a trigger and a stored
procedure to emulate the same functionality. A trigger based on an insert or update event can
execute a stored procedure which tests the constraint condition and if necessary raise an
exception to reject the row data which violates the constraint.
The Oracle PARALLEL clause, which specifies parallel execution of an operation, must be
removed from any SQL statements (such as CREATE TABLE and ALTER TABLE). In Informix
there are ways to accomplish this parallel execution depending on the context in which these SQL
statements are called (shell script file, batch file, and so on.).
ALTER TABLE
Informix offers a rich set of ALTER TABLE features: adding and dropping columns (rename by
using the RENAME statement), changing column data types, altering the next size, and changing
the lock mode. Informix will choose one of three algorithms when executing an ALTER TABLE
statement depending upon the operation to be performed. For certain conditions, the database
server uses either a “slow”, “in-place" or “fast” alter algorithm to modify the table.
Informix provides “in-place” alter table support for adding or dropping a column anywhere in the
table, changing the column length, and changing the column data type without an exclusive lock
on the table. An “in-place” alter will modify the table’s definition without changing the existing rows
or unloading and reloading the data. After the ALTER TABLE operation, the database server
inserts rows using the latest definition. Informix will not change the row structure until a data row is
touched by a user operation. Once a query accesses a row that is not yet converted, there can be
a slight degradation in the performance because the database server reformats each row in
memory before it is returned.
Informix uses the “slow” alter algorithm when the ALTER TABLE statement makes column
changes that it cannot perform in place. This type of alter would be:


Adding or drop a column created with the ROWIDS keyword
Dropping a column of the TEXT or BYTE data type
Version 1.6
22
IBM Software Group


IBM Information Management
Converting an INT or a SMALLINT column to SERIAL or SERIAL8
Modifying the data type of a column so that some possible values of the old data type
cannot be converted to the new data type
For example, if you modify a column of data type INTEGER to CHAR(n), the
database server uses the slow ALTER algorithm if the value of n is less than 11. An
INTEGER requires 10 characters plus one for the minus sign for the lowest possible
negative values.


Modifying the data type of a fragmentation column in a way that value conversion
might cause rows to move to another fragment
Adding, dropping or modifying any column when the table contains user-defined data
types or smart large objects
When the database server uses the slow alter algorithm to process an ALTER TABLE statement,
the table can be unavailable to other users for a long period of time because the database server
will lock the table exclusively for the duration of the operation, make a copy of the table to convert
the table to the new definition and convert the data rows. This type of ALTER TABLE processing
can encounter the scenario of a statement being a long transaction and abort it if the Long
Transaction High Water Mark (LTXHWM) threshold is exceeded.
Informix will use the “fast” alter algorithm when the ALTER TABLE statement changes attributes
of the table but does not affect the data. The database server uses the fast alter algorithm when
you use the ALTER TABLE statement to make the following changes:
•
Change the next-extent size
•
Add or drop a constraint
•
Change the lock mode of the table
•
Change the unique index attribute without modifying the column type
With the “fast” alter algorithm, the database server holds a lock on the table for a very brief period.
In some cases, the database server will lock the system catalog tables but only long enough to
change the attribute. In either case, the table is unavailable for queries for only a short time.
Data Partitioning
Informix Table Fragmentation is the counterpart to Oracle’s Table Partitioning and allows the user
to control where data is physically placed at the table level. Table Fragmentation or Data
Partitioning is typically done to large tables, but Informix and Oracle implement fragmentation and
partitioning for different reasons and with different results. Informix recommends using table
fragmentation to improve single-user response time, concurrency, data availability, backup /
restore characteristics, and data-load performance. While Oracle does state that table partitioning
may improve the performance of queries, and that the Oracle optimizer takes partitioning into
account, the primary goal of partitioning in Oracle is improving database maintenance.
Partitioning strategies in Oracle include range partitioning as well as hash and composite
partitioning. Composite partitioning combines range and hash partitions through the use of subpartitions. Tables incorporating Oracle LOB’s (large objects) cannot be partitioned.
Informix fragmentation strategies include expression-based and round robin. Basic expressionbased fragmentation can replace Oracle range partitioning. Unlike Oracle LOBs, Informix’s Smart
Large Objects can be fragmented. Examples of creating tables with Oracle range partitioning and
Informix fragmentation by expression are shown below:
Oracle range partitioning:
CREATE TABLE dept
Version 1.6
23
IBM Software Group
IBM Information Management
(
deptno
NUMBER(2),
dname
VARCHAR2(14),
loc
VARCHAR2(13) )
partition by range (deptno)
(partition PART1 values less than
tablespace PART1_TS,
partition PART2 values less than
tablespace PART2_TS,
partition PART3 values less than
tablespace PART3_TS,
partition PART4 values less than
tablespace PART4_TS);
(11)
(21)
(31)
(MAXVALUE)
Informix expression based fragmentation:
CREATE TABLE dept(
deptno
SMALLINT,
dname
VARCHAR(14),
loc
VARCHAR(13)
)
FRAGMENT BY EXPRESSION
deptno < 11 IN dbspace1,
deptno >= 11 AND deptno < 21 IN dbspace2,
deptno >= 21 AND deptno < 31 IN dbspace3,
REMAINDER IN dbspace4;
Oracle uses MAXVALUE for values not found in the specified range while Informix uses the
REMAINDER keyword for values that fall outside the specified expression or expressions.
Prior to IDS version 10.00, each table fragment had to go into a separate dbspace. Now tables
can be fragmented within a single dbspace. You can create partitions within a dbspace that can
each support a table fragment. It is better to have one chunk per disk drive, and now it is not
necessary to create a dbspace just to facilitate fragmentation.
This feature can simplify the management of dbspaces. The benefits gained through this new
development include:


It reduces the total number of dbspaces needed for a fragmented table.
Storing multiple table fragments in a single dbspace improves query performance over
storing each fragmented expression in a different dbspace.
For example, Informix partition fragmention in a single dbspace:
CREATE TABLE dept(
deptno
SMALLINT,
dname
VARCHAR(14),
loc VARCHAR(13)
)
FRAGMENT BY EXPRESSION
PARTITION part1
PARTITION part2
PARTITION part3
PARTITION part4
(deptno <
(deptno <
(deptno <
REMAINDER
11) IN dbspace1,
21) IN dbspace1,
31) IN dbspace1,
IN dbspace1;
Partitions of an Informix fragmented table can be manipulated using the ALTER FRAGMENT
statement which supports attaching, detaching, adding, modifying, and dropping, as well as
initializing the distribution strategy.
Version 1.6
24
IBM Software Group
IBM Information Management
For example, the following SQL removes a partition fragment and places the contents into a new
table:
ALTER FRAGMENT ON TABLE dept DETACH PARTITION part3 dept_part3;
Making use of ALTER FRAGMENT to detach fragments can be an effective way of deleting large
quantities of rows from a table, quickly and easily. After the above statement completes, the table
will no longer contain rows with a deptno greater than 21 and less than 31.
Refer to the Informix Guide to SQL: Syntax for a complete description on how to use the ALTER
FRAGMENT statement to change the distribution strategy or the storage location of an existing
table or index.
Data types
Numeric
Oracle’s NUMBER data type needs to be replaced with one of the following Informix equivalent
data types, depending on the size of the column. The Informix numeric data types are listed
below.
 SMALLINT (-32,767 to 32,767)
 INTEGER (-2,147,483,647 to 2,147,483,647)
 BIGINT (-9,223,372,036,854,775,807 to 9,223,372,036,854,775,807)
 INT8 (-9,223,372,036,854,775,807 to 9,223,372,036,854,775,807)
The BIGINT type is more efficient in terms of space and speed; there are few reasons to
use INT8 now that BIGINT is available.

-130
DECIMAL (floating point up to 32 significant digits -10
124
to 10
)
In an ANSI database, there is an implied scale of 0 when no scale is given; so, this is not
strictly speaking a floating point type within an ANSI database.






-130
124
NUMERIC (floating point up to 32 significant digits -10
to 10
FLOAT (double precision, like double data type of C)
SMALLFLOAT (single precision, like float data type of C)
REAL (same as SMALLFLOAT)
DOUBLE (same as FLOAT)
LONG (same as long data type of C)
)
Oracle’s NUMBER data type is used to store zero, positive and negative fixed size, and floating
-130
125
point numbers with magnitudes between 1.0 x 10
and 9.9...9 x 10 (38 9s followed by 88 0s)
with 38 digits of precision. A fixed-point number is specified by NUMBER(p, s) where p is the
precision, or the total number of digits, and s is the scale, or the number of digits to the right of the
decimal point. For example, a column defined as NUMBER(10,4) would contain numbers in the
format 999999.9999.
In Oracle, the scale can range from -84 to 127. If the scale is 0, or not mentioned, then the data
type can be converted into Informix’s SMALLINT, INTEGER, or BIGINT depending on the
precision, or FLOAT, SMALLFLOAT, DOUBLE or REAL, depending on usage in the application.
When the scale is positive, the data type should be converted to Informix’s DECIMAL or
NUMERIC. A floating-point data type in Oracle is declared using the type NUMBER without
mentioning scale and precision. In Informix this can be replaced with FLOAT, SMALLFLOAT,
REAL, DOUBLE PRECISION, or DECIMAL(p) in an non-ANSI database.
Version 1.6
25
IBM Software Group
IBM Information Management
Oracle allows a negative scale. If the scale is negative, the actual data is rounded to the specified
number of places to the left of the decimal point. For example, a specification of NUMBER (10, -2)
means to round to the hundred. If the general form for any number is:
exponent
mantissa X 10
then precision is the number of digits in the mantissa, and scale is the negative exponent.
Example:
select cast( '987654321' AS NUMBER(10,-2) ) from dual;
returns
987654300
Informix does not support a negative scale. If precision - scale is less than the maximum precision
of an integer type, then that is the most efficient type to use. Failing that, and if the database is
non-ANSI, a floating point DECIMAL can be used. If that is not sufficient, then it may be
necessary to define a user type and associated functions.
Oracle also allows the scale to be greater than the precision. Precision is just the number of digits
that will be preserved. A NUMBER(3, 5) might have the value 0.00123. If the Oracle scale is less
than the Informix maximum precision, then the Oracle scale can be used for both the Informix
precision and scale. A NUMERIC(5,5) column could also store the value 0.00123.
You may need to take into consideration not only the minimum and maximum values but the
default size for data types. For example, when the size of the NUMBER data type is absent,
Oracle will default to NUMBER(38), while Informix defaults to NUMERIC(16).
Oracle and Informix support the ANSI DECIMAL data type. Therefore, in the case of an ANSI data
type, the Oracle data type can be converted to the same Informix data type.
There are differences between conversions based on theory versus those based on practice. For
instance, it is very common to see an undecorated NUMBER declaration where the customer
database and applications are using integer data. When converting NUMBER declarations, it may
be necessary to consider how the data is being used in order to determine the best type mapping.
CHAR, VARCHAR and LVARCHAR
In Oracle, the default for a CHAR column is one character, and the maximum allowed is 255
characters. In Informix, the maximum length of CHAR and LVARCHAR columns is 32,767.
Therefore, Oracle’s CHAR columns can always be converted to an Informix CHAR column. The
CHAR data type columns can only contain printable characters, tabs, and spaces. The CHAR
columns store leading and trailing spaces. In Oracle, a zero-length string can be inserted into a
CHAR column, but the column is padded with one blank character when it is used in comparisons.
Also, in Informix, a zero-length string can be inserted into a CHAR column; however, the column
is padded with enough spaces to fill the column. In the case of inserting NULL into an Informix
CHAR column, no padding occurs.
Oracle’s VARCHAR and VARCHAR2 are currently synonymous and have a maximum data length
of 4,000 bytes while the maximum length for the Informix VARCHAR data type is 255. Informix’s
CHAR and LVARCHAR data types have a maximum length of 32,767 and 32,739, respectively,
measured in bytes. These should be used to replace Oracle’s VARCHAR, VARCHAR2, LONG
and LONG VARCHAR if the data length is between 256 and the maximum. If the data length
exceeds the maximum, use Informix’s TEXT, BYTE, BLOB or CLOB data types. See the Raw
Data section below for more information on TEXT, BYTE, BLOB and CLOB data types.
Version 1.6
26
IBM Software Group
IBM Information Management
Empty Oracle VARCHAR2 strings are considered NULL. Empty Informix VARCHAR and
LVARCHAR strings are not considered NULL; rather, they contain at least one space. Oracle
compares VARCHAR2 values using non-padded comparison semantics. Therefore, “BOB” 
“BOB “. Informix ignores trailing blanks. Therefore, “BOB” = “BOB “ or “” = “ ”. Hence, checks
for NULL within the application must be replaced with checks for an empty string (such as “” or “
”) whenever an empty string is inserted into the column. If NULL is truly inserted into the column,
checking for NULL is appropriate (for example, SELECT * FROM … WHERE … IS NULL).
In Oracle, LONG columns store variable length character strings containing up to 2 gigabytes, or
31
2 -1 bytes. Informix LONG columns store numeric data. Oracle’s LONG columns have many of
the characteristics of VARCHAR2 columns. They can be used in a SELECT list, in the SET clause
of an UPDATE statement, and in an INSERT statement, but they cannot be used in a WHERE
clause, a GROUP BY clause, or an ORDER BY clause, and they cannot be indexed. Oracle’s
LONG columns should be converted to an Informix Smart Large Object or “SLOB” (BLOB, CLOB)
column.
Date and Time
Oracle’s DATE data type contains date and time components, from year down to second. It can
be to be replaced most directly with Informix’s DATETIME YEAR TO SECOND. Some analysis
may be necessary to determine whether the time is really necessary. In other words, does the
application reference the date and time portions of the values?
If the application only references the date portion, then replace Oracle’s DATE with Informix’s
DATE and change the host variable to X(10) or char(10), accordingly. The Informix DATE default
display format is MM-DD-YYYY, although the DATE data type stores the calendar date. The
Informix DATE data type requires 4 bytes, which is stored internally as an integer value equal to
the number of days since December 31, 1899. The default display format can be changed with
the environment variable DBDATE. If the application uses different date formats, then using
DBDATE is not a solution. Sometimes it might be necessary to write small subroutines to emulate
Oracle’s DATE representations. See the Informix Guide to SQL, Reference manual for details on
DBDATE and also, DBCENTURY.
If the application only references the time portion of the values, replace Oracle’s DATE with
Informix’s DATETIME using the EXTEND function to specify precision. In addition, Informix
provides the data type INTERVAL for use while performing DATE and DATETIME calculations.
In Oracle, the DATE data type is used to store date and time information. Although date and time
information can be represented in both CHAR and NUMBER data types, the DATE data type has
special associated properties. For each DATE value the following information is stored:
 century
 year
 month
 day
 hour
 minute
 second
Also regarding the Oracle DATE data type, if a date value without a time component is specified,
the default time is 12:00:00a.m. If a DATE value without a date is specified, the default date is the
first day of the current month.
Interval
Within Informix there are two classes of interval types, YEAR-MONTH and DAY-FRACTION.
There are different numbers if days in different months; so, the MONTH-DAY boundary cannot be
crossed without creating ill-defined results. Within each of these classes, Informix allows you to
declare columns or variables as any subset of the start and end fields. Oracle has one INTERVAL
Version 1.6
27
IBM Software Group
IBM Information Management
type for each of the two classes, YEAR(p) TO MONTH and DAY(p) TO SECOND(s). The Oracle
scale on the SECOND field is logically equivalent to the Informix scale on the FRACTION field.
Raw data and Large Objects
Oracle’s support of large blocks of raw, unstructured data (such as graphic images, video clips,
and sound waveforms) in binary or character format is provided by the large object (LOB) data
types BLOB, CLOB, NCLOB, and BFILE. Traditional Oracle data types MLSLABEL (used with
Trusted Oracle), RAW and LONG RAW are also used for data that is not to be interpreted by the
engine and converted when moving data between different systems.
Informix supports two types of large objects (LOBs; Simple Large Objects and Smart Large
31
Objects. Simple LOBs consist of the TEXT and BYTE data types and can be 2 bytes or 2
Gigabytes in size. Smart LOBs include both Character Large Object (CLOB) and Binary Large
40
Object (BLOB) data types and may be up to 4*2 bytes or 4 Terabytes in size. Simple LOBs can
be stored either in-line with table data or in blobspaces while Smart LOB’s are stored in sbspaces.
Oracle’s CLOB, BLOB, MLSLABEL, RAW and LONG RAW data types should be replaced with
Informix’s BYTE, TEXT, CLOB or BLOB, depending on the column’s size and usage.
Informix’s Smart BLOB data types, CLOB and BLOB, should be used under the following
conditions and considerations:
 The large object needs to be referenced by multiple sources.
 The object size exceeds 2 GB.
 Fragmentation is required.
 Byte level locking is available, making it possible to lock only a portion of the object.
 Logging can be specified at the object level.
 Updates are done in place or moved as needed.
Be aware of the following restrictions for Simple Large Objects:
 Data can only be inserted into a BYTE or TEXT column with the dbload or onload utilities,
the DBACCESS load statement, BYTE or TEXT host variables, respectively, in ESQL/C,
or declaring a file in ESQL/COBOL.
 BYTE and TEXT columns cannot be inserted or updated with a literal, neither quoted text
string nor number.
 BYTE or TEXT columns cannot be used in string operations, with aggregate functions,
with the GROUP BY, ORDER BY, IN, LIKE, or MATCHES clauses.
ROWID
The implementation of ROWID differs between Oracle and Informix. Oracle’s ROWID is both a
pseudo-column and a data type. See the ROWID subsection in the Pseudo-Columns section in
CHAPTER 3: Data Manipulation Language for more information. Informix implements ROWID as
a pseudo-column only. Oracle stores the ROWID column and ROWID data type column values in
hexadecimal format. Informix stores the ROWID column values in INTEGER format. The Oracle
and Informix engines maintain the values of the ROWID pseudo-column. Oracle’s engine does
not maintain the values of other columns of type ROWID.
In Informix, the term rowid refers to an integer that defines the physical location of a row. Informix
assigns rows in a non-fragmented table a unique rowid, which allows applications access to a
particular row in a table. Rows in fragmented tables, in contrast, are not assigned a rowid. To
access data by rowid in a fragmented table, a rowid column must be explicitly created as is
described in the Informix Guide to SQL: Reference manual Creating a Rowid Column. If
applications attempt to reference a rowid in a fragmented table that does not contain a rowid that
was explicitly created, Informix displays an appropriate error message and execution of the
application is halted.
Version 1.6
28
IBM Software Group
IBM Information Management
When used as a data type for a column, Oracle does not guarantee that the values are valid
ROWIDs. For example, if the ROWID is used as a data type on a column, such as a column in a
child table named parent_rowid containing the ROWID of the parent, then the values are
maintained by the application, outside of the engine. The application must read the ROWID of the
parent and insert it into the parent’s corresponding child table rows. This is usually done so the
two tables can be joined on the parent’s ROWID and the child’s parent_rowid column. This
functionality can be duplicated in Informix by using primary and foreign keys. Informix
recommends that primary keys are used as a method of access in applications rather than rowids,
because primary keys are defined in the ANSI specification of SQL, using them to access data
makes applications more portable. Refer to the Informix Guide to SQL: Reference and the
Informix Guide to SQL: Syntax for a complete description on how to define and use primary keys
to access data.
User-defined types
Both Oracle and Informix allow the user to create and define data types. Oracle refers to these as
abstract data types while Informix refers to these as user-defined types. In Oracle, all userdefined types are referred to as abstract data types while Informix may refer to user-defined
types as COLLECTION types, ROW types, DISTINCT types and OPAQUE types. Currently, the
Informix ROW type is closest in form and function to the Oracle abstract data type. An example
of syntax for creating both an Oracle abstract data type and an Informix ROW type is shown
below:
Oracle abstract data type:
CREATE TYPE name_type AS OBJECT
(first_name
VARCHAR2(25),
middle_initial
CHAR(1),
last_name
VARCHAR2(30));
Informix row type:
CREATE ROW TYPE name_type
(first_name
VARCHAR(25),
middle_initial
CHAR(1),
last_name
VARCHAR(30));
Both Oracle and Informix support the use of user-defined types for table definition or column
definition within a table. Building on the example above, the following create table example show a
table definition and column definition within a table based on user-defined types:
Oracle table creation:
CREATE TABLE name OF name_type;
Informix table creation:
CREATE TABLE name OF type name_type;
Oracle column definition:
CREATE TABLE employee
(empno
name
NUMBER(9),
name_type);
Informix column definition:
CREATE TABLE employee
Version 1.6
29
IBM Software Group
IBM Information Management
(empno
name
INTEGER,
name_type);
For more information on User Defined Types, see the Informix Guide to SQL: Syntax.
Complex data types
Informix offers users the ability to create data types from existing built-in types, OPAQUE types,
DISTINCT types and other complex types. Complex data types may either be a ROW type or a
COLLECTION type. Oracle treats complex data types as abstract data types. For more
information on Oracle abstract data types see the User Defined Types section above. For more
information on Complex Data Types, see the Informix Guide to SQL: Syntax.
For recommended type mappings and additional information, see the appendix “Data type
mappings”.
Sequence objects
Oracle sequences
An Oracle sequence is a database object from which multiple users, or transactions, may
generate unique integers. For example, sequences can be used to automatically generate primary
key values. When a sequence object is queried, the sequence number is incremented and
passed to the query, independent of the transaction committing or rolling back. If two applications
increment the same sequence, the sequence numbers each application acquires may not be
sequential since sequence numbers are being generated by the other application. One user, or
transaction, can never acquire the sequence number generated by another user, or transaction.
Once a user or transaction generates a sequence value, that value will never be generated and
passed to another user or transaction.
Informix sequences
Informix ’s implementation of sequence objects is identical to that of Oracle. Issues regarding
syntax compatibility should be negligible with the exception of some keywords which have no effect on
the behavior of the sequence.
Informix supports DML statements (CREATE SEQUENCE, ALTER SEQUENCE, RENAME
SEQUENCE, DROP SEQUENCE) for sequence objects that multiple users can access concurrently
to generate unique integers in the 8-byte integer range. GRANT and REVOKE statements support
access privileges on sequence objects, and the CREATE SYNONYM and DROP SYNONYM
statements can be used to reference synonyms for sequence objects in the local database. The
operators, CURRVAL and NEXTVAL, can read or increment the value of an existing synonym with
behavior the same as Oracle.
Indexes
Composite indexes
A composite index can have up to 16 key parts that are columns, or up to 341 key parts that are
values returned by a UDR. This limit is language-dependent, and applies to UDRs written in SPL or
Java™; functional indexes based on C language UDRs can have up to 102 key parts. A composite
index can have any of the following items as an index key:

One or more columns
Version 1.6
30
IBM Software Group


IBM Information Management
One or move values that is returned by a user-defined function (referred to as a functional
index)
A combination of columns and user-defined functions
Maximum key size
The total widths of all indexed columns in a single CREATE INDEX statement have a limitation
based upon the page size of the dbspace in which the index resides. This limitation does not apply
to functional indexes.
An enhancement introduced with Informix Dynamic Server Version 11.10 is configurable page
sizes for dbspaces. Prior to this release, the page size of dbspaces were restricted to that of the
operating system and could not be changed thus Informix was limited to 390 byte indexes. With
page sizes configurable from 2K through 16K wider indexes are supported.
Refer to the table below, 16K page sizes raises the limit on index width to over 3000 bytes. Lifting
the 390 byte limit also permits LVARCHAR columns larger than 387 bytes to be included in an
index definition.
Page Size
Maximum Key Size
2 kilobytes
387 bytes
4 kilobytes
796 bytes
8 kilobytes
1615 bytes
12 kilobytes
2435 bytes
16 kilobytes
3245 bytes
In addition to aiding the porting process, wider indexes have satisfied requirements for Unicode
data as well as provide performance gains by reducing B-Tree index traversal costs since
indexing can be built with more items on an index page and produce fewer levels.
Index fragmentation
Just as Oracle and Informix support table fragmentation, or partitioning in Oracle, both support
index fragmentation as well. See the Table fragmentation section above for more information
regarding Informix table fragmentation and Oracle table partitioning.
Oracle indexes that are partitioned in the same manner as the table they are indexing are referred
to as local indexes. Informix refers to these as attached indexes. Oracle indexes that span
partitions are known as global indexes. Informix refers to these as detached indexes. Informix
detached indexes may also refer to indexes that do not follow the same fragmentation scheme as
the table they are indexing. Starting with Informix version 11.10, indexes can be fragmented
similarly to tables, on a partition level.
General index information
The Informix CLUSTER option should be used when appropriate. This option orders the data
within the table in the order the index requires. It is important to note that the CLUSTER index is
not maintained over time. The primary factor determining the frequency of CLUSTER index
rebuilds is the amount of DML performed against the table. Frequent INSERTS, UPDATES and
DELETES make it necessary to closely monitor CLUSTER indexes. There is only one clustered
index per table since a table’s data can only be stored in one order.
Oracle’s INITRANS and PCTFREE functionality is similar to the Informix index FILLFACTOR
option of the CREATE INDEX statement or the FILLFACTOR configuration parameter in the
ONCONFIG file. In either case, the functionality is handled by Informix’s engine once it is set, and
can be removed from the application. FILLFACTOR specifies the degree of index-page
Version 1.6
31
IBM Software Group
IBM Information Management
compactness. A low value provides room for growth in the index. A high value compacts the
index. If an index is fully compacted (100 percent), any new inserts result in splitting nodes. The
setting on the CREATE INDEX statement overrides the ONCONFIG file value. The FILLFACTOR
default value for both the CREATE INDEX statement as well as the ONCONFIG is 90.
Informix has no support for bitmap indexes.
Views
Oracle’s CREATE VIEW statement contains three options; FORCE, NO FORCE and WITH
READ ONLY. FORCE creates the view regardless of whether the view's base tables exist or the
owner of the schema containing the view has privileges on them. NO FORCE creates the view
only if the base tables exist and the owner of the schema containing the view has privileges on
them. WITH READ ONLY specifies that no deletes, inserts, or updates can be performed through
the view. These options must be removed from the Informix CREATE VIEW statements.
Because a view is not really a table, it cannot be indexed, and it cannot be the object of such
statements as ALTER TABLE and RENAME TABLE. The columns of a view cannot be renamed with
RENAME COLUMN. To change anything about the definition of a view, you must drop the view and
re-create it.
Because it must be merged with the user’s query, the SELECT statement on which a view is based
cannot contain any of the following clauses:
INTO TEMP
The user’s query might contain INTO TEMP; if the view also contains it, the data
would not know where to go.
UNION
The user’s query might contain UNION. No meaning has been defined for nested
UNION clauses.
ORDER BY
The user’s query might contain ORDER BY. If the view also contains it, the choice
of columns or sort directions could be in conflict.
Stored procedures and triggers
The ways stored procedures and triggers are created differ between Oracle and Informix. Oracle
allows a REPLACE clause in the CREATE statement to handle situations when the object already
exists. Informix does not support the REPLACE option. Instead, a DROP PROCEDURE or DROP
TRIGGER statement must precede the CREATE PROCEDURE or CREATE TRIGGER
statement, respectively, to handle the situation when the object already exists.
It should be noted a DROP statement will generate an error when the object does not exist. If it is
run interactively within the DBACCESS user interface, the DROP statement error will terminate
processing. If it is run using script execution using DBACCESS at the command line processing
will continue.
To run DBACCESS from the command line type:
dbaccess db_name
To run the file containing the create statements from the command line type:
dbaccess db_name sql_file_name.
Informix introduced an IF EXISTS clause to most of the CREATE and DROP statements at 11.7,
but the logic is different from Oracle’s OR REPLACE clause. For example, these statements:
Version 1.6
32
IBM Software Group
IBM Information Management
DROP PROCEDURE IF EXISTS …
CREATE PROCEDURE …
are logically the same as this Oracle statement:
CREATE OR REPLACE PROCEDURE …
So, it is possible to achieve the same result, but not necessarily the same number of statements.
Oracle extensions
The Oracle CLUSTER option in CREATE statements should be removed. These are not to be
confused with Informix CLUSTER index statements (See Indexes section above). An Oracle
cluster is a database schema object that contains one or more tables that all have one or more
columns in common. Rows of one or more tables that share the same value in these common
columns are physically stored together within the database. Removing this Oracle feature will not
affect the application.
Other non-Informix DDL statements like CREATE DATAFILE, CREATE CONTROLFILE,
CREATE ROLLBACK SEGMENT, CREATE SNAPSHOT, CREATE DATABASE and CREATE
DATABASE LINK must be removed or changed (in the case of the CREATE DATABASE
statement).
The Oracle CREATE PROFILE statement must be removed. An Oracle profile is a set of limits on
database resources. Profiles can be used to limit the database resources available to a user for a
single SQL statement or a single session.
Version 1.6
33
IBM Software Group
IBM Information Management
Data Manipulation
Language
CHAPTER 4:
SQL
Labels using keywords
Oracle displays labels in SQL statements that are Informix reserved words, such as UNITS,
YEAR, MONTH, DAY, HOUR, and so on, must be converted by using the Informix AS clause
between the column name and the display label. Otherwise, syntactic ambiguities will cause
errors.
Inequality operations
In addition to the Informix supported “not equal to” symbols “<>” and “!=”, Oracle supports the
symbol “^=”. All occurrences of ^= must be replaced with one of the Informix supported symbols.
Selects
Queries are executed based on how the optimizer determines the best path to the data. Oracle
and Informix developed their own query optimizers, with their proprietary methods and rules. A
query that looks exactly the same in both environments may run differently in each, following a
different path and executing faster or slower. Therefore, every query in the ported application
should be tested for performance, regardless of whether a query had to be converted.
Furthermore, Oracle supports optimizer hints within a SELECT statement. Prior to IDS 7.3 and
Informix Dynamic Server 9.2, Informix did not allow optimizer hints. See the Optimizer Directives
subsection below for more information on porting Oracle’s optimizer hints to Informix’s optimizer
directives.
Optimizer directives
Informix offers optimizer directives similar to Oracle’s optimizer hints. This feature provides the
query developer the flexibility to direct the optimizer to follow specific paths, rather than choosing
a plan through its analysis.
A query is processed in two steps. First it is optimized and compiled to product a query plan.
Secondly, it is executed to produce a result. Optimizer directives are a method for influencing the
choice of the optimizer in the creation of the plan.
Version 1.6
34
IBM Software Group
IBM Information Management
Optimizer directives address the following key issues:

Reduced time for correcting performance problems. Rewriting queries can be very time
consuming, and this allows you to have a quick way to alter a plan.

Competitive pressure. Users accustomed to this function were looking for it in Informix.

Product development tuning. This allows product development to alter plans dynamically
rather than through code changes to evaluate the effect of different optimization
techniques.
The syntax and behavior of Informix’s implementation is compatible with Oracle’s optimizer hints,
which eases the porting of applications from Oracle to Informix.
Directives are written as a comment whose first character is a ‘+’ (plus sign). An example is:
select {+ ORDERED AVOID_FULL(e)} empname, deptno
from employee e, department d
where e.dept_no = d.dept_no;
This above example specifies that the tables should be joined in the order specified in the query
and that the employee table (e) should NOT be accessed with a full table scan.
The Informix implementation differentiates itself significantly from Oracle’s in one way. Informix
supports the notion of negative directives whereas Oracle only supports direct hints. A directive
that tells the optimizer what to avoid, rather than what to choose, is unique to Informix. The query
result can be realized by writing a directive to avoid certain actions known to cause performance
issues, but allow any new indexes or table attributes to be explored by the optimizer as they are
added over the life of the table and query. This allows a DBA to continue to add indexes to tables
and not have to rewrite directives.
Additionally, Informix supports full recognition of directives with SET EXPLAIN output. Informix will
highlight semantic and syntactic errors, which Oracle does not. Optimizer directives support
control in the following areas of the optimization process:




Access methods: Index versus scans
Join Methods: Forcing hash joins, nested loop joins
Join Order: Specify which order the tables are joined
Goal: Specify first rows or all rows (response time versus throughput)
See the Informix Guide to SQL: Syntax or Reference for more information.
External optimizer directives
External optimizer directives give the DBA the ability to specify query directives and save them in
the database. These directives are applied automatically to subsequent instances of the same
query.
The SAVE EXTERNAL DIRECTIVES statement associates one or more optimizer directives with
a query, and stores a record of this association in the sysdirectives system catalog table, for
subsequent use with queries that match the specified query string. The query string must be an
exact match that includes case and white space positioning. This statement establishes an
association between the list of optimizer directives and the text of a query, but it does not execute
the specified query. Only the DBA or user informix can execute SAVE EXTERNAL DIRECTIVES.
This associates AVOID_INDEX and FULL directives with the specified query:
SAVE EXTERNAL DIRECTIVES
/*+ AVOID_INDEX (table1 index1)*/, /*+ FULL(table1) */
ACTIVE FOR
SELECT col1, col2 FROM table1, table2
Version 1.6
35
IBM Software Group
IBM Information Management
WHERE table1.col1 = table2.col1
These directives are applied automatically to subsequent instances of the same query. You must
include one of the ACTIVE, INACTIVE, or TEST ONLY keyword options to enable, disable, or
restrict the scope of external directives. When external directives are enabled and the
sysdirectives system catalog table is not empty, the database server compares every query with
the query text of every ACTIVE external directive, and for queries executed by the DBA or user
informix, with every TEST ONLY external directive.
External directives are ignored if the EXT_DIRECTIVES parameter is set to 0 in the ONCONFIG
file. In addition, the client system can disable this feature for its current session by setting the
IFX_EXTDIRECTIVES environment variable to 0. If an external directive has been applied to a
query, output from the SET EXPLAIN statement indicates “EXTERNAL DIRECTIVES IN EFFECT”
for that query. Any inline directive is ignored by the optimizer when the external directives are
applied to a query that matches the SELECT statement.
Like inline optimizer directives that are embedded within a query, external directives can improve
performance in some queries for which the default behavior of the query optimizer is not
satisfactory. Unlike inline directives, external directives can be applied without revising or
recompiling existing applications.
Inserts
Informix does not support Oracle’s INSERT with SELECT statement utilizing an UNION clause
(although a view with an UNION clause can be referenced, resulting in an UNION operation).
Additionally, Informix does not support an INSERT statement with a VALUE clause with SELECT
statements. The SELECT statement within a VALUE clause can be rewritten by omitting the
VALUE clause and performing an INSERT INTO table_name SELECT … FROM
other_table_name.
Temporary tables
Informix and Oracle implemented the concept of temporary tables differently. Oracle implements
temporary tables as a work area during batch data loads. Informix implements temporary tables
just like regular database tables. These temporary tables can be created, manipulated, and
dropped only within a session, such as stored procedures and ESQL programs. Once the session
ends, any remaining temporary tables are automatically dropped. Temporary tables can give an
application extra functionality; however, their use should be limited if reducing database
extensions to increase database independence within an application is a priority.
Outer joins
Both Oracle (starting with Oracle 9i) and Informix support ANSI standard syntax for outer join
specification. The syntax for left and right outer join using the plus sign (+) in the WHERE clause
is only supported for backward compatibility however it is still in existence. The use of ANSI outer
join syntax is recommended.
The Oracle outer join syntax + (placed after the column which has values not matching the
corresponding column in the joined table) can be replaced with the Informix equivalent, OUTER.
The OUTER keyword is placed within the SELECT statement before the name of the subservient
table. Unlike Oracle, in Informix multiple outer joins per SELECT statement are allowed, grouped
with parentheses.
Sorts
In Oracle sorts, NULL values are considered the highest value and are therefore ordered last in
ascending sorts. Informix sorts with NULLS as the lowest value, ordering them first in ascending
sorts. First, it must be determined whether this sorting difference will affect the outcome enough
to warrant a work around. In most cases it will not. If it does, then a stored procedure can be
Version 1.6
36
IBM Software Group
IBM Information Management
written to evaluate whether a column is NULL and if so, replace it with a high value so that it will
sort last. Once the application receives the results, it must replace the high values with NULL if
the column is going to be displayed, or manipulated.
Exceptions
Error handling using hard coded Oracle SQL codes must be replaced with the corresponding
Informix SQL codes.
Correlation names
Informix does not support correlation names with aliases on the main table of an UPDATE or
DELETE statement. Such cases must be converted. For example:
Oracle:
UPDATE customer C
SET zip_code = ‘92612’
WHERE zip_code IN
(SELECT zip_code FROM zip_table Z
WHERE C.create_date <= Z.effective_date)
Informix:
UPDATE customer
SET zip_code = ‘92612’
WHERE zip_code IN
(SELECT zip_code FROM zip_table Z
WHERE customer.create_date <= Z.effective_date)
-andOracle:
DELETE customer C
WHERE order_date <=
(SELECT control_value FROM control_table T
WHERE T.control_field = ‘archive_date’
AND C.state = T.state )
Informix:
DELETE customer
WHERE order_date <=
(SELECT control_value FROM control_table T
WHERE T.control_field = ‘archive_date’
AND customer.state = T.state )
Note that Informix allows correlation names with aliases on tables other than the updated or
deleted table.
Aliases
Unlike Oracle, in Informix, if an alias is used in the FROM clause of a SELECT statement, it must
also be used in the SELECT list and WHERE clauses. The original table name should be
replaced with the alias wherever aliases and original names are used together within a SELECT
statement in an Oracle application.
Hierarchical queries
Informix does not allow query results to be organized hierarchically in a B-tree fashion. Oracle
does allow it by using the clauses START WITH… and CONNECT BY PRIOR in the SQL
Version 1.6
37
IBM Software Group
IBM Information Management
statement. In Oracle, if a table contains hierarchical data, a bill of materials for example, rows can
be selected in a hierarchical order using the following clauses.
START WITH
The START WITH clause identifies the row(s) to be used as the root(s) of a hierarchical
query. This clause specifies a condition that the root(s) must satisfy. If this clause is
omitted, Oracle uses all rows in the table as root rows. A START WITH condition can
contain a subquery.
CONNECT BY
The CONNECT BY clause specifies the relationship between parent and child rows in a
hierarchical query. This clause contains a condition that defines this relationship. The part
of the condition containing the PRIOR operator must have one of the following forms:
PRIOR expression comparison_operator expression
-orexpression comparison_operator PRIOR expression
To find the children of a parent row, Oracle first evaluates the PRIOR expression to
identify the parent row(s) and the other expression for each row in the table. Rows for
which the other expression is true are the children of the parent. The CONNECT BY
clause can contain other conditions to further filter the rows selected by the query.
WHERE
The WHERE clause can restrict the rows returned by the query without affecting other
rows of the hierarchy.
Oracle uses the information from each of the clauses mentioned above to form the hierarchy
using the following steps.
1. Oracle selects the root row(s) of the hierarchy. These are the rows that satisfy the
condition of the START WITH clause.
2. Oracle selects the child rows of each root row. Each child row must satisfy the
condition of the CONNECT BY clause with respect to one of the root rows.
3. Oracle selects successive generations of child rows. Oracle first selects the children
of the rows returned in step 2, and then the children of those children, and so on.
Oracle always selects children by evaluating the CONNECT BY condition with respect
to a current parent row.
4. If the query contains a WHERE clause, Oracle removes all rows from the hierarchy
that do not satisfy the condition of the WHERE clause. Oracle evaluates the WHERE
condition for each row individually, after the row has been fetched, rather than only
fetching rows that satisfy the WHERE condition.
5. Oracle returns the rows in the order of an in-order, or left-root-right, binary tree
traversal.
Version 1.6
38
IBM Software Group
IBM Information Management
For example, the following SQL statement returns the data in the adjacent table in hierarchical
order. The root row is defined to be the employee whose job is ‘PRESIDENT’. The child rows of a
parent row are defined to be those rows whose manager number is the employee number of the
parent row.
SELECT ename, empno,
mgr, job
FROM emp
START WITH
job = ‘PRESIDENT’
CONNECT BY PRIOR
empno = mgr
ENAME
KING
JONES
SCOTT
ADAMS
FORD
SMITH
BLAKE
ALLEN
WARD
MARTIN
TURNER
JAMES
CLARK
MILLER
EMPNO
7839
7566
7788
7876
7902
7369
7698
7499
7521
7654
7844
7900
7782
7934
MGR
7839
7566
7788
7566
7902
7839
7698
7698
7698
7698
7698
7839
7782
JOB
PRESIDENT
MANAGER
ANALYST
CLERK
ANALYST
CLERK
MANAGER
SALESMAN
SALESMAN
SALESMAN
SALESMAN
CLERK
MANAGER
CLERK
To duplicate this hierarchical functionality in Informix, stored procedures or functions can be
written requiring intensive use of cursors and program arrays. Informix offers the choice of
creating and using a User Defined Routine or “UDR”. See User Defined Routines section below.
Use of Informix global arrays will help considerably. To maximize read processing at the expense
of insert processing, another method is to break the table into two tables, one containing the data
and the other containing the relationship (foreign keys) between each parent and child. A parent
row would have an entry in the relationship table for each of its children, grandchildren, great
grandchildren, and so on. The opposite is true, where a child row would have an entry in the
relationship table for its parent, grandparent, great grandparent, and so on.
Truncate
Informix supports the TRUNCATE statement for deleting all active data rows from a table and
associated indexes. When using Informix’s TRUNCATE, you also have the option of releasing the
storage space that was occupied by the rows and index extents or keeping the space allocated to
be used as the table is repopulated with new data.
TRUNCATE [TABLE] table [ [ DROP | REUSE ] STORAGE ];
You may use the command’s simplest usage:
TRUNCATE my_table;
In the example above, the TRUNCATE statement drops all the data for the table and keeps only
the initial extents. There is a minor difference from Oracle syntax as Informix does not require the
keyword TABLE.
Another example:
TRUNCATE my_table REUSE STORAGE;
Version 1.6
39
IBM Software Group
IBM Information Management
This example drops all the data for the table but retains all the space allocated.
The permissions needed for TRUNCATE TABLE depend on the existence of DELETE triggers on
the table. For tables with DELETE triggers, ALTER permission on the table is required and
RESOURCE or DBA privileges because the DELETE triggers will be bypassed. For tables without
DELETE triggers, you need DELETE permission on the table and CONNECT privilege to the
database.
While Oracle does not provide rollback, Informix does permit TRUNCATE TABLE to execute
within a transaction. When you rollback a TRUNCATE statement, no rows are removed from the
table, and the storage extents that hold the data rows and index pages continue to be allocated to
the table. In a database that supports transaction logging, only the COMMIT WORK or
ROLLBACK WORK statement is valid after the TRUNCATE statement within a transaction. Any
other statement will generate an error.
The TRUNCATE statement does not reset the serial value of SERIAL or SERIAL8 columns. To
reset the counter of a serial column, you must do so explicitly by using the MODIFY clause of the
ALTER TABLE statement, either before or after you execute the TRUNCATE statement.
After the TRUNCATE statement successfully executes, Informix automatically updates the
statistics and distributions for the table and for its indexes in the system catalog to show no rows
in the table nor in its dbspace partitions. It is not necessary to run the UPDATE STATISTICS
statement immediately after you commit the TRUNCATE statement.
Host variables
Host variable formats should not change during the porting process. Instead, data types should be
converted in a manner to preserve the column and host variable’s formats. However, there are
times when the database schema changes in a way where the host variable format must change.
Any column converted to a different format in Informix than that of Oracle requires that its
corresponding host variable format be changed to be consistent.
Alternatively, if an Oracle format, such as date and numeric variables, is not directly supported in
Informix, then the conversion may require some format processing before or after the SQL
statement. For example, the Oracle function TO_CHAR is used to format both date and numerical
values. A similar function, or at least two functions, one to handle date data types and another to
handle numeric data types, can be declared and used in the Informix application.
Informix provides two built-in functions: TO_DATE which converts a character string to a
DATETIME variable and TO_CHAR which converts a DATETIME variable to a character string. .
When converting variables, an optional formatting string is allowed which determines how the
string is displayed (full day names, partial day names, full months, month number, and so on).
There is also a function, ifx_to_gl_datetime(), which takes an Oracle date format and returns the
corresponding Informix date format. This function is supplied in genlib and is for use in ESQL
programs to ease migration efforts from Oracle.
The syntax is as follows:
TO_CHAR (source_date, fmt)
Returns a character string, containing the date specified
in source_date, in the format specified by fmt if one is
provided. If fmt is missing, the function will use the
default date format (as specified by the client
environment variables). Note, fmt must be an Informix
format and does not necessarily include all possible
Oracle date formats.
TO_DATE (source_string, fmt) Evaluates source_string as a date according to the
format fmt. If fmt is missing, the function will use the
Version 1.6
40
IBM Software Group
IBM Information Management
default format (as specified by the client environment
variables). Note, fmt must be an Informix format and
does not necessarily include all possible Oracle date
formats.
These functions are mainly useful for simplifying migration from Oracle to Informix, but are also
useful for performing advanced searches on DATETIME data types and for better output
presentation.
Date and time functions
Informix version now has built-in support for most of Oracle’s date functions so it will not be
necessary to modify or replace Oracle’s SYSDATE or ADD_MONTHS(date,months),
LAST_DAY(date), MONTHS_BETWEEN(date1, date2), NEXT_DAY(date,char),
ROUND(date,format), SYSDATE, and TRUNC(date,format).
SYSDATE
IDS 11.10 will support the SYSDATE operator which returns a single value representing the
current date and time from the operating system clock. SYSDATE is identical to the Informix’s
CURRENT operator, except that the default precision of SYSDATE is YEAR TO FRACTION(5),
while the default precision of CURRENT is YEAR TO FRACTION(3). On Windows platforms that
do not support a seconds scale greater than FRACTION(3), SYSDATE is effectively a synonym
for the CURRENT operator,
In addition to SYSDATE, Informix version 11.10 has support for Oracle’s date functions
ADD_MONTHS(date,months), LAST_DAY(date), MONTHS_BETWEEN(date1, date2),
NEXT_DAY(date,char), ROUND(date,format), SYSDATE, and TRUNC(date,format). Depending
on the whether or not the Oracle date_format argument is supported by Informix, TO_CHAR(date,
char_format) and TO_DATE(character_string, date_format) may have to be converted to Informix
date processing. Date processing may be required because the Oracle application may format
the date in many different ways, unsupported by Informix.
The formats used in the Oracle functions TO_CHAR, TO_NUMBER and TO_DATE are illustrated
below. These formats should be replaced with Informix formats wherever possible, format
processing functions, or stored procedures written to duplicate the Oracle functionality. Refer to
the appropriate Informix API Programmer’s Manual (Informix-ESQL/C Programmer’s Manual or
Informix-ESQL/COBOL Programmer’s Manual) for more information.
Number formats
Element
9
Example
9999
0
$
B
09999990
$9999
B9999
MI
9999MI
S
S9999999
Version 1.6
Description
Return value with the specified number of digits with a leading
space if positive. Return value with the specified number of
digits with a leading minus if negative. Leading zeros are
blank, except for a zero value, which returns a zero for the
integer part of the fixed-point number.
Return leading zeros. Return trailing zeros.
Return value with a leading dollar sign.
Return blanks for the integer part of a fixed-point number
when the integer part is zero (suppress leading zeros
regardless of whether zeros are used in the format model i.e.
B00999 ).
Return negative value with a trailing minus sign “-“. Return
positive value with a trailing blank.
Return negative value with a leading minus sign “-“. Return
41
IBM Software Group
Element
IBM Information Management
Example
S
PR
9999PR
D
G
C
L
,
.
V
99D99
9G999
C999
L999
9,999
99.99
999V99
EEEE
RNrn
9.9EEEE
RN
FM
FM90.9
Description
positive value with a leading plus sign “+”. Return negative
value with a trailing minus sign “-“. Return positive value with a
trailing plus sign “+”.
Return negative value in <angle brackets>. Return positive
value with a leading and trailing blank.
Return a decimal point “.” In the specified position.
Return a group separator in the specified position.
Return the ISO currency symbol in the specified position.
Return the local currency symbol in the specified position.
Return a comma in the specified position.
Return a decimal point “.” In the specified position.
n
Return a value multiplied by 10 (and if necessary, round it
up), where n is the number of “9”s after the “V”.
Return a value in scientific notation.
Return a value as Roman numerals in uppercase. Return a
value as Roman numerals in lowercase. Value can be an
integer between 1 and 3999.
Return a value with no leading or trailing blanks.
Date formats
Element
-/,.;:”text”
AD or A.D.
AM or A.M.
BC or B.C.
CC or SCC
D
DAY
DD
DDD
DY
IW
IYY or IY or I
IYYY
HH or HH12
HH24
J
MI
MM
MONTH
MON
RM
Q
RR
WW
W
PM or P.M.
SS
SSSSS
Y/YYY
YEAR or SYEAR
YYYY or SYYYY
Version 1.6
Meaning
Punctuation and quoted text is reproduced in the result.
AD indicator with or without periods.
Meridian indicator with or without periods.
BC indicator with or without periods.
Century; “S” prefixes BC dates with “-“.
Day of week (1-7).
Name of day, padded with blanks to length of 9 characters.
Day of month (1-31).
Day of year (1-366).
Abbreviated name of day.
Week of year (1-52 or 1-53) based on the ISO standard.
Last 3, 2, or 1 digit(s) of ISO year.
4-digit year based on the ISO standard.
Hour of day (1-12).
Hour of day (0-23).
Julian day; the number of days since January 1, 4712 BC. Number
specified with ‘J’ must be integers.
Minute (0-59).
Month (01-12; JAN = 01)
Name of month, padded with blanks to length of 9 characters.
Abbreviated name of month.
Roman numeral month (I-XII; JAN = I).
Quarter of year (1, 2, 3, 4; JAN-MAR = 1)
Last 2 digits of year; see below for years in other centuries.
Week of year (1-53) where week 1 starts on the first day of the year
and continues to the seventh day of the year.
Week of month (1-5) where week 1 starts on the first day of the
month and ends on the seventh.
Meridian indicator with and without periods.
Second (0-59).
Seconds past midnight (0-86399).
Year with comma in the “/” position.
Year spelled out; “S” prefixes BC dates with “-“.
4-digit year; “S” prefixes BC dates with “-“.
42
IBM Software Group
YYY or YY or Y
IBM Information Management
Last 3, 2, or 1 digit(s) of year.
The RR date format element
The RR date format element is similar to the YY date format element, but it provides additional
flexibility for storing date values in other centuries. The RR date format element allows storing the
century even though only two digits are entered for the year. The table below illustrates how the
year is stored based on only two digits.
If the year is entered as:
0 – 49
50 - 99
The return date is in the The return date is in the century
If the last two
0 - 49
current century.
before the current one.
digits of the
current year
50 - 99 The return date is in the The return date is in the current
century after the current one.
century.
are:
User-defined routines
User-defined data types, user defined behaviors and user defined access methods add rich
functionality to Informix. A user-defined routine (UDR) can be developed in C, Java, or Informix
SPL language, to vastly extend the capabilities of the database. Porting applications to Informix
gives the option to create UDRs for aggregate and mathematical functions or to emulate Oracle
built-in functions and reduce the impact of replacing all references throughout the application. Or,
you can rename an Informix function to the corresponding Oracle function name.
Compatible SQL Functions
Informix Dynamic Server version 11.10 has added support for a number of built-in SQL functions
to ease a migration effort. These new functions, which perform common operations and data
manipulation, provide compatibility with Oracle routines thus simplifying the migration of
applications that have been developed for an Oracle database.






Date and time functions; ROUND, TRUNC, ADD_MONTHS, LAST_DAY, NEXT_DAY,
MONTHS_BETWEEN, SYSDATE
Conversion functions; ASCII, TO_CHAR, TO_NUMBER
String manipulation; LTRIM, RTRIM
Number manipulation; ROUND, TRUNC, CEIL, FLOOR, POWER
Bit manipulation; BITAND, BITOR, BITXOR, BITNOT, BITANDNOT
Others; NULLIF, FORMAT_UNITS
These functions are documented with examples in the IBM Informix Guide to SQL: Syntax.
Aggregate functions
Like Oracle, the result returned by an Informix aggregate function is NULL if all of the column
values are NULL, with the exception of COUNT which returns 0 (zero).
Like Oracle, Informix aggregate functions cannot be used in a WHERE clause unless it is on a
corresponding column originating from a parent query and the WHERE clause is within a subquery that is within a HAVING clause, or the aggregate function is contained within a sub-query.
Unlike Oracle, in Informix the argument of an aggregate function cannot be another aggregate
function.
Informix supports the SELECT COUNT (column_name) … statement, where the number of rows
containing non-null values in the specified column is returned.
Version 1.6
43
IBM Software Group
IBM Information Management
The Oracle aggregate functions STDDEV and VARIANCE are supported, however the Informix
standard deviation routine is named STDEV thus all references to Oracle’s STDDEV must be
changed to match Informix’s STDEV.
Informix does not support Oracle’s greatest lower boundary (GLB ) or least upper boundary
(LUB). Therefore, UDRs must be written to provide equivalent functionality. Informix allows users
to define their own aggregate functions known as user-defined aggregates (UDA). This extension
of existing aggregates can be used for new data types as well as the definition of new aggregates.
In Informix, TEXT and BYTE columns cannot be used in aggregate functions such as COUNT,
AVG, MAX, MIN and SUM.
Mathematical functions
Informix does not support all of Oracle’s mathematical functions such as SIGN, COSH, SINH, and
TANH. Therefore, functions or UDRs must be written in the Informix application to provide
equivalent functionality.
In Informix, the rounding factor within the ROUND function must be a value from -32 to 32. This
limitation has seldom been encountered as a migration issue.
String functions
LENGTH
Oracle’s LENGTH function will return different values than Informix for strings stored in CHAR
data types. The numeric return value representing the string length returned by Oracle will include
all trailing spaces. Whereas Informix’s LENGTH function will ignore trailing blanks regardless of
data type. For example, for the two CHAR strings “BOB” and “BOB “ Oracle’s LENGTH function
will return different values for each string, 3 and 5 respectively. Whereas Informix’s LENGTH
function will ignore trailing blanks and return the value 3 for both. When the input string is NULL,
both database functions will return a NULL.
LTRIM and RTRIM
The SQL Compatibility features of Informx has support for LTRIM and RTRIM and will return
identical values to that of Oracle. No modifications will be necessary to SQL statements utilizing
these functions.
Oracle Extensions
Informix does not support all of Oracle’s string functions such as CHR, INSTR, SOUNDEX, and
TRANSLATE. Therefore, corresponding user-defined routines or UDRs (i.e. functions or stored
procedures) must be written in the Informix application to provide equivalent functionality.
Please note that the VERITY and EXCALIBUR Datablades included with Informix will work with
Oracle’s string function SOUNDEX.
Other Oracle Functions
Informix does not support the following Oracle functions. Therefore, corresponding functions must
be written in the Informix application to provide equivalent functionality. Alternatives to some of the
more common Oracle functions follow this list.
CHARTOROWID
CONVERT
DUMP
GREATEST
GREATEST_LB
Version 1.6
44
IBM Software Group
IBM Information Management
HEXTORAW
LEAST
LEAST_UB
RAWTOHEX
ROWIDTOCHAR
TO_LABEL
TO_MULTI_BYTE
TO_SINGLE_BYTE
UID
USERENV(OSDBA/ LABEL/ LANGUAGE/ TERMINAL/ SESSIONID/ ENTRYID)
VSIZE
Macros
Oracle contains macros, sometimes referred to as language constructs, which can determine the
status of an object. Informix does not support Oracle’s macros. These macros must be removed
from the code, and the associated logic should be implemented with equivalent Informix logic,
where applicable.
%ISOPEN and %NOT FOUND
The macro cursor_name%ISOPEN returns a Boolean value to indicate whether the cursor is
open, and cursor_name%NOTFOUND indicates whether there are any more rows yet to be
fetched from the cursor cursor_name. These macros, used in condition statements, are followed
by some logic to handle the true and/or false conditions.
In the case of ISOPEN, this macro and its associated logic can just be omitted since the
FOREACH loop processing does not explicitly open a cursor and therefore, the condition cannot
be checked. In the case of NOTFOUND, this macro should be omitted and its associated logic
converted to Informix logic within an Informix FOREACH loop.
%ROWTYPE
The Oracle macro prefix%ROWTYPE is used in the declarative section as a data type to declare
variables, similar to the structure construct of C or RECORD of INFORMIX. The prefix can be
either a table name or another structure name. Structure names ultimately refer back to a table
name. This macro may be replaced with the Informix statement LIKE table_name.*. The construct
LIKE table_name.* cannot be used in SPL. Instead, the construct DEFINE column1 LIKE
table_name.column1; DEFINE column2 LIKE table_name.column2; and so on, should be used to
declare variables corresponding to all the columns of the table. Then operations on the whole or
part of the structure should be replaced with operations on single SPL variables.
%TYPE
The Oracle macro prefix%TYPE is used in the declarative section as a data type to declare single
variables. The prefix is either a table_name.column_name or a structure_name.variable_name. A
structure_name.variable_name ultimately refers back to a table_name.column_name. This macro
can be replaced with the Informix statement LIKE table_name.column_name.
Pseudo-columns
Pseudo-columns are columns that exist in tables but are not displayed from a SELECT * FROM
table_name query. Informix pseudo-columns are generally reserved for the engine’s use.
Eliminating the use of such columns increases an application’s portability and eliminates the need
for future modifications if the engine is ever modified to process the column differently or not at all.
Version 1.6
45
IBM Software Group
IBM Information Management
LEVEL
In Oracle, for each row returned by a hierarchical query, the pseudo-column LEVEL returns 1 for a
root node, 2 for a child of a root, 3 for a child whose parent is at level 2, and so on. A root node is
the highest node within an inverted tree, and therefore has no parent. A child node is any non-root
node. A parent node is any node that has children. A leaf node is any node without children. To
define a hierarchical relationship in a query, you must use the START WITH and CONNECT BY
clauses. Informix does not support the LEVEL clause. See the Hierarchical Queries subsection in
the SQL section in the “Data Manipulation Language” chapter for more information on how to
process these queries.
ROWID
Oracle’s ROWID pseudo-column returns the row's address for each row in the database. ROWID
values contain the following information necessary to locate a row:



Which data block in the data file
Which row in the data block (first row is 0)
Which data file (first file is 1)
Usually, a ROWID value uniquely identifies a row in the database. However, rows in different
tables that are stored together in the same cluster can have the same ROWID. Values of the
ROWID pseudo-column have the data type ROWID. ROWID values have several important uses:
 They are the fastest way to access a single row.
 They can show you how a table's rows are stored.
 They are unique identifiers for rows in a table.
A ROWID does not change during the lifetime of its row. However, you should not use ROWID as
a table's primary key. If a row is deleted and re-inserted, its ROWID may change, even when
using the export and import utilities. If a row is deleted, Oracle may re-assign its ROWID to a new
row inserted later. Although you can use the ROWID pseudo-column in the SELECT and WHERE
clauses of a query, these pseudo-column values are not actually stored in the database. The
value of a ROWID pseudo-column cannot be inserted, updated, or deleted. For example, the
following Oracle statement selects the address of all rows that contain data for employees in
department 20:
SELECT ROWID, ename
FROM emp
WHERE deptno = 20
ROWID
0000000F.0000.0002
0000000F.0003.0002
0000000F.0007.0002
0000000F.000A.0002
0000000F.000C.0002
ENAME
SMITH
JONES
SCOTT
ADAMS
FORD
The equivalent pseudo-column in Informix is also known as ROWID, and although the behavior is
similar, the data type is different from Oracle’s. See the ROWID subsection in the Data Types
section in the chapter “Data definition language” for more information.
ROWNUM
In Oracle, for each row returned by a query, the ROWNUM pseudo-column returns a number
indicating the order in which Oracle selected the row from a table or set of joined rows. The first
row selected has a ROWNUM of 1, the second has 2, and so on. ROWNUM can be used to limit
the number of rows returned by a query, as in this example to read 9 rows:
SELECT *
FROM emp
WHERE ROWNUM < 10
Version 1.6
46
IBM Software Group
IBM Information Management
You can also use ROWNUM to assign unique values to each row of a table, as in this example:
UPDATE tabx
SET col1 = ROWNUM
Oracle assigns a ROWNUM value to each row as it is retrieved, before the rows are sorted by an
ORDER BY clause. Therefore, the final order of the rows is in ORDER BY order not in ROWNUM
order. An ORDER BY clause does not affect the ROWNUM values except in the case where the
ORDER BY clause causes Oracle to use an index. In that case, the ROWNUM values are set in
the order the rows are retrieved using the index and hence in ORDER BY order. This order is
different than if the rows were retrieved without the index. So in this case the ORDER BY can
affect the ROWNUM values.
Conditions which test for ROWNUM values greater than zero are always false. For example, this
query returns no rows:
SELECT * FROM employee
WHERE ROWNUM > 1
The first row fetched is assigned a ROWNUM of 1, thus making the condition false. The second
row to be fetched is now the first row and is also assigned a ROWNUM of 1 making the condition
false. All rows subsequently fail to satisfy the condition, so no rows are returned.
Although there is no ROWNUM equivalent in Informix, there are solutions. Beginning with IDS 7.3
and in Informix Dynamic Server 2000, Informix provides a feature which allows the user to limit
the results of a query to the first N rows. This was implemented for TPC-D compliance and to
support “rank” queries. Rank queries can be assembled by using FIRST N with the ORDER BY
clause. Informix will return the top N rows according to some ordering criteria.
Therefore the following Oracle SELECT utilizing ROWNUM:
SELECT * FROM emp WHERE ROWNUM < 10
can be ported to Informix as follows:
SELECT FIRST 9 * FROM emp
Informix does not support SELECT FIRST N in complex cases as the following:



Sub-queries (SELECT within a SELECT)
View definitions (Cannot be used by a SELECT statement which references a view)
UNION queries
The behavior of SELECT FIRST N depends on the presence of an ORDER BY clause. If no
order by clause is specified, the first N rows returned may be in any order. Examples are as
follows:
/* find 10 highest paid employees */
SELECT FIRST 10 name, salary
FROM emp
ORDER BY salary;
/* find 10 highest salary values
SELECT FIRST 10 DISTINCT salary
FROM emp
ORDER BY salary;
Version 1.6
*/
47
IBM Software Group
IBM Information Management
Informix supports column names of “first”. Thus, without a positive integer following the word
“first”, the token is parsed as a column name rather than a keyword. The value of N may be
31
between 1 and (2 -1).
When ROWNUM is used in a WHERE clause, the same results can be obtained through the use
of the FIRST N and SKIP clauses, but if ROWNUM is used in the select list, the solution is a little
more complicated. Simply stated, you can construct a query where the ROWNUM column in any
row is the count of the rows that came before. This involves creating a correlated subquery where
the subquery contains a self-join. This can be done for any table, or set of tables, which has a
unique key defined on it. Here is an example using the customer table of the stores7 database.
select
counter.rownum,
base.customer_num,
base.fname,
base.lname
from
-- There can be more than one table here, and the result
-- set should thought of as a table (just not a base table).
-- The result table has to be joined to itself in the
-- subquery; so, if there are multiple tables in this FROM
-- clause, the expansion can get messy. You have to have a
-- set of columns that uniquely identify each row in the
-- result table, and join across them. ROWID would
-- likely work if the table is not fragmented, but if it is,
-- there is no guarantee the final results would be accurate
-- because ROWID is not guaranteed to be unique across
-- fragments.
customer base,
(select
count(*) as rownum,
a.customer_num
-- any unique key, possibly multiple
-- columns
from
customer a,
customer b
where
-- This is where the rownum is determined the relationship
-- here has to match the outer order-by, where the rows
-- are sorted, and has to create a unique sort order
--- Any columns to be ordered by go here.
-- Also, the unique key has to be used to keep rows
-- that do not have a unique sort order from being merged
(a.lname > b.lname) -- example, sorting by last name
or
(a.lname = b.lname and a.fname > b.fname)
-- sorting by fname where lname is equal
or
(a.lname = b.lname and a.fname = b.fname
and a.customer_num >= b.customer_num)
-- sorting by unique key where all the
-- other sort columns are equal
-- The expansion above is logically the same as
-a.lname || a.fname || to_char(a.customer_num) >=
-b.lname || b.fname || to_char(b.customer_num)
-- but it allows the server to utilize any indexes that
-- may exist.
group by
-- unique key columns go here
Version 1.6
48
IBM Software Group
IBM Information Management
a.customer_num
) counter
where
-- key columns in the base tables go here
base.customer_num = counter.customer_num
-- if you want to limit on rownum, it goes here
-- and rownum <= 10
order by
counter.rownum
If using ROWNUM as an assignment, as in:
UPDATE tabx
SET col1 = ROWNUM
The following Informix-ESQL/C pseudo-code example would have to be used:
int counter = 0;
EXEC SQL declare c1 cursor for
SELECT col1, col2
INTO :col1, :col2
FROM table 1
WHERE col1 = "XX";
EXEC SQL open c1;
while (SQLCODE == 0)
{
EXEC SQL fetch c1;
counter++;
/* Increment counter for each row
fetched */
if (counter >= 5)
{
break;
/* logic... */
}
}
/* End if */
/* End while */
Update using cursors
There are slight differences between the ways Informix and Oracle process cursors. Unlike
Oracle, in Informix, the WHERE CURRENT OF clause cannot be used to update tables in a
SELECT statement joining multiple tables since the WHERE CURRENT OF clause requires a
FOR UPDATE cursor and Informix does not support the FOR UPDATE clause in SELECT
statements that join multiple tables. Therefore, in the multi-table join statements, the Oracle
options FOR UPDATE and WHERE CURRENT OF should be removed and the update of the
rows should be done using a separate UPDATE statement in the same cursor loop.
Version 1.6
49
IBM Software Group
IBM Information Management
In Informix, a commit or rollback statement closes all cursors open in a given transaction
boundary. See the Transaction Processing section in CHAPTER 5: Application Architecture for
more information. In situations where the intention is to commit or rollback without closing the
cursor, in other words, where the commit or rollback is executed within a cursor fetch loop, the
cursor can be declared as a HOLD cursor. This requires that a BEGIN WORK is issued before
the cursor loop starts. A HOLD cursor is not closed when a commit or rollback statement is
issued.
In Informix, the FOR UPDATE clause cannot be used when declaring a HOLD cursor. Thus,
where an Oracle application updates a table from which it fetches data in the fetch loop or issues
a commit work in the fetch loop, it must be converted to Informix. The cursor can be declared with
HOLD and then an UPDATE statement can be issued without the WHERE CURRENT OF clause.
In order to uniquely identify the row to be updated in the table, in other words, in order to simulate
the WHERE CURRENT OF clause, the ROWID or unique primary key columns of the table(s) to
be updated must also be fetched and the WHERE CURRENT OF clause can be replaced with
WHERE ROWID = fetched rowid or WHERE unique primary key column(s) = fetched unique
primary key column(s). A BEGIN WORK must follow immediately after a COMMIT WORK or
ROLLBACK WORK in the fetch loops to simulate Oracle implied transaction boundaries.
These transaction control statements work for either Informix logged databases or Informix ANSI
mode databases, however, ANSI mode database processing with these statements will set
certain warning flags after executing the BEGIN WORK statement and continue processing
without failure. See the ANSI vs. Non-ANSI subsection in the Databases section in the chapter
“Data Manipulation Language” for more information.
System tables
References to Oracle system tables should be replaced with corresponding references to Informix
system tables. The information schema views provided by Informix can be used. These views are
created after the database is installed. They are populated by data in the system catalog tables
and are used for easier porting.
Stored procedures
Informix procedures and functions are considered to be user-defined routines (UDR). A UDR can be
written in Informix’s Stored Procedure Language (SPL) or an external language, such as C or
Java. A procedure is a routine written that does not return a value. A function is a routine written
that returns a single value, a value with a complex data type, or multiple values.
Informix SPL is an extension to Informix SQL and provides procedural flow control such as
looping and branching. A SPL routine is a generic term that includes both SPL procedures and SPL
functions. You use SQL and SPL statements to write an SPL routine. SPL statements can be used
only inside the CREATE PROCEDURE, CREATE PROCEDURE FROM, CREATE FUNCTION, and
CREATE FUNCTION FROM statements. SPL routines are parsed, optimized, and stored in the
system catalog tables in executable format.
Like Oracle, Informix stored procedures support input, output and input/output parameters and
can be used in SQL statements wherever expressions are allowed.
Size limit
Informix stored procedures have a size limit of approximately 64K. Oracle stored procedures
greater than 64K in size can be broken into smaller Informix stored procedures communicating
with each other as though they were one by passing and returning the necessary values.
Parameter limit
Version 1.6
50
IBM Software Group
IBM Information Management
Informix has a limit of 341 parameters for each stored procedure. This limit also applies to UDRs
written in the Java language. UDRs written in the C language can have no more than 102
parameters.
You can define any number of SPL routine parameters, but the total length of all parameters
passed to an SPL routine must be less than 64 kilobytes. No more than nine arguments to a UDR
written in the Java language can be DECIMAL data types of SQL that the UDR declares as
BigDecimal data types of the Java language. Any C language UDR that returns an opaque data
type must specify opaque_type in the var binary declaration of the C host variable.
Packages
An Oracle package is a collection of functions, procedures, and variables that can be enabled and
accessed as a unit. There is no direct equivalent within Informix, but there are ways of achieving
similar capabilities.
Within Oracle, a procedure within a package can be accessed through grammar such as
package_name.procedure_name. If you create an owner or schema name within the Informix
system the same as the package name, then it will be easier to migrate calls to that procedure
because the grammar is effectively the same, although the meaning changes somewhat. Using
this practice, a call to a migrated procedure would be owner.procedure_name, where the owner
name is the same as the package name. Translating package names as owner names is a way to
maintain the scoping of the objects within the package.
Maintaining the aspect of being able to enable use of or upgrade the collection of package objects
can be done by creating a datablade that contains all the objects that used to be part of the
package. Datablade routines can be procedures or functions written in Stored Procedure
Language (SPL), C, and Java. In addition, routines can be written in C++ on Windows platforms.
Routines
Oracle’s stored functions and stored procedures are similar in concept to Informix’s stored
procedures. Oracle’s user defined database level functions such as stored functions, stored
procedures all need to be converted to Informix stored procedures using the Informix SPL, C, or
Java. Routines written in SPL have the advantage of being maintained and backed up with
database backups. Routines written in C are fast, but are not automatically backed up when the
database is and need to be compiled specifically for the operating system on which it will run.
Routines written in Java also not backed up by the DBMS itself, but they are platform
independent. However, probably as a result of having to convert between system memory where
the objects have C structures and Java virtual machine memory where the objects have Java
structures, the performance of Java routines can be slow compared with the C equivalent.
All procedures written in an Oracle package body must be rewritten as separate Informix
procedures. When rewriting package bodies into separate procedures, Oracle’s variable
declarations can be replaced at the package level (global) with Informix’s global variables. The
Informix global variables must be defined in the first stored procedure of the logical group.
Exceptions
The method of handling exceptions is different between Informix and Oracle. Oracle has many
predefined and user defined exception labels such as CURSOR_ALREADY_OPEN,
NO_DATA_FOUND, ZERO_DIVIDE, and so on. The labels can be used in the logic to identify
errors. Only one exception check is allowed per BEGIN and END block using the EXCEPTION
construct, and it is normally placed just before the END statement.
Informix also supports predefined and user defined exceptions, however, they are represented
numerically, not with labels. In Informix, all the exceptions checked in the stored procedure control
blocks, delimited with BEGIN and END statements, must be declared explicitly at the top of each
Version 1.6
51
IBM Software Group
IBM Information Management
control block with the Informix EXCEPTION construct. Therefore, Oracle procedure code must be
restructured to manipulate these exceptions.
In Oracle, an exception can be raised globally and acted upon globally. In Informix, the scope of
an exception mechanism is always restricted to the block in which it is located. This leads to the
addition of multiple Informix exception handling mechanisms for each Oracle exception raised as
well as a redesign of the overall stored procedure to a more blocked format.
Error handling
In Oracle, errors are processed as part of a function call return value. In Informix, errors are
retrieved as a separate function call that has multiple structures that have to be created in order to
retrieve error and status.
The SQLCA structure is not fully available in Informix stored procedures. It is not possible to
check the SQLCODE variable in the stored procedure body. Instead, the function DBINFO can be
used to extract the value of two members of the SQLCA structure: sqlca.sqlerrd1 and
sqlca.sqlerrd2. This function should be used inside the FOREACH construct while the cursor is
open. Once the cursor is closed, the DBINFO function cannot return proper values.
The sqlca.sqlerrd1 option returns different values depending on the type of SQL statement. For
INSERT statements, if the table contains a serial column, then the sqlca.sqlerrd1 option will return
the serial value of the last row inserted into the table. For SELECT, DELETE, and UPDATE
statements the sqlca.sqlerrd1 option will return the number of rows processed by the query. In
these cases, upon each pass through the FOREACH loop, sqlca.sqlerrd1 is the same value: the
number of rows the FOREACH loop will process. The sqlca.sqlerrd1 value can still be interrogated
during each pass through the FOREACH loop.
The sqlca.sqlerrd2 option returns the number of rows processed by a SELECT, INSERT,
UPDATE, DELETE, or EXECUTE PROCEDURE statement. It should not be interrogated until
after the cursor has finished processing. In other words, within the FOREACH loop, the
sqlca.sqlerrd2 value can be moved to a variable which is then interrogated outside of the
FOREACH loop.
Cursors
Unlike Informix, in Oracle, cursors can be global to a package. In Informix, Oracle’s global cursors
can be replaced with temporary tables. A temporary table can be created and populated in place
of where the cursor is opened. The temporary table can then be processed the same way the
cursor is processed. Finally, the temporary table should be dropped in place of where the cursor is
closed.
Cursors are explicitly declared, opened and fetched in Oracle stored procedures. In Informix,
cursors do not need to be explicitly declared, opened and fetched in stored procedures. Instead,
Oracle stored procedure cursors can be replaced with Informix’s FOREACH construct. The
Oracle cursor name should be used in the FOREACH statement, for example: FOREACH
cursor_name SELECT … END FOREACH.
In order to update a cursor row in Oracle, the cursor must be declared with the FOR UPDATE
clause. In Informix, if the SELECT statement in the FOREACH construct is not a multi-table join,
then each fetched row can be updated using the UPDATE <table_name> WHERE CURRENT OF
<cursor_name> statement. See the Update Using Cursors section in “Data Manipulation
Language” for more information. Informix does not support the SELECT FOR UPDATE statement
in a stored procedure. Therefore, the SELECT FOR UPDATE clause cannot be used in the
FOREACH construct.
Version 1.6
52
IBM Software Group
IBM Information Management
Variable declaration and assignment
Oracle allows implicit variable definitions within a FOR loop. The variables are defined using an
assignment operator and a column name. For example:
out_customer_name := customer.name;
The variable out_customer_name is defined as the same type as the column name in the
customer table.
Informix requires that all variables be defined at the beginning of each stored procedure control
block. For example:
DEFINE out_customer_name LIKE customer.name;
DEFINE counter INTEGER;
Therefore, Oracle’s implicit variable declaration must be replaced with Informix’s explicit variable
declaration before the control block.
Additionally, assignment operations will need to be ported. Oracle uses a colon and an equal sign
(:=) for assignment while Informix utilizes the LET keyword in combination with an equal sign (=)
(i.e. LET var = 1). Therefore, assignment statements must be modified with the LET keyword and
an equal sign.
Boolean
Oracle’s BOOLEAN variable type can be replaced with Informix’s BOOLEAN data type.
Binary data types
Binary data types are very different between Oracle and Informix. In Oracle, the binary type is
defined as a type RAW and is explicitly defined with a maximum length as part of the declaration.
In Informix, the binary type is defined as REFERENCES BYTE, which deals only with pointers to
BLOBs. It implicitly defines a maximum length as part of the function call in which the pointer to
the BLOB and maximum length (as used in the function call) was passed as values. As a result
the binary type cannot be assigned a binary value in a stored procedure nor can it be inserted into
a table via the SQL INSERT statement in a stored procedure. These operations that initialize a
binary type must be performed outside of stored procedures.
Dynamic SQL
Unlike Oracle, Informix does not support dynamic SQL within the Stored Procedure Language. In
other words, a statement such as SELECT variable_name FROM variable_name WHERE
variable_name is not supported. This kind of processing can be achieved in Informix within an
embedded SQL program. This requires that either the Oracle stored procedure be converted to an
embedded SQL program, or just the Dynamic SQL portion be placed in an embedded SQL
program and then called from within the stored procedure. The latter option will have performance
implications since calling an embedded SQL program from a stored procedure requires an
operating system call.
Another option is to use the Informix EXEC Bladelet. The EXEC Bladelet consists of user-defined
functions that take a SQL query as an argument, execute it, and return a result (the format of
which varies depending on the function and the kind of query). The EXEC Bladelet functions can
handle most Data Definition Language (DDL) statements, and all Data Manipulation Language
(DML) queries. Further details can be found in Chapter 7: Using Bladelets.
Compiler
Unlike Oracle, the Informix compiler was developed with the concept that developers can create
stored procedures independently of the database. Therefore, Informix’s stored procedure
Version 1.6
53
IBM Software Group
IBM Information Management
compiler has a limited set of errors that it checks compared to Oracle’s. For example, the Informix
stored procedure compiler does not validate database object names such as table, column, and
view names. Therefore, database object naming errors will occur at runtime, not compile time.
Additionally, the error messages generated from the compiler are not very specific. Identifying a
problem in a stored procedure may require breaking it apart and recompiling the pieces until the
problem is found. This may impact the time necessary to unit test the stored procedures.
Triggers
Oracle supports the use of multiple trigger events, for example, insert, update, and delete within
the same trigger. Informix only supports one trigger event per trigger. In Informix, the Oracle
trigger body in this example must be copied into three different triggers each with only one event.
Informix triggers have some constraints; Oracle’s do not. In Informix, if a trigger is fired due to
inserting a row into a table, a trigger can only act on any rows or columns within that table using
the EXECUTE PROCEDURE … INTO syntax. Similarly, if a trigger is fired due to updating a row,
then the trigger can only act on the column that caused the trigger to fire using the EXECUTE
PROCEDURE … INTO syntax. Like Oracle, if a trigger is fired due to deleting a row, there are no
restrictions.
Prior to IDS 7.3 when a trigger was fired on an INSERT/UPDATE action, no modification could be
done to the columns (in the row) which just fired the trigger. The reentrant UPDATE/INSERT
triggers feature introduced with IDS 11.10 enables users to update the triggering columns by
using the EXECUTE PROCEDURE ... INTO syntax. Additionally, the feature enforce that this
action will not cause any additional triggers to be fired (same or different trigger) causing a
cascading of triggers and potentially an infinite loop.
The following example demonstrates how the reentrant UPDATE/INSERT trigger feature is used:
create table foo
(
x int default NULL,
y int default NULL,
z int default NULL
);
create procedure reentrant()
returning int;
return 56;
end procedure;
create trigger reentrant_trigger insert on foo for each row
(
execute procedure reentrant() into z
);
insert into foo values
(
1,
2,
3
);
The following SELECT will result in the following returned data:
select * from foo;
x
1
Version 1.6
y
2
z
56
54
IBM Software Group
IBM Information Management
Oracle allows SQL statements, logical statements, and stored procedure calls within a trigger
body. Informix allows only SQL statements and stored procedure calls within a trigger body.
Oracle triggers containing logical statements must be converted to Informix by moving their
contents into a stored procedure. The stored procedure should then be executed from the trigger.
Constraints
Constraints in both Oracle and Informix can be enabled and disabled within an application
transaction, however, there are behavioral differences. In Oracle, the application is always
executing within a transaction. In Informix, transaction boundaries are explicitly declared and care
should be taken to ensure that this functionality is performed within the boundaries of a
transaction. See the Transaction Processing section in CHAPTER 5: Application Architecture for
more information.
The constraint syntax available in Informix is:
SET {CONSTRAINTS/INDEXES/TRIGGERS} FOR table_name
{ENABLED|DISABLED}
SET CONSTRAINTS comma_separated_constraint_names
{ENABLED|DISABLED}
SET INDEXES comma_separated_index_names {ENABLED|DISABLED}
SET TRIGGERS comma_triggers_constraint_names {ENABLED|DISABLED}
SET CONSTRAINTS {ALL/constraint_name} {IMMEDIATE|DEFERRED}
The first four statements must be executed with DBA privileges if placed in the application.
Therefore, care should be taken when using them. Note that the last statement contains a
DEFERRED clause. This is the statement used if the users of the application do not have DBA
privileges. When the constraint is set with the DEFERRED clause, the specified constraints are
not checked until the transaction is committed. If a constraint violation occurs while the transaction
is being committed, the transaction is rolled back.
DUAL table
Oracle’s DUAL table is a system table with only one row containing one column named DUMMY.
This table is used to complete the syntax of an SQL statement that does not involve an existing
table such as:

A SELECT statement which assigns some constant value (which can only be derived
in an SQL statement) to a host variable:
SELECT TO_CHAR(SYSDATE) INTO :date_var FROM DUAL;

A SELECT statement which assigns a value of another variable to a variable:
SELECT :source_var INTO :dest_var FROM DUAL;

A SELECT statement which unions application host variable values with another
SELECT statement to return a result containing a row of application variable values:
SELECT col1, col2, col3 FROM table_name
UNION
SELECT :host_var1, :host_var2, :host_var3 FROM DUAL;
Converting Oracle’s DUAL table functionality to Informix depends on the way it is used.
Converting statements that just assign constants is as simple as replacing the DUAL statement
with an Informix assignment statement.
The solutions below apply to Informix versions prior to 11. At 11 and above, the concept of a
DUAL table, as well as sysdate, is supported:
Version 1.6
55
IBM Software Group
IBM Information Management
SELECT sysdate FROM sysmaster:sysdual;
If you want a dual table in your local database, then create the following synonym. The
sysmaster:sysdual table is much faster than a physical table in your database because it is an inmemory pseudo table.
CREATE SYNONYM dual FOR sysmaster:sysdual;
If you are restricted to using a version of Informix prior to 11, then the following solutions can be
used.
A dummy table can be created to mimic the behavior of simple SELECT INTO statements used to
assign values to variables.
CREATE TABLE dual (dummy VARCHAR(1));
INSERT INTO dual VALUES(‘X’);
An alternate solution to widespread use of the DUAL table could be creating a permanent view
that is generally accessible.
CREATE VIEW dual (d) as SELECT 'X'
FROM systables WHERE tabid = 1;
The exact definition could be used or modified as needed, but this would solve the problem of
having DUAL be permanent, usable by anyone, and not modifiable.
Version 1.6
56
IBM Software Group
CHAPTER 5:
IBM Information Management
Embedded SQL
Oracle’s embedded SQL products are Pro*C and Pro*COBOL. Informix’s corresponding
embedded SQL products are ESQL/C and ESQL/COBOL.
Host variables
Declaration override
The Oracle EXEC SQL VAR declarative statement (host variable equivalency of Oracle external
data types by overriding the default assignment) can be converted to an Informix explicit
declaration statement. For example:
Oracle:
char char_var[20];
EXEC SQL VAR char_var IS STRING(11);
Informix:
char char_var[11];
Note that the size and type used in the EXEC SQL VAR section is the final information required to
declare the host variable in Informix.
Arrays
Oracle arrays are not subscripted in SQL statements since it is not required to process the host
arrays in a loop in the SQL statement. In Informix, subscripting is mandatory. In Oracle, if an array
is defined of size 200 then an SQL statement would be:
EXEC SQL FETCH CURSOR-NAME INTO
:VAR-A,
:VAR-B,
:VAR-C
END-EXEC
-orEXEC SQL SELECT COL1, COL2, COL3
INTO
:VAR-A,
:VAR-B,
:VAR-C
FROM TABLE1
WHERE COL2 > 100
END-EXEC
where VAR-A, VAR-B and VAR-C are each an array of say 200.
Version 1.6
57
IBM Software Group
IBM Information Management
In Informix, the first example would be converted to:
PERFORM VARYING LOOP-CTR FROM 1 BY 1 UNTIL
LOOP-CTR IS GREATER THAN 200
EXEC SQL FETCH CURSOR-NAME INTO
:VAR-A(LOOP-CTR),
:VAR-B(LOOP-CTR),
:VAR-C(LOOP-CTR)
END-EXEC
IF SQLCODE = 100
GO TO EXIT-PERFORM
END-IF
END-PERFORM
EXIT-PERFORM.
For the second Oracle example given above, a cursor must be declared in Informix, opened, and
fetched for 200 rows or less (less, because there may be less than 200 qualifying rows) into the
host array and then should be closed. If the number of qualifying rows is more than 200, then the
extra rows must be ignored to duplicate the Oracle functionality. But for the first example, each
fetch in Oracle will return the next 200 or less number of rows. Therefore, each Oracle fetch
needs to be replaced by another call to the Informix fetch loop. Oracle also uses this method for
inserts, deletes and updates. These array techniques are mainly used in batch SQL processing.
Formatting
In Informix, when a DECIMAL, MONEY, DATE, or DATETIME value is selected into a host
variable of the same data type, the value must be formatted using the available Informix
formatting routines before they can be printed or displayed. For example:
…
dec_t
dec_host_var;
char
formatted_dec[40];
EXEC SQL SELECT DEC_COLUMN INTO :dec_host_var FROM TABLE_NAME;
rfmtdec(&dec_host_var, “&&&&&&&.&&&”, formatted_dec);
printf(“The Decimal Value is %s\n”, formatted_dec);
…
Version 1.6
58
IBM Software Group
IBM Information Management
Informix supplies many formatting functions and formatting strings. The names of these functions
are different in Informix ESQL/C and ESQL/COBOL, but the functionality is the same. Refer to the
appropriate Informix API Programmer’s Manual (Informix-ESQL/C Programmer’s Manual or
Informix-ESQL/COBOL Programmer’s Manual) for more information.
SQL structures
SQLCA
Oracle’s SQLCA structure is different from that of Informix., However, the components of both
structures are logically the same. Oracle’s SQLCA components can be replaced with the
corresponding Informix components.
Oracle’s SQLCA structure:
SQLCAID
SQLCABC
SQLCODE
SQLERRM
SQLERRML
SQLERRMC
SQLERRP
SQLERRD
SQLERRD(0)
SQLERRD(1)
SQLERRD(2)
SQLERRD(3)
SQLERRD(4)
SQLERRD(5)
SQLWARN
SQLWARN(0)
SQLWARN(1)
SQLWARN(2)
SQLWARN(3)
SQLWARN(4)
SQLWARN(5)
SQLWARN(6)
SQLWARN(7)
SQLTEXT
Version 1.6
string containing “SQLCA”
length of SQLCA data structure
Oracle error message code
sub-record for error message
length of error message
text of error message
reserved for future use
array of six-integer status codes
reserved for future use
reserved for future use
number of rows processed
reserved for future use
parse error offset
reserved for future use
array of eight warning flags
another warning flag set
character string truncated
no longer in use
SELECT list not equal to INTO list
DELETE or UPDATE without WHERE clause
reserved for future use
no longer in use
no longer in use
reserved for future use
59
IBM Software Group
IBM Information Management
Informix’s SQLCA structure:
SQLCODE
SQLERRM
SQLERRP
SQLERRD
SQLERRD(0)
SQLERRD(1)
SQLERRD(2)
SQLERRD(3)
SQLERRD(4)
SQLERRD(5)
SQLWARN
SQLWARN0
SQLWARN1
revoked
SQLWARN2
SQLWARN3
end
SQLWARN4
SQLWARN5
SQLWARN6
SQLWARN7
Informix error code
error message parameter
reserved for future use
array of six-integer status codes
estimated number of rows returned
serial value of INSERT or ISAM error code
number of rows processed
estimated cost
parse error offset
ROWID after INSERT
structure of eight warning flags
another warning flag set
character string truncated or no privileges
NULL value returned or ANSI database
SELECT list not equal to INTO list or turbo backDELETE or UPDATE without WHERE clause
if non-ANSI statement
if server is in data replication secondary mode
reserved
In order to get Oracle error messages, an application normally uses the SQLCA element
SQLERRMC. The Informix equivalent is SQLERRM. On the HP/UX and Solaris platforms, the
Informix function rgetmsg should be used instead of the element SQLERRM. At the time of this
writing, using SQLERRM would cause an error on the HP/UX and Solaris platforms.
SQLDA
The implementation of Oracle’s SQLDA structure is very different from that of Informix. Significant
changes are necessary to convert Oracle’s functionality to Informix. Oracle’s sqlald function can
be replaced with Informix’s ALLOCATE DESCRIPTOR statement. Since Oracle’s and Informix’s
SQLDA structures are so different, Oracle’s SQLDA logic must be rewritten with the more
powerful Informix SQLDA logic or alternatively, the Informix system-descriptor area logic.
Oracle’s SQLDA Structure:
N
maximum number of SELECT list items or placeholders
V
pointer to array of address of SELECT list items or bind variables
L
pointer to array of lengths of SELECT list items or bind variables
T
pointer to array of data types of SELECT list items or bind variables
I
pointer to array of addresses of indicator variable values
F
actual number of SELECT list items or placeholders
S
pointer to array of addresses of SELECT list items or placeholder names
M
pointer to array of max lengths of SELECT list items or placeholder
names
C
pointer to array of current lengths of SELECT list items or placeholder
names
X
pointer to array of addresses of indicator variable names
Y
pointer to array of maximum lengths of indicator variable names
Z
pointer to array of current lengths of indicator variable names
Version 1.6
60
IBM Software Group
Informix’s SQLDA Structure:
SQLD
SQLVAR
SQLDATA
SQLTYPE
SQLLEN
SQLIND
SQLNAME
SQLFORMAT
SQLIDATA
SQLITYPE
SQLILEN
IBM Information Management
count of the following SQLVAR members
pointer to array of structures
pointer to actual data
data type of placeholder or SELECT item
length of the placeholder or SELECT item
pointer to the indicator
pointer to placeholder or SELECT item name
reserved
indicator data pointer
indicator variable type
length of indicator variable
If an Oracle application uses the simple dynamic SQL method using macros only, not the SQLDA
structure directly, the value indicators/placeholders can be replaced with a ‘?’ in Informix. For
example:
Oracle:
sprintf(sqlstring, “INSERT INTO TABLE1 VALUES (:v1, :v2)”);
Informix:
sprintf(sqlstring, “INSERT INTO TABLE1 VALUES (?, ?)”);
ORACA
Oracle’s ORACA structure is not supported by Informix. This structure is used to handle Oracle
specific communication and more runtime information than SQLCA. Oracle statements containing
references to this structure should be removed from the application.
Pre-compiler options
The Oracle options beginning with the EXEC ORACLE OPTION statement can be removed from
the application. The options set after this statement do not affect the application logic. They may
affect some application performance only.
Embedded PL/SQL
Oracle allows procedure language (PL/SQL) blocks inside Pro*C and Pro*COBOL code delimited
by the EXEC SQL EXECUTE and END-EXEC statements. In Informix, these blocks must be
replaced with the equivalent ESQL/C or ESQL/COBOL code.
Oracle Call Interface
Oracle call interface (OCI) is the base layer for a variety of other application programming
interfaces such as JDBC-OCI, Oracle Precompilers, and Oracle ODBC. It is also used directly by
customers who are willing to develop their code using a lower level, proprietary API. From a high
level, it can be thought of as if IBM Informix had standardized and published the function calls in
the ESQL/C library. Although some customers have reverse engineered these calls and
developed applications using them, this is generally discouraged because there is no guarantee
that the library of calls will not change. There is no direct equivalent to this Oracle API in Informix.
Migrating applications written using Oracle Call Interface (OCI) will require rewriting the code from
scratch. OCI is native to the C language and so it should be less effort to migrate the application
to an Informix API that is also native to C. This could be ESQL/C or CLI. The following information
explains differences between Oracle OCI and Informix ODBC.
Version 1.6
61
IBM Software Group
IBM Information Management
The following table is an approximate mapping of the differences between the Informix CLI and
Oracle OCI function calls in which there is not a direct one-to-one mapping:
Buffer Areas
Connect and allocate
resources
Oracle
HAD, LDA, CDA
OLOG, OOPEN
Update, delete, insert, select
OPARSE, OBNDRV, OEXEC
Select
Commit, Rollback
Disconnect
ODEFIN, OFETCH
OCOM, OROL
OLOGOF, OCLOSE
Informix
HENV, HDBC, HSTMT
SQLConnect, SQLAllocEnv,
SQLAllocConnect,
SQLAllocStmt
SQLPrepare,
SQLBindParameter,
SQLExecute
SQLBindCol, SQLFetch
SQLTransact
SQLDisconnect, SQLFreeStmt,
SQLFreeConnect,
SQLFreeEnv
Database library calls
One of the first main differences between Informix CLI and Oracle OCI calls is the overall data
structures and mechanisms used to process database library calls. Oracle uses direct
connections to the database server. Informix uses an ODBC connection to the database server.
As a result, the Informix calls will be implemented as ODBC SQL calls utilizing three tiers of
increasing SQL levels of complexity.
Global area processing
Another main difference between Informix CLI and Oracle OCI is Informix’s use of pointers to
three global areas versus Oracle’s use of pointers to three different, but similar, global areas.
Hence, the Oracle OCI calls that utilize HAD (Handle Data Area), LDA (Logon Data Area) and
CDA (Cursor Data Area) pointers must be translated over to Informix CLI calls that utilize HENV
(Environment Area), HDBC (Database Connection Area) and HSTMT (Statement Area) pointers,
respectively, in conjunction with an ODBC interface.
Fetch cycle
Another difference between Informix CLI and Oracle OCI calls is that the overall fetch cycle is
different for each and must be modified accordingly. In Oracle, the fetch cycle for selecting
multiple rows utilizing a cursor area involves parsing, binding, defining, fetching, and then
executing into a cursor data area. These must be translated to a cycle that involves preparing,
binding, executing, binding, and then fetching via the “For Each” cycle.
RAW binary data type processing
RAW binary data types in Oracle will need to be translated to a pointer-to-BLOB REFERENCES
BYTE type in Informix. See the Binary Data Types subsection of the Stored Procedures section in
CHAPTER 3:
Parameter bindings
In Oracle, multiple output bindings of parameters are declared as type “OUTPUT” in the
ODEFIN() calls. In Informix, convert the calls to Informix SQLBindCol() calls and bind the output
parameters as columns.
Differences also exist between Informix CLI and Oracle OCI in the use of input/output bindings. In
Oracle, these bindings are declared as type “INPUT/OUTPUT” in the ODEFIN() calls. In Informix,
a “round robin” approach is used using three variables in the following manner: A=B, B=C, C=A.
A variable (A) is declared before the SQL bindings as an input variable. The function is called
Version 1.6
62
IBM Software Group
IBM Information Management
using a second input variable (B) that is set to the first input variable (A). The function returns a
third variable (C) that is bound as an output column. Finally, the first variable (A) is now set to the
returned third variable (C) that made the first variable (A) appear as an “input/output” variable to
the rest of the program.
Embedded SQL for C
VARCHAR
Oracle’s Pro*C VARCHAR data type is expanded after pre-compiling into a structure with two
elements, one is unsigned short len and the other is unsigned char arr[size]. The
name of the expanded structure is the same name as the VARCHAR variable and size is
replaced with the size of the VARCHAR variable. In Informix, the VARCHAR data type is just a
synonym for the C language’s char data type. Therefore, statements that use
variable_name.len can be removed from the application and all occurrences of
variable_name.arr can be replaced with variable_name. For example:
Oracle:
VARCHAR vName[40];
strcpy(vName.arr, “Company Name”);
vName.len = strlen(vName.arr);
Informix:
VARCHAR vName[40];
strcpy(vName, “Company Name”);
Host variables
The Oracle statement EXEC SQL TYPE is synonymous with the C language’s typedef declarative
instruction. It can be easily replaced with the Informix declarative instruction typedef.
Embedded SQL for COBOL
VARCHAR
Oracle’s Pro*COBOL character host variable declaration statement’s VARYING clause is
expanded after pre-compiling into a group with two elements, one is variable-name-LEN PIC
S9(4) COMP and the other is variable-name-ARR PIC X(size). The group name is the
same as the host variable name and size is replaced with the size of the VARYING variable.
Informix does not support this concept. Therefore, statements that use variable-name-LEN
must be removed from the application and all occurrences of variable-name-ARR must be
replaced with variable-name. Also, the VARYING clause must be removed from the
declarative statement. For example:
Oracle:
05 vName PIC X(40) VARYING.
…
MOVE “Company Name” TO vName-ARR.
MOVE 12 TO vName-LEN.
Informix:
05 vName PIC X(40).
…
MOVE “Company Name” TO vName.
Version 1.6
63
IBM Software Group
IBM Information Management
Level 88
COBOL’s level 88 functionality is not supported within an Informix ESQL/COBOL host variable
declaration section in versions prior to 7.2. Level 88 functionality is supported in Informix
ESQL/COBOL 7.2.
SQLDA
In Informix ESQL/COBOL, the SQLDA structure is not available. The Informix macros, such as
ALLOCATE DESCRIPTOR, DESCRIBE, GET DESCRIPTOR, and SET DESCRIPTOR must be
used to retrieve and manipulate the SQLDA data.
REDEFINES
Oracle supports the use of the REDEFINES clause at the elementary level in the host variable
declaration section. In other words, the redefined item cannot be a group item but the redefining
item may be a group item. Informix does not support the use of the REDEFINES clause in the
host variable declaration section in versions prior to 7.2. The REDEFINES clause is supported in
Informix ESQL/COBOL 7.2.
Tips
If the Informix pre-compiler finds an SQL statement within an IF [ELSE IF … ] END-IF or
EVALUATE END-EVALUATE or PERFORM END-PERFORM block, then the pre-compiler adds a
period after the generated COBOL statements regardless of whether there is a period at the end
of the SQL statement. This is a violation of COBOL rules for such blocks and the code may cause
syntax errors during compilation, or may behave unexpectedly. To avoid these problems, each
SQL statement group should be moved to a new paragraph and these paragraphs should be
performed from the block from which they were moved.
ODBC
Although the Open Database Connectivity (ODBC) API is designed to make it possible to write
and compile an application once and use it with any ODBC driver on the same platform, there are
frequently differences between the underlying DBMSs that can expose problems to the
applications. For instance, there can be differences between how unspecified parts of a date-time
value are filled. Most of these kinds of differences that get exposed through ODBC have their
origins in the differences between the DBMSs themselves. There are also cases where there are
gaps in the ODBC standard; for example, there is a standard ODBC call that allows the
application to ask the driver if it can support scrollable cursors, and there is another call to ask if it
can support updateable cursors. There is no call to ask if it can support both at the same time.
With Informix, you can have a scrollable cursor and you can have an updateable cursor, but you
can not have one cursor that is both scrollable and updateable. A more complete description of
ODBC application migration issues is beyond the scope of this article.
Version 1.6
64
IBM Software Group
CHAPTER 6:
IBM Information Management
Application Architecture
Transaction processing
Transaction boundaries are defined differently in Oracle and Informix. Oracle’s transactions begin
implicitly in one of two ways, either by issuing a CONNECT statement or issuing a COMMIT or
ROLLBACK statement. A CONNECT statement marks the beginning of a transaction and a
COMMIT or ROLLBACK statement commits or rolls back the previous transaction, respectively,
and then implicitly begins a new transaction. CONNECT statements are usually issued once at
the beginning of a program; however, they may be nested or issued more than once serially to
connect to the same or a different database. When using more than one CONNECT statement
within a program, each CONNECT statement must be named. This marks the beginning of
named transactions. Every SQL statement within a named transaction must also be named with
the same transaction name as the CONNECT statement at where the SQL is to be executed.
SQL is named using the EXEC SQL statement’s AT clause.
Informix’s transaction boundaries are explicitly marked with the reserved words BEGIN WORK
and COMMIT WORK or ROLLBACK WORK. Note that once a transaction has begun for a given
connection, it stays open until a COMMIT or ROLLBACK is executed. In other words, if an ESQL
program begins a transaction and then calls a stored procedure, the stored procedure executes
within the same transaction. If the stored procedure issues a COMMIT, then the whole transaction
is committed and the calling ESQL program should not issue a COMMIT or ROLLBACK.
Informix transactions can be written to behave the same way as Oracle’s. To simulate Oracle’s
CONNECT statement behavior, an Informix CONNECT should also be issued followed by a
BEGIN WORK statement. If more than one CONNECT statement is used in a program, Informix
also requires that the CONNECT and SQL statements be named. To simulate Oracle’s COMMIT
and ROLLBACK statement behavior, an Informix COMMIT WORK or ROLLBACK WORK
statement should be issued followed by a BEGIN WORK statement. Nested transactions can be
simulated in Informix with the CONNECT statement and naming the transactions. Then the
Informix SET CONNECTION connection_name statement can be used to switch between
transactions. Committing or rolling back each named transaction does not commit or roll back
other active transactions.
The Oracle statement EXEC SQL {COMMIT/ROLLBACK} RELEASE should be replaced with the
Informix statements EXEC SQL {COMMIT/ROLLBACK} [WORK] followed by EXEC SQL
DISCONNECT CURRENT.
In the following examples, ws-dbenviron is the database name, ws-connect-nm is the user name
and ws-identity-nm is the password set in the program, enp and connection-name are the
connection names. For Informix, the user name and password information should correspond to
the entries in the /etc/passwd file on the UNIX system. See the User Authentication section later in
this chapter for more information. The default server name is automatically obtained from the
environment variable INFORMIXSERVER. The following examples illustrate how Oracle and
Informix implement the CONNECT functionality.
Version 1.6
65
IBM Software Group
IBM Information Management
Simple Connect
Oracle:
CONNECT :ws-connect-nm IDENTIFIED BY :ws-identity-nm
Informix:
CONNECT :ws-dbenviron USER :ws-connect-nm USING :ws-identity-nm
Named Connect with Literal
Oracle:
DECLARE enp DATABASE
…
CONNECT :ws-connect-nm
IDENTIFIED BY :ws-identity-nm
AT enp USING :ws-dbenviron
…
AT enp SELECT col1, col2 INTO :var1, :var2
FROM table_name
Informix:
CONNECT TO :ws-dbenviron
AS “enp”
USER :ws-connect-nm USING :ws-identity-nm
WITH CONCURRENT TRANSACTION
…
SET CONNECTION “enp”
…
SELECT col1, col2 INTO :var1, :var2
FROM table_name
Named Connect with Variable
Oracle:
CONNECT :ws-connect-nm
IDENTIFIED BY :ws-identity-nm
AT :connection-name USING :ws-dbenviron
…
AT :connection-name SELECT col1, col2 INTO :var1, :var2
FROM table_name
Informix:
CONNECT TO :ws-dbenviron
AS :connection-name
USER :ws-connect-nm USING :ws-identity-nm
WITH CONCURRENT TRANSACTION
…
SET CONNECTION :connection-name
…
SELECT col1, col2 INTO :var1, :var2
FROM table_name
Autonomous Transaction
An autonomous transaction is an independent transaction that is initiated by another transaction
(the parent transaction). An autonomous transaction can modify data and commit or rollback
independent of the state of the parent transaction.
The autonomous transaction must commit or roll back before the autonomous transaction is
ended and the parent transaction continues.
Version 1.6
66
IBM Software Group
IBM Information Management
An autonomous transactions has been available since the release of Oracle 8i.
An autonomous transaction is defined in the declaration of a PL/SQL block. This can be an
anonymous block, function, procedure, object method or trigger.This is done by adding the
statement 'PRAGMA AUTONOMOUS_TRANSACTION;' anywhere in the declaration block.
There isn't much involved in defining a PL/SQL block as an autonomous transaction. You simply
include the following statement in your declaration section:
PRAGMA AUTONOMOUS_TRANSACTION;
Sample code:
PROCEDURE test_autonomous
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
insert ....
commit;
END test_autonomous;
Autonomous transactions can be used for logging in the database independent of the
rollback/commit of the parent transaction.
Savepoints
Oracle allows savepoints within its PL/SQL. For example, a PL/SQL block can be structured so
that SAVEPOINT A is issued upon entry and SAVEPOINT B is issued after some processing.
Then, after some more processing, a COMMIT or ROLLBACK can be issued against all the logic
since the last COMMIT point, which is before the PL/SQL block, or up to any of the savepoints, by
naming the COMMIT or ROLLBACK with the savepoint name. In other words, a savepoint can be
issued at the beginning of a stored procedure and then only the stored procedure logic can be
committed without committing the changes pending before the stored procedure was executed.
Those changes can be committed or rolled back once processing is returned from the stored
procedure. Informix does not support savepoint processing within a stored procedure.
Concurrency
Database concurrency can be managed through the combination of two configurable settings; one
specifies the lock granularity on database objects while the other influences how the application
behaves in regards to the presence and placement of locks using a transaction isolation level.
Row Level Locking
Oracle and Informix implement locking differently on database objects. Oracle defaults to row
level locking whereas Informix defaults to page level. In most cases, row level locking is preferred
to improve concurrency.
Informix supports row level locking however it must be either explicitly requested, specified by an
environment variable or permanently changed in the instance’s configuration. Having three
methods for establishing the lock level there is an order of precedence:
1. To be explicitly requested the CREATE TABLE statement must include the specification
of the LOCK MODE attribute:
CREATE TABLE emp (
name CHAR(40),
salary MONEY,
ssn LVARCHAR(64)
) LOCK MODE ROW;
Version 1.6
67
IBM Software Group
IBM Information Management
2. The environment variable IFX_DEF_TABLE_LOCKMODE will establish the default for
CREATE TABLE statements issued without the LOCK MODE attribute and will override
the Instance’s configuration setting. The variable setting on the client will override the
server environment setting.
set IFX_DEF_TABLE_LOCKMODE=ROW
-or-
export IFX_DEF_TABLE_LOCKMODE=ROW
3. Informix allows the instance’s lock level default to be changed using a configuration
parameter. Row level locking can be as the default by adding the parameter
DEF_TABLE_LOCKMODE to the instance’s ONCONFIG file. This parameter may not be
found in the existing file and if not present can be added using an editor and establish a
new default setting of ROW:
DEF_TABLE_LOCKMODE
ROW
None of the steps will apply a change to existing tables only establish the lock level for the
CREATE TABLE statement.
Transaction Isolation Level
Oracle databases incorporate a feature known as “read consistency” which allows a query return
a result based on the state of the data when the query started, regardless of other processes
updating or deleting the same data while the query is running. Informix facilitates this type of
behavior differently, by providing control of the application’s placement of locks as well as how it
reacts to those placed by other processes through the use of the transaction’s isolation level.
If Oracle’s technique of “readers not blocking writers” is a requirement, then in many circumstance
Informix’s DIRTY READ isolation level can be used. The readers will not block the writers with
dirty read processing; however, the query result may contain updates performed while the query
was running which may be uncommitted.
If the emulation of Oracle’s “read consistency” is desired, the LAST COMMITTED option of
Informix’s COMMITTED READ isolation level can reduce the risk of locking conflicts when two or
more sessions attempt to access the same row in a table whose locking granularity is row-level.
When an application attempts to read a row on which another session holds an exclusive lock,
these keywords instruct the database server to return the most recently committed version of the
row, rather than wait for the lock to be released. This isolation level attribute could be preferable to
executing queries using DIRTY READ since it will return only the most recently committed
versions of the data.
The LAST COMMITTED option can be enabled in the following ways:
1. Setting the USELASTCOMMITTED parameter in the Instance’s configuration
(ONCONFIG) will apply this feature as the default isolation level to all database
transactions. The parameter‘s values will designate the scope of applying the LAST
COMMITED option to either ALL, NONE or only COMMITED READ and DIRTY READ
isolation levels.
USELASTCOMMITTED
[ALL | NONE | COMMITTED READ | DIRTY READ]
2. The SET ENVIRONMENT statement can override the USELASTCOMMITTED
configuration parameter setting for the duration of the current session. The same
semantics apply as the parameter within the ONCONFIG file with the setting value
enclosed in quotes (‘).
SET ENVIRONMENT USELASTCOMMITTED ‘ALL’;
Version 1.6
68
IBM Software Group
IBM Information Management
3. The SET ISOLATION statement can be used to override the instance configuration and
session environment setting. The SET ISOLATION statement is an Informix extension to
the ANSI SQL-92 standard and provides the same functionality as the ISO/ANSIcompliant SET TRANSACTION statement. There is no support for the LAST
COMMITTED option with the SET TRANSACTION statement. SET TRANSACTION
complies with ANSI SQL-92 and only ANSI supported isolation levels are supported.
SET ISOLATION TO COMMITTED READ LAST COMMITTED;
4. PREPARE statements in ODBC/JDBC applications
This feature is primarily documented in the Guide to SQL: Syntax, Guide to SQL: Reference,
Administrator's Reference, and Administrator's Guide.
Version 1.6
69
IBM Software Group
CHAPTER 7:
IBM Information Management
Security
User authentication
In Oracle security information is stored in the database. Up until recently Informix has used only
the operating system security subsystem to check security. For security purposes Oracle
connects to the server and passes the user ID and password information to the database for
verification.
Operating system security
Informix does not store user ID and password information in the database. Instead they are
validated against the operating system’s security mechanism on the server, for example the
/etc/passwd file in UNIX. Therefore, either every database user must have an entry in the server’s
password file, or the application must handle a level of security where user IDs are converted into
a group id based on database permissions and only those group IDs are entered into the
password file. Note that if the second alternative is chosen, then auditing capabilities based on
user ID are lost. Also, if the application performs security functions, then those functions are not
applicable to third party applications, such as report writers, application development tools, and so
on, when they access the database. The home directory of all the users should point to the same
physical directory where the application executable resides.
The Informix method of using the operating system for security checking allows external programs
to be called from within stored procedures. This capability is not allowed in Oracle.
In Oracle, the OPS$User_name is sometimes used to connect to the database where
OPS$User_name is a valid Oracle user and User_name is a valid operating system level user. In
this case, the connection is made to the database using just the ‘/’ character without the user id
and password. Informix’s technique of using the /etc/passwd file for security works fine for this
type of connection.
Non-operating system security
In previous releases, each user who needed to access the database server also needed an
operating system account on the host computer. Now you can configure Informix so that users
who are authenticated by an external authentication service (such as Kerberos or Microsoft Active
Directory) can connect to Informix. The new USERMAPPING configuration parameter specifies
whether or not such users can access the database server, and whether any of those users can
have administrative privileges. When Informix is configured to allow user mapping, you can still
control which externally authenticated users are allowed to connect to Informix and their
privileges. Please refer to the IBM Informix documentation on connection security for more
information.
Version 1.6
70
IBM Software Group
IBM Information Management
Informix supports for the pluggable authentication module (PAM) framework, which lets an
administrator customize authentication for individual applications, and permits column-level
encryption.
Role based authority
Role based authority can help you manage your database permissions. As of version 11.10, you
can create a role and assign that as a default role for individual users (or to PUBLIC). A role is a
work-task classification, such as “payroll” or “manager”. Each defined role has privileges on the
database object granted to the role. You use the CREATE ROLE statement to define a role and
GRANT DEFAULT ROLE to establish the user’s initial setting when connecting to the database.
A user’s role can be changed after connecting by using the SET ROLE statement.
Column-level encryption
You can use column-level encryption to improve the confidentiality of your data. IDS Version 11.10
has new built-in SQL scalar functions provide methods for data in columns to be stored in an
encrypted format. Use the ENCRYPT_AES or the ENCRYPT_TDES function to define encrypted
data. Use the DECRYPT_BINARY() and DECRYPT_CHAR() functions to query encrypted data.
When using the routines the encryption of data is under application control and the DBMS is not
aware that data is encrypted. Informix’s support of column level encryption is analogous to
Oracle’s DBMS Obfuscation Tool Kit.
Built-in ENCRYPT functions provide methods for encrypting and decrypting the following character
data types or smart large object data types:







CHAR
NCHAR
VARCHAR
NVARCHAR
LVARCHAR
BLOB
CLOB
Passwords and hints
Passwords are necessary when using the encryption functions. Only users who can provide a
secret password can view, copy, or modify encrypted data. The password must be a minimum of
6 bytes and can be a maximum of 128 bytes. When you set an encryption password, you have the
option of specifying a password hint. Hints can be up to 32 bytes of text. If you specify a hint, you
can store the hint with the encrypted password or in another location. Passwords (and hints) to be
used by default can be set for a session using the SET ENCRYPTION PASSWORD statement.
SET ENCRYPTION PASSWORD ‘password’ [ WITH HINT ‘hint string’ ];
Hence, the password and hint parameters can be optional when calling the encryption function.
Explicit values override the session default values.
The password or hint can be a single word or several words. The hint should be a word or phrase
that helps you to remember the password, but does not include the password. You can
subsequently execute the built-in GETHINT function (with an encrypted value as its argument) to
return the plain text of hint. Calling the GETHINT function with an argument of encrypted data will
return the hint (if any) from the encrypted data or an empty string (NULL) is no hint was provided.
There is no privilege needed, anybody can get any hint at any time.
When you set a password, Informix transfers the password and any hint to 128-bit key that is
used to encrypt the password and hint. Passwords and hints are not stored as plain text any table
of the system catalog. The key is a time-based random value per instance. The database server
Version 1.6
71
IBM Software Group
IBM Information Management
initializes the key when the server starts; the key is destroyed when the database server shuts
down.
Encrypting a column
Column data can be encrypted through the use of two functions, ENCRYPT_TDES and
ENCRYPT_AES, corresponding to the two data encryption standards; Triple Data Encryption
Standard (Triple-DES) and Advanced Encryption Standard (AES) which describes the cipher
algorithm used to protect data from unauthorized viewing. AES encryption (also known as
Rijndael) uses a 128-bit key size and Triple-DES encryption uses two 56-bit keys for 112-bits
overall. Both functions are variant functions and will return a different result every time it is used.
The following example demonstrates how to use the encryption functions with a column that
contains a social security number:
CREATE TABLE emp (name CHAR (40), salary MONEY, ssn LVARCHAR(64));
INSERT INTO emp
VALUES ('Alice', 50000, ENCRYPT_AES('123-456-7890','one two
three 123'));
-orCREATE TABLE emp (name CHAR(40), salary MONEY, ssn LVARCHAR(64));
SET ENCRYPTION PASSWORD "one two three 123";
INSERT INTO emp
VALUES ('Alice', 50000, ENCRYPT_AES('123-456-7890'));
Querying an encrypted column
Encrypted data can be translated using Informix’s DECRYPT_CHAR and DECRYPT_BINARY scalar
functions. Encrypted data contains information about the encryption method and all the other data
needed to decrypt it except the password. The encrypted data value is passed as the first
argument and a password as the second, unless the SET ENCRYPTION statement has specified
for this session with the same session password by which the first argument was encrypted. If the
data is not encrypted, the function call will return an error.
The DECRYPT_CHAR function is used to invoke a decryption routine on character data types (i.e.
CHAR, LVARCHAR, NCHAR, NVARCHAR and VARCHAR) while the DECRYPT_BINARY function
accepts an encrypted large object of type BLOB or CLOB.
If the first argument to DECRYPT_CHAR or DECRYPT_BINARY is not an encrypted value, or if
the second argument (or the default password specified by SET ENCRYPTION) is not the
password that was used when the first argument was encrypted, Informix will issue an error and
the call fails. If the call to the decryption function is successful, it returns the plain text version of
the encrypted data argument.
The following example demonstrates how to use the decrypt function to query encrypted data:
SELECT name, salary, DECRYPT_CHAR(ssn, ‘one two three 123’)
FROM emp
WHERE DECRYPT_CHAR(ssn) = ‘123-456-7890’;
-orSET ENCRYPTION PASSWORD ‘one two three 123’;
SELECT name, salary, DECRYPT_CHAR(ssn)
FROM emp
WHERE DECRYPT_CHAR(ssn) = ‘123-456-7890’;
The first argument to DECRYPT_BINARY is expected to be an encrypted value of a large object
data type however if it is called with a character data type Informix invokes the DECRYPT_CHAR
function and attempts to decrypt the specified value.
Version 1.6
72
IBM Software Group
IBM Information Management
Do not use either decryption function to create a functional index on an encrypted column. This
would store the decrypted values as plain text data in the database, defeating the purpose of
encryption.
Performance impact of encryption
The performance impact of encryption is significant. Encryption, by its nature, will slow down most
SQL statements. If some care and discretion are used, the amount of extra overhead should be
minimal. Also, encrypted data will have a significant impact on your database design. In general,
you want to encrypt a few very sensitive data elements in a schema, like social security numbers,
credit card numbers, patient names, and so on.
The effect on performance depends on direction: encrypting is slower than decrypting. It does not
depend measurably on which algorithm is used; AES performs at the same speed as Triple-DES.
It does depend on data size; the relative overhead is less when there is more data to encrypt.
Storage considerations
An encrypted value uses more storage space than the corresponding plain text value. Data
encrypted using AES can be bigger than Triple-DES, but not by a significant amount. This occurs
because all of the information needed to decrypt the value, except the encryption key, is stored
with the value. Therefore, before you set the encryption password and encrypt the data, you must
be sure the encrypted data can fit in the column. A chart of the expected sizes can be found in the
IBM Informix Administrator Guide.
Compliance regulations
Informix’s encryption routines comply with the United States’ regulations of Health Insurance
Portability and Accountability Act (HIPAA), Sarbanes-Oxley, Gramm-Leach-Bliley, and California
Personal Information: Privacy (SB 1386) as well as the international requirements of Basel II.
Also, they comply with the latest cryptographic standards (OpenSSL 0.9.7c).
Version 1.6
73
IBM Software Group
CHAPTER 8:
IBM Information Management
Environment
Scripts
Oracle make files used to build the application should be modified to invoke the appropriate
Informix ESQL/COBOL, ESQL/C, MF COBOL, and other application language commands.
The shell scripts, shell startup scripts, and command files should be modified for Informix
compliant statements.
SQL script substitution variables
In Oracle, a substitution variable is a user variable name preceded by one or two ampersands (&).
When Oracle (SQL*Plus) encounters a substitution variable in a command, Oracle executes the
command as though it contained the value of the substitution variable, rather than the variable
itself.
In Oracle, the substitution variables can be used anywhere in SQL and SQL*Plus commands,
except as the first word entered at the command prompt. When SQL*Plus encounters an
undefined substitution variable in a command, SQL*Plus prompts the user for the value.
SQL*Plus reads the responses from the keyboard, even if terminal input or output has been
redirected to a file. If a terminal is not available (if, for example, the command file is run in batch
mode), SQL*Plus uses the redirected file.
Informix’s dbaccess does not provide this functionality, however, a work-around for the redirected
file type of substitution is a follows (no user prompting).
Create the following shell script (named subvals.ksh in this case).
#!/bin/kshif [[ $# -ne 2 ]]
then
echo "\nUsage: $0 <dfile> <cfile>\n"
echo "Desc: This script accepts two files - dfile, the decode
file,"
echo "
and cfile, the change file. It modifies the
change file"
echo "
using the values listed in the decode file."
echo "
The decode file should contain two columns - old
value"
echo "
and new value."
echo "
Ex:"
echo "
changethis
tothis"
echo
echo "
In this case, every occurance of 'changethis'
would be"
echo "
replaced with 'tothis'.\n"
exit 1
fi
Version 1.6
74
IBM Software Group
IBM Information Management
#----------------------# Declare variables
#----------------------dfile=$1
cfile=$2
awk '{print "s/"$1"/"$2"/"}' $dfile > $dfile"_sed"
sed -f $dfile"_sed" $cfile
The preceding script is used by creating a “decode” file (named decodefile in this case), which
holds two columns in the form, which may contain multiple rows:
oldval
newval
Executing the following command:
subvals.ksh decodefile chgfile
will replace every occurrence of oldval with newval in the file chgfile. The shell script (subvals.ksh)
writes to standard output, therefore, the output should be redirected. The redirected file will then
be able to run with dbaccess.
Utilities
To improve performance, the Informix EXPLAIN utility should be used by executing the SET
EXPLAIN ON command to see how an SQL statement accesses the database. From that point
forward the access path for every SQL statement is written in the SQEXPLAIN.OUT file in the
current working directory, or the home directory of the process that initiated the request on the
host machine. The Informix SET EXPLAIN OFF should be executed to turn off this feature when
finished.
The overall system performance should be monitored using the Informix ONSTAT utility.
System catalog
The following items discuss how Informix implements the system catalog differently than Oracle.
Each item refers to the Informix implementation only.
Object names are stored in lower case.
The system catalog tables are owned by ‘informix’. To query the systables table use: SELECT *
from ‘informix’.systables.
Each table in systables is assigned a tabid by the system. It is used as the primary key and
therefore, the foreign key for the other catalog tables.
The identifier information is stored in sysindexes. Columns part1 - part16 each contain a column
component of a composite index. They are integers, positive for ascending order, negative for
descending order.
In syscolumns, collength and coltype have special meanings depending on the data type of the
column. See the Informix Guide to SQL, Reference Version for details.
Version 1.6
75
IBM Software Group
CHAPTER 9:
IBM Information Management
Using Bladelets
What is a Bladelet?
A "Bladelet" is a small, informal Informix Datablade module. It's meant to be useful "out of the
box," and is offered complete with source code at no cost -- and no support or warranty.
In the context of this document, the term "Datablade" refers to an extension to the standard IBM
Informix database engine. These generally take the form of new data types (for example,
timeseries or video) and/or new routines that execute inside the server. The new routines might
operate on new data types, or on existing ones.
A Datablade module is usually a formal product, available for sale. In addition a Datablade is:




Developed either by IBM Informix or by a third-party developer
Rigorously tested
Packaged and sold for profit
May or may not be formally certified by IBM Informix as having been developed according
to approved Datablade coding practices
In contrast, a Bladelet is:



Not rigorously tested
Not sold for profit
Not certified by IBM Informix
A Bladelet is an extension to the database engine that is narrow in scope and thought to be
generally useful being offered at no cost, complete with source. Just remember before you use
any of this code in mission-critical applications, it's up to you to thoroughly test it and fix any
problems you find. Please review the disclaimer which applies to any sample code you find on this
site:
http://www.ibm.com/developerworks/db2/zones/informix/library/samples/db_downloads.html
Note: The bladelets at this link have not been updated for some time (at the time of this writing);
some of the capabilities, especially simple function call that increase compatibility, may have been
introduced into the Informix server itself since they were written.
Useful Bladelets
Bladelet
Description
Exec
Defines two user-defined functions that provide dynamic SQL functionality within a SPL
procedure.
Flat File Access Method
A complete access method that lets you build virtual tables based on operating system files.
IUtil
Implements a collection of "other database vendor" functions for Informix
Version 1.6
76
IBM Software Group
IBM Information Management
JPEG Image Bladelet
Provides a user-defined type for JPEG images that allows you to manipulate images and to
extract and search on image properties
Multirepresentational lvarchar
Opaque Type
Creates the idn_mrLvarchar opaque type, which stores character data up to 2 gigabytes.
Node Datablade Module
Creates the node opaque type, which is intended to solve one of the hardest problems in
relational databases: transitive closure.
Regexp
Creates routines that let you manipulate character and clob data using regular expressions.
Shapes DataBlade Module
Creates several opaque types for managing spatial data, including R-tree index support.
Smart Blob Information
DataBlade Module
Includes a variety of useful routines for working with smart blobs.
SqlLib C
SqlLib is a Bladelet that adds several "other database compatibility" functions to Informix .
There are two functionally identical implementations: SqlLib for Java and SqlLib for C.
SqlLib Java
SqlLib is a Bladelet that adds several "other database compatibility" functions to Informix .
There are two functionally identical implementations: SqlLib for Java and SqlLib for C.
Versioning Table Access
Method
Permits users to create and manage "versioned" tables.
We will look closer at two bladelets which could assist with migration; the Exec datablade and
SQLLib.
Informix Exec bladelet for Dynamic SQL
Often, it is desirable to execute a SQL query that is generated at run-time within the RDBMS. For
example, a developer may not know the name of the temporary table they wish to run the query
against, or they might want to append predicates to a query. In external programs, this can be
accomplished using the ESQL/C SQLCA and DESCRIPTOR facilities.
Unfortunately the INFORMIX Stored Procedure Language (SPL) does not support Dynamic SQL.
Queries must be hard-coded into the SPL logic. The objective of the Exec bladelet is to remedy
this situation. Exec consists of user-defined functions that take an SQL query as an argument,
execute it, and return the result (the format of which varies depending on which function is called
and the kind of query). The Exec functions can handle most Data Definition Language (DDL)
statements and all Data Manipulation Language (DML) queries. For more details and download
refer to:
http://www.ibm.com/developerworks/db2/zones/informix/library/demo/ids_exec.html
There are three User Defined Routines (UDRs) in the Exec bladelet. Two of them are external 'C'
functions that use the Server API (SAPI). These must be compiled into shared libraries on the
target machine, and you need to declare them to the server using CREATE FUNCTION
statements. The third UDR is a routine written in Informix Stored Procedure Language (SPL) that
uses the first two UDRs to return a collection of items.
The Exec bladelet module consists of the following:
1. EXEC
The EXEC() function takes an LVARCHAR that it treats as a SQL query, executes the query
and returns a single, LVARCHAR result string. Depending on what kind of SQL statement is
submitted, Exec() returns a different result format.
Version 1.6
77
IBM Software Group
IBM Information Management
2. EXEC_FOR_ROWS
The EXEC_FOR_ROWS() UDR is an iterator function, which means it can return more than one
result row. Of course, it only does so when it is asked to execute a SELECT. Otherwise, it
behaves exactly as the EXEC() UDR. Being an iterator function limits the ways in which such
a UDR can be used. It cannot be used in another SQL query. The only place it can be used
effectively is inside a SPL routine.
3. EXEC_FOR_MSET
EXEC_FOR_MSET() is a SPL routine that uses the EXEC_FOR_ROWS() routine introduced
above. Instead of returning a set of rows as an iterator, or a single row as the EXEC() UDF
does, this UDR collects the results of the SQL query together into a single object: a multi-set.
Refer to Appendix E: Sample Code for examples on using the EXEC bladelet functions.
SqlLib DataBlade module (SqlLibC.1.1 / SqlLibJ.1.1)
The SqlLib DataBlade module implements SQL routines that the Informix does not support
natively but that are supported by some other database vendors. Source code is freely available
for download and includes two implementations, one in C (SqlLibC) and the other in Java
(SqlLibJ).
The following routines are included:

ascii - takes a single character as input and returns the ASCII value, in decimal, that
corresponds to that character








ceil - takes a single numeric value as input and returns the smallest integer that is either
equal to or greater than the input value
chr - takes an integer value and returns the character that is represented by the ASCII
value (in decimal) of that integer
instr - searches for a value in a string, and returns the position where it was found. It
returns 0 if the search value was not found.
instrb - provides the exact same functionality as instr() but for single-byte character sets
sign - takes a numeric argument and returns an integer that indicates if the input value is
positive (1), negative (-1), or zero (0)
to_decimal - converts the input character argument into a decimal type
to_float - converts the input character argument into a float type
to_integer - converts the input character argument into an integer type
For more details and download refer to:
http://www.ibm.com/developerworks/db2/zones/informix/library/techarticle/db_sqllib.html
For more details and download refer to:
http://www.ibm.com/developerworks/db2/zones/informix/library/techarticle/db_sqllib.html
Version 1.6
78
IBM Software Group
A P P E N D I X A:
IBM Information Management
Planning guide
The checklist below will help an analyst determine which Oracle features which need to be
converted to Informix and give some guidance on the effort involved. Each porting task is listed.
They are followed by a quantity field used to determine how prevalent the item, the difficulty or
amount of effort involved, 1 (low) to 5 (high), is used to estimate the amount of time needed to
perform the task when the associated item exists in the application a moderate number of times.
What is moderate depends on the size of the application. If there are an unusually large number
of occurrences of an item, then the effort should be increased. Conversely, if there are a small
number of occurrences of an item, then the effort should be decreased. Each of these items is
discussed in detail within this document. Each heading corresponds to a section heading within
the document.
Tasks
Quantity
Effort
DDL
Identifiers
Delimit identifiers named with Informix reserved words
Databases
Determine database names and create databases
Replace Oracle tablespace names with Informix dbspace names
ANSI vs. Non-ANSI considerations
Tables
Convert create table statements
Convert DDL syntax
Reduce primary key length to 390 bytes
Data Types
Convert Oracle’s NUMBER data type
Convert VARCHAR columns
Convert Oracle’s DATE data type
Convert raw data types
Convert Rowids
Indexes
Convert Indexes
Views
Remove CREATE VIEW statement options
Stored Procedures and Triggers
Convert CREATE and REPLACE Stored Procedure and Trigger syntax
Oracle Extensions
Remove non-supported Oracle extensions from DDL
Tasks
2
3
1
3
2
3
5
3
2
5
2
2
2
1
1
1
Quantity
Effort
DML
SQL
Add the Informix AS clause to display labels
Replace non-supported DML syntax: ^=, /* … */, :=, ELSE IF
Convert Optimizer Directive/Hints
Convert Insert/Select/Union and Insert/Value/Select statements
Version 1.6
1
2
2
3
79
IBM Software Group
IBM Information Management
Convert Delete statement syntax
Convert temporary table processing
Convert Join statements: +, MINUS, INTERSECT, different data types
Convert sorts
Convert hard coded SQL error messages
Remove correlation names on the main table of Update and Delete
statements
Replace original table names in SELECT statements using aliases
Convert hierarchical implementation (CONNECT BY PRIOR)
Host Variables
Convert host variable format or add conversion processing
Functions
Convert date and time functions
Convert aggregate functions
Convert mathematical functions
Convert string function syntax
Convert other unsupported Oracle functions
Macros
Convert ISOPEN, NOT FOUND, ROWTYPE, and TYPE macros
Pseudo-Columns
Convert Level processing
Convert Rownum processing
Update Using Cursors
Convert WHERE CURRENT OF processing for multiple table joins
Convert FOR UPDATE with a HOLD cursor processing
Convert concurrency processing from Oracle’s implicit to Informix’s
explicit
System Tables
Convert system table references
Tasks
Stored procedures
Break stored procedures greater than 64K in size into smaller ones
Convert Oracle’s stored procedure packages
Convert exception processing
Convert error handling (SQLCA)
Convert Oracle’s global cursor processing
Convert Oracle’s explicit cursor processing
Convert flow control processing
Convert Oracle’s implicit variable declaration and assignment
Convert Oracle’s BOOLEAN variable type
Convert binary data type processing
Convert Oracle’s dynamic SQL processing
Triggers
Convert multi-functional triggers
Convert Insert and Update triggers which are not supported in Informix
Place logical statements in a stored procedure
Constraints
Convert constraint enabling and disabling processing
DUAL table
Convert Dual table processing
1
2
2
4
3
2
1
5
5
5
3
5
1
5
3
3
2
5
2
4
1
Quantity
Effort
2
3
5
2
5
2
5
3
1
5
3
5
5
5
4
Embedded SQL
Host variables
Version 1.6
80
IBM Software Group
IBM Information Management
Convert declaration overrides
Convert array processing
Convert Oracle’s formatting functions
SQL structures
Convert SQLDA processing
Convert ORACA processing
Pre-compiler options
Convert Oracle pre-compiler options
Embedded PL/SQL
Convert Oracle’s Embedded PL/SQL
ODBC
Convert Oracle’s OCI
Convert database library calls
Convert global area processing
Convert fetch cycle
Convert RAW data type processing
Convert parameter bindings
Embedded SQL for C
Convert VARCHAR processing
Embedded SQL for COBOL
Convert VARCHAR processing
Convert 88 Level processing in COBOL
Convert Redefine processing in COBOL
Tasks
1
5
4
5
1
1
5
5
2
2
2
4
Quantity
Effort
Application architecture
Transaction processing
Convert application to Informix transaction processing
Convert multiple connect processing
Convert savepoints
Concurrency
Address Informix locking processing
User authentication
Address Informix security processing
5
5
n/a
2
n/a
4
Environment
Convert make files
Convert shell scripts, shell startup scripts, and command files
Convert script substitution variables
Version 1.6
2
2
81
IBM Software Group
A P P E N D I X B:
IBM Information Management
Syntax comparison
See the Informix Guide to SQL: Syntax for more information on each item.
Oracle
Boolean
AND
NOT
OR
Greater Than or Equal To
Less Than or Equal TO
Not Equal
Identifiers
Data types
Character
Long Character
Number (2 bytes)
Number (4 bytes)
Number (> 4 bytes)
Image
DML
Comments
Assignment
Condition
Aggregate functions
Average
Count
Maximum
AND
NOT
OR
>=
<=
<>, !=, or ^=
letters, numbers,”_”,”$”,”#”
AND
NOT
OR
>=
<=
<> or !=
letters, numbers, and “_”
CHAR
VARCHAR (2000) if <= 2000
LONG VARCHAR if > 2000
NUMBER
NUMBER
NUMBER
LONG RAW, CLOB, BLOB
CHAR
CHAR or TEXT
--, /* … */
var1 := expression
ELSE IF
--, { … }
LET var1 = expression
ELSE
or
ELIF
IF
AVG(expression), AVG(ALL
expression), AVG(DISTINCT
expression)
AVG(expression), AVG(ALL
expression), AVG(DISTINCT
column_name), AVG(UNIQUE
column_name)
COUNT(*), COUNT(DISTINCT
column_name), COUNT
(UNIQUE column_name)
COUNT(*), COUNT
(expression), COUNT(ALL
expression), COUNT
(DISTINCT expression)
MAX(expression), MAX(ALL
expression), MAX(DISTINCT
expression)
Minimum
MIN(expression), MIN(ALL
expression), MIN(DISTINCT
expression)
Sum
SUM(expression), SUM(ALL
expression), SUM(DISTINCT
expression)
Algebraic functions
Round
Statistical functions
Standard Deviation
Variance
Range
Version 1.6
Informix
SMALLINT
INTEGER
DECIMAL
BYTE, TEXT, CLOB, BLOB
MAX(expression), MAX(ALL
expression), MAX(DISTINCT
column_name), MAX(UNIQUE
column_name)
MIN(expression), MIN(ALL
expression), MIN(DISTINCT
column_name), MIN(UNIQUE
column_name)
SUM(expression), SUM(ALL
expression), SUM(DISTINCT
column_name), SUM(UNIQUE
column_name)
ROUND(expression,rounding
factor)
ROUND(expression,rounding
factor)
STDEV(expression)
VARIANCE(expression)
?
STDDEV(expression)
VARIANCE(expression)
RANGE(expression)
82
IBM Software Group
String functions
Trim
Length
Like
Like (single character)
Like (wildcard)
String Delimiter
Escape Character
Stored procedures
Create
Arguments
Version 1.6
IBM Information Management
LTRIM(expression)
RTRIM(expression)
LENGTH(string)
LIKE(string)
_
%
‘ or “
set within LIKE clause using
ESCAPE “?” to make “?” the
escape character
LTRIM(expression)
RTRIM(expression)
LENGTH(string)
LIKE(string)
_
%
‘ or “
\ or set within LIKE clause
using ESCAPE “?” to make “?”
the escape character
CREATE OR REPLACE
PROCEDURE
procedure_name (var1 IN
CHAR(1), var2 OUT DATE,
var3 IN OUT NUMBER);
DROP PROCEDURE
procedure_name;
CREATE PROCEDURE
procedure_name (var1
CHAR(1), var3 INTEGER)
RETURNING DATE,
INTEGER;
EXECUTE PROCEDURE
procedure_name (var1, var3)
RETURNING var2, var3;
EXECUTE PROCEDURE
procedure_name (var1 IN,
var2 OUT, var3 IN OUT);
83
IBM Software Group
A P P E N D I X C:
IBM Information Management
Database concepts
The table below illustrates the relationship between each database vendor’s database objects.
Oracle
Informix
Database name attached to a group of files
Specific database name
Data file
Chunk
Tablespace (logical partition) or Segments
(Index Segment, Table Segment and so on)
Dbspace
Extent
Extent
Rollback Segment
Physical Log
Redo Log
Logical Log
System tablespace
Root dbspace
Temporary tablespace
Temporary dbspaces, dbspacetemp
environment variable, or dbspacetemp onconfig
parameter
Pointer
Blobspace, Sbspace
Table partitioning
table fragmentation
Database link
Not supported
Snapshot
Not supported
oerr utility
finderr utility
sqldba and svrmgrl - monitor utilities
onstat and oncheck utilities
SQLPlus utility
dbaccess utility
Pro*C
ESQL/C
Pro*COBOL
ESQL/COBOL
SQL*NET
INet
OCI
Like the ESQL function library after precompiling, if they were publically documented.
Read Consistency
COMMITTED READ LAST COMMITTED
Version 1.6
84
IBM Software Group
A P P E N D I X D:
IBM Information Management
Sample code
User defined functions
User Defined Routines (UDR) can be developed to extend the capabilities of the database and
provides the option to create UDRs to emulate Oracle built-in functions and reduce the impact of
replacing all references throughout the application. Or rename an Informix function to the
corresponding Oracle function name.
CONCAT
CREATE PROCEDURE concat (str1 VARCHAR(255), str2 VARCHAR(255))
RETURNING VARCHAR(255);
RETURN str1 || str2;
END PROCEDURE;
INSTR
CREATE PROCEDURE instr(
str
VARCHAR(255),
mask VARCHAR(255),
strt SMALLINT DEFAULT 1,
occur SMALLINT DEFAULT 1
)
RETURNING INT;
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
LET
LET
LET
LET
LET
LET
LET
LET
LET
slen SMALLINT;
mlen SMALLINT;
tempstr VARCHAR(255);
tempmask VARCHAR(255);
nomatch SMALLINT;
count SMALLINT;
pos SMALLINT;
retpos SMALLINT;
i SMALLINT;
j SMALLINT;
srchstrt SMALLINT;
slen
mlen
count
nomatch
pos
retpos
tempstr
tempmask
srchstrt
=
=
=
=
=
=
=
=
=
LENGTH(str);
LENGTH(mask);
0;
0;
1;
1;
'';
'';
strt;
IF (strt < 0) THEN
- reverse the str
FOR i = 1 TO slen
LET tempstr = str[1,1] || tempstr;
LET str = str[2,255];
END FOR;
-- reverse the mask
FOR i = 1 TO mlen
LET tempmask = mask[1,1] || tempmask;
LET mask = mask[2,255];
END FOR;
Version 1.6
85
IBM Software Group
IBM Information Management
LET srchstrt = strt * -1;
LET str = tempstr;
LET mask = tempmask;
END IF;
FOR j = 1 TO slen
LET tempstr = str;
LET tempmask = mask;
FOR i = 1 TO mlen
IF (tempmask[1,1] != tempstr[1,1]) THEN
LET nomatch = 1;
EXIT FOR;
END IF;
LET tempmask = tempmask[2,255];
LET tempstr = tempstr[2,255];
END FOR;
IF (nomatch = 0) THEN
IF (pos >= srchstrt) THEN
LET count = count + 1;
END IF;
IF (count = occur) THEN
IF (strt < 0) THEN
RETURN slen - pos + 1;
ELSE
RETURN pos;
END IF;
END IF;
END IF;
LET str = str[2,255];
LET nomatch = 0;
LET pos = pos + 1;
END FOR;
RETURN 0;
END PROCEDURE;
YYYYMMDD
CREATE PROCEDURE yyyymmdd (str VARCHAR(10)) RETURNING varchar(8);
DEFINE retstr VARCHAR(8);
IF str IS NULL THEN
RETURN NULL;
ELSE
LET retstr = str[7,10] || str[1,2] || str[4,5];
RETURN retstr;
END IF;
END PROCEDURE;
Using EXEC bladelet functions
Version 1.6
86
IBM Software Group
IBM Information Management
Using EXEC
Note the ROW data type variable can be referenced using table and column syntax.
CREATE PROCEDURE example1() RETURNING INTEGER
DEFINE sql_stmt LVARCHAR(255);
DEFINE rcnt ROW(val INTEGER);
LET sql_stmt = "select count(*) from items where manu_code = ‘ANZ’";
EXECUTE FUNCTION EXEC(sql_stmt) INTO rcnt;
RETURN rcnt.val;
END PROCEDURE;
Using EXEC_FOR_ROWS
CREATE PROCEDURE example2() RETURNING INTEGER, CHAR(1)
DEFINE rs_rowdata ROW(customer_num INTEGER, call_code CHAR(1));
DEFINE sql_stmt LVARCHAR(255);
LET sql_stmt = "select customer_num, call_code from cust_calls where
customer_num = 106";
FOREACH
EXECUTE FUNCTION EXEC_FOR_ROWS(sql_stmt) INTO rs_rowdata
RETURN rs_rowdata.customer_num, rs_rowdata.call_code WITH RESUME;
END FOREACH;
END PROCEDURE;
Using EXEC_FOR_MSET
Note the DEFINE statement for the variable rs_data. Collection data types used in a SPL routine
cannot be defined using the LIKE attribute in the DEFINE statement.
CREATE PROCEDURE example3() RETURNING INTEGER, VARCHAR(8)
DEFINE v_customer_num LIKE accounts.customer_num;
DEFINE v_account_cd LIKE accounts.account_cd;
DEFINE rs_data MULTISET(ROW(
r_customer_num INTEGER,
r_account_cd VARCHAR(8)) NOT NULL);
DEFINE sql_stmt LVARCHAR;
LET sql_stmt = "select customer_num, order_num from orders where
company_id = 51155";
EXECUTE FUNCTION EXEC_FOR_MSET(sql_stmt) INTO rs_data;
FOREACH
SELECT r_customer_num, r_account_cd INTO v_customer_num,
v_account_cd
FROM TABLE(rs_data)
RETURN v_customer_num, v_account_cd WITH RESUME;
END FOREACH;
END PROCEDURE;
Version 1.6
87
IBM Software Group
IBM Information Management
Date arithmetic
Informix has extensive capabilities for manipulating dates and times. You can add or subtract
DATE and DATETIME variables from each other. You can add or subtract an INTERVAL to a
DATE or DATETIME.
UNITS Keyword
When working with INTERVAL values, sometimes it is necessary to specify the precision with
which you are dealing. For example, suppose you have the following field defined:
To add 10 days to the lead time you could use a SQL statement like this:
SELECT lead_time + INTERVAL(10) DAY to DAY FROM orders
-or-
SELECT lead_time + 10 UNITS DAY FROM orders
Using EXTEND function
The EXTEND function allows operations between data types of different precisions.
SELECT
EXTEND(myvar, YEAR to MINUTE) – INTERVAL(5) MINUTE to MINUTE
FROM member
Calculate Week Of The Year
SELECT ROUND((TODAY - DATE('01/01/'||YEAR(TODAY))) /7 + .5) FROM DUAL;
Number of days difference
SELECT DATE('01/06/'||YEAR(TODAY)) - DATE('01/06/2005') FROM DUAL;
Number of weeks difference
SELECT ROUND((DATE('01/06/'||YEAR(TODAY)) - DATE('01/06/2005'))
/ 7 + .5) FROM DUAL;
String representation of date and time
Day and date
SELECT TO_CHAR(TODAY, '%A %B %d, %Y') FROM dual;
-returns month, day and 4 digit yearTuesday January 03, 2006
Abbreviation of day of week
SELECT SUBSTR(TO_CHAR(TODAY, '%A %B %d, %Y %R'),1,3) FROM dual;
-orSELECT TO_CHAR(TODAY, '%a') FROM dual;
-returns MON, TUE, WED, THU, FRI, SAT, SUN-
Returning the number of rows affected
Version 1.6
88
IBM Software Group
IBM Information Management
Within SPL routines, you can use the DBINFO function to find out the number of rows that have
been processed in SELECT, INSERT, UPDATE, DELETE, EXECUTE PROCEDURE, and
EXECUTE FUNCTION statements.
CREATE FUNCTION del_rows(pnumb INT) RETURNING INT;
DEFINE nrows INT;
DELETE FROM sec_tab WHERE part_num = pnumb;
LET nrows = DBINFO('sqlca.sqlerrd2');
RETURN nrows;
END FUNCTION;
To ensure valid results, use this option after SELECT and EXECUTE PROCEDURE or EXECUTE
FUNCTION statements have completed executing. If you use the 'sqlca.sqlerrd2' option within
cursors, make sure that all rows are fetched before the cursors are closed.
Using an Informix collection data type
A collection data type as a VARRAY
In the following examples the collection data types of MULTISET and SET are used in a function
to hold a collection of values. You cannot define a collection variable as global (with the GLOBAL
keyword) or with a default value. Informix SPL allows you to declare a cursor for a collection
variable using the FOREACH statement called a collection cursor.
Also demonstrated is how to utilize a variable declared with the keyword COLLECTION. A
variable declared as type SET, MULTISET, or LIST is a typed collection variable. It can hold a
collection of its specified data type only. However a COLLECTION is an un-typed (or generic)
collection variable that can hold a collection of any data type.
This function will build a MULTISET list of values:
CREATE FUNCTION func1() RETURNING MULTISET(INTEGER NOT NULL)
DEFINE v_array_of_ints MULTISET(INTEGER NOT NULL);
INSERT INTO TABLE (v_array_of_ints) VALUES(1);
INSERT INTO TABLE (v_array_of_ints) VALUES(2);
INSERT INTO TABLE (v_array_of_ints) VALUES(5);
INSERT INTO TABLE (v_array_of_ints) VALUES(4);
RETURN v_array_of_ints;
END FUNCTION;
This function will receive the COLLECTION list of values from func1:
CREATE FUNCTION func2() RETURNING INTEGER
--- DEFINE lmset MULTISET(INTEGER NOT NULL);
-DEFINE lmset COLLECTION;
DEFINE v_int INTEGER;
--- call func1 to populate local multiset variable
-LET lmset = func1();
--- tally a count the number of elements
-FOREACH
SELECT COUNT(*) INTO v_int FROM TABLE(lmset)
Version 1.6
89
IBM Software Group
IBM Information Management
RETURN v_int WITH RESUME;
END FOREACH;
--- return the values
-FOREACH
SELECT * INTO v_int FROM TABLE(lmset)
RETURN v_int WITH RESUME;
END FOREACH;
END FUNCTION;
NOTE: In the example func2, a duplicate declaration for the “lmset” variable as a MULTISET data
type has been commented out, by declaring the variable as a COLLECTION it can accept any of
the 3 types (MULTISET, SET and LIST).
When executing the function, the resulting expression will be:
EXECUTE FUNCTION func2();
(expression)
4 (row count)
1
2
5
4
By using a SET data type, inserts will not permit duplicates:
CREATE FUNCTION func1() RETURNING SET(INTEGER NOT NULL)
DEFINE v_array_of_ints SET(INTEGER NOT NULL);
INSERT INTO TABLE (v_array_of_ints) VALUES(1);
INSERT INTO TABLE (v_array_of_ints) VALUES(2);
INSERT INTO TABLE (v_array_of_ints) VALUES(2);
INSERT INTO TABLE (v_array_of_ints) VALUES(5);
INSERT INTO TABLE (v_array_of_ints) VALUES(5);
INSERT INTO TABLE (v_array_of_ints) VALUES(5);
INSERT INTO TABLE (v_array_of_ints) VALUES(5);
INSERT INTO TABLE (v_array_of_ints) VALUES(5);
RETURN v_array_of_ints;
END FUNCTION;
NOTE: Because func2 is expecting a un-typed COLLECTION variable func1 does not have to be
dropped and recreated. It can receive a value from any Collection Data Type (MULITSET, SET
and LIST).
The function’s return values would change to: (with duplicates suppressed)
EXECUTE FUNCTION func2();
(expression)
3 (row count)
1
2
5
Using a LIST data type, support for assigning values based on ordinal position:
Version 1.6
90
IBM Software Group
IBM Information Management
CREATE FUNCTION func1() RETURNING LIST(INTEGER NOT NULL)
DEFINE v_array_of_ints LIST(INTEGER NOT NULL);
--- first insert no ordinal position can be established, By default, the
-- database server inserts LIST elements at the end of the list.
-INSERT AT 5 INTO TABLE (v_array_of_ints) VALUES(5);
INSERT AT 1 INTO TABLE (v_array_of_ints) VALUES(1);
INSERT AT 2 INTO TABLE (v_array_of_ints) VALUES(2);
--- Only 3 LIST elements exist, position 4 has not been instantiated
-- this element will insert at the end of the list
-INSERT AT 4 INTO TABLE (v_array_of_ints) VALUES(4);
INSERT AT 3 INTO TABLE (v_array_of_ints) VALUES(3);
RETURN v_array_of_ints;
END FUNCTION;
NOTE: The elements of a LIST have ordinal positions; with a first, second, and third element in a
LIST. To support the ordinal position of a LIST, the INSERT statement provides the AT clause.
This clause allows you to specify the position at which you want to insert a list-element value.
Note the behavior of the ordinal positioning above preceded by a commented explanation.
When executing the function, the resulting expression will be:
EXECUTE FUNCTION func2();
(expression)
5 (row count)
1
2
3
5
4
Using MULTISET and ROW to replace PL/SQL TABLE and RECORD types
Creating variables using Informix Collection data types SET, MULTISET and LIST in combination
with ROW data types can be useful when migrating applications which use Oracle REF
CURSORS as arguments to functions as well as Oracle collection data types TABLE and
RECORD.
Typical Oracle Package specification:
CREATE OR REPLACE PACKAGE MyPackage
IS
TYPE recOrders IS RECORD (
order_num
orders.order_num%TYPE,
order_date
orders.order_date%TYPE,
customer_num
orders.customer_num%TYPE,
po_num
orders.po_num%TYPE
);
TYPE tabOrders IS TABLE OF recOrders
INDEX BY BINARY_INTEGER;
TYPE ref_curtype IS REF CURSOR;
Both tabOrders or ref_curtype can be converted to the following Informix SPL definition:
DEFINE tabOrders MULTISET(ROW(
Version 1.6
91
IBM Software Group
IBM Information Management
order_num INTEGER,
order_date DATETIME YEAR TO FRACTION(3),
customer_num INTEGER,
po_num CHAR(10)) NOT NULL);
DEFINE ref_curtype MULTISET(ROW(
{ define columns based on query result set}
) NOT NULL);
Version 1.6
92
IBM Software Group
A P P E N D I X E:
IBM Information Management
Counting system
objects
Using the system catalog
System catalog
Below is a list of SQL statements that will extract most, if not all, of the counts of system objects
owned by user ‘XXX’.
select count(table_name) from all_tables
where owner=’xxx’;
select count(*) from dba_indexes
where owner=’xxx’;
select count(synonym_name) from dba_synonyms
where owner=’xxx’;
select count(*) from dba_views
where owner=’xxx’;
select count(*) from dba_tab_columns
where length(column_name)>18
and owner=’xxx’;
select count(*) from dba_tab_columns
and owner=’xxx’;
select count distinct(*) from dba_tab_columns
and owner=’xxx’;
select count(*) from dba_tables
where length(table_name)>18
and owner=’xxx’;
select count(*) from dba_synonyms
where length(synonym_name)>18
and owner=’xxx’;
select count(*) from dba_views
where length(view_name)>18
and owner=’xxx’;
select count(*) from dba_indexes
where length(index_name)>18
and owner=’xxx’;
select count(*) from dba_tab_columns
where data_type=’varchar2’
and owner=’xxx’;
Version 1.6
93
IBM Software Group
IBM Information Management
select data_type, count(data_type) from dba_tab_columns
where owner=’xxx’
group by data_type;
select count(*) from dba_tab_columns
where data_type=’varchar2’
and length(data_type)>254
and owner=’xxx’;
select count(*) from dba_tab_columns
where data_type=’number’
and data_scale=0
and owner=’xxx’;
Using SQL code
Built-in function references
The following instructions can be used to find references to built-in functions. On the UNIX
machine or the NT box where your code resides, please create the following file as
/tmp/functionlist:
convert(
hextoint(
inttohex(
getdate(
datename(
datepart(
datediff(
dateadd(
months_between(
char(
char_length(
charindex(
compute(
difference(
length(
lower(
patindex(
replicate(
reverse(
right(
soundex(
space(
str(
stuff(
substring(
upper(
abs(
atn2(
log(
ceiling(
Version 1.6
94
IBM Software Group
IBM Information Management
cot(
degrees(
floor(
radians(
rand(
sign(
to_char(
to_date(
to_number(
exception(
pi(
raise_application_error(
raiserror(
SQLCODE
rollback
savepoint
/\*
declare
decode(
nvl(
print(
rowid
waitfor
recompile
bcp
%isopen(
%notfound(
%rowtype(
%type(
Then, please run the following program with the proper subdirectories:
#! /bin/ksh
rm –f /somehome/*.outfile
cd /somesource/database
export sourcebase=”somepath”
for functor in `cat /tmp/function_list`
do
echo before find $functor
find /$sourcebase/database -exec grep -i $functor {} \; >>
/somehome/$functor.outfile
find /$sourcebase/intfc -exec grep -i $functor {} \; >>
/somehome/$functor.outfile
echo after find $functor
done
Object types and counts
This script attempts to count the objects of each type by grepping for CREATE statements
containing the object type, and counts procedure definitions that are inside package bodies, which
are not proceeded by a CREATE keyword. It is not a sophisticated parser; so, the results may not
be perfect.
#!/bin/bash
if [ "$1" = "" ]; then
Version 1.6
95
IBM Software Group
IBM Information Management
echo "Usage: objCounts.sh \"<FilePattern>\""
return 1;
fi
declare -a objectTypes=('CLUSTER' 'CONTEXT' 'CONTROLFILE' 'DATABASE'
'DATABASE +LINK' 'DIMENSION' \
'DIRECTORY' 'DISKGROUP' 'FUNCTION' 'INDEX' 'INDEXTYPE' 'JAVA' 'LIBRARY'
'MATERIALIZED +VIEW' \
'MATERIALIZED +VIEW +LOG' 'OPERATOR' 'OUTLINE' 'PACKAGE' 'PACKAGE
+BODY' 'PFILE' 'PROCEDURE' 'PROFILE' \
'RESTORE +POINT' 'ROLE' 'ROLLBACK +SEGMENT' 'SCHEMA' 'SEQUENCE' 'SPFILE'
'SYNONYM' 'TABLE' 'TABLESPACE' \
'TRIGGER' 'TYPE' 'TYPE +BODY' 'USER' 'VIEW');
echo
for type in "${objectTypes[@]}"
do
if [ "$type" = "PROCEDURE" ];
then
echo $type " object count: " `cat $1 | grep -icE "^ *(|CREATE +|OR REPLACE
+)\b$type\b"`
else
echo $type " object count: " `cat $1 | grep -icE "^ *(CREATE +|OR +REPLACE
+)\b$type\b"`
fi
done
Version 1.6
96
IBM Software Group
A P P E N D I X F:
IBM Information Management
Data type mapping
Oracle built-in data types (including ANSI types) can be converted to similar data
types in the Informix database, according to the mapping described here. This
table provides default mappings based on most common usage patterns; in
some cases another mapping may work better.
In the following table n is used to indicate length, p is used to indicate precision,
and s is used to indicate scale.
Oracle data type
Informix® Server data type
BFILE
LONG RAW
BLOB
BLOB
BINARY_DOUBLE
DOUBLE PRECISION
BINARY_FLOAT
DOUBLE PRECISION
BINARY_INTEGER
INTEGER
PLS_INTEGER
NATURAL
NATURALN
POSITIVE
POSITIVEN
32-bit integers; only used in
PL/SQL. NATURAL and
POSITIVE are unsigned
integers.
BOOLEAN (PL/SQL only)
BOOLEAN
CHAR(n) or CHARACTER(n)
CHAR(n)
DATE
DATETIME YEAR TO
SECOND
DOUBLE PRECISION
DOUBLE PRECISION
Version 1.6
97
IBM Software Group
FLOAT
IBM Information Management
FLOAT
See note on FLOAT below.
INTEGER
INT
INTEGER
A 38-digit NUMBER sub-type.
May want to flag with a
warning on possible overflow.
INTERVAL DAY(p) TO
SECOND(s)
INTERVAL DAY(p) TO FRACTION(min(5,
s))
Note: Oracle fractional
seconds have 9 digits.
INTERVAL YEAR(p) TO
MONTH
INTERVAL YEAR(p) TO MONTH
LONG
CLOB
CLOB
LONG VARCHAR (xxx)
LVARCHAR
Oracle recommends not using
this type.
NCHAR(n)
NATIONAL CHAR(n), or
NATIONAL CHARACTER(n)
NCHAR(n)
NCLOB
CLOB
NUMBER
INTEGER
See National Language Types below.
NUMBER(*,0)
NUMBER(p)
NUMBER(p, s)
Where scale (s) is less than 0
(that is, s < 0), and p-s < 10.
NUMBER(3,-2): 12300
Version 1.6
98
IBM Software Group
NUMBER(p)
NUMBER (p,0)
IBM Information Management
BIGINT
Where precision (p) is greater
than or equal to 10 and <= 18.
NUMBER(p, s)
Where scale (s) is less than 0
(that is, s < 0), and 10 <= p-s
< 19.
NUMBER(9,-2): 12345678900
NUMBER(p, s)
NUMERIC (min(p,32), min(s,32))
Where scale (s) is greater
than 0 and precision (p) is
greater than or equal to s (that
is, s > 0 and p >= s).
NUMBER(p, s)
NUMERIC (min(s,32),min(s,32))
Where scale (s) is greater
than 0 and precision (p) is
less than s (that is, s > 0 and
p < s).
NUMBER(3,5): 0.00123
NUMBER(p, s)
NUMERIC (min(p-s,32),0)
Where scale (s) is less than 0
(that is, s < 0), and p-s > 18
and p-s <= 32.
NUMBER(p, s)
NUMERIC (32)
Scale cannot be greater than precision.
Where scale (s) is greater
than 32, or pInformix-s is greater NUMERIC(32,32) would guarantee that
than 32.
digits to the left of the decimal would be lost.
Using a floating point decimal provides the
simplest, best way to capture as many digits
in a value as possible.
Version 1.6
99
IBM Software Group
DEC
DECIMAL
NUMERIC
DEC(p)
DECIMAL(p),
IBM Information Management
There is no difference within Oracle between
these types and each other and these types
and NUMBER. The Oracle system catalogs
contain the NUMBER type id for all
declarations of these types, and the integer
types as well. Declarations of these types
can be mapped using the same rules as
those for NUMBER.
NUMERIC(p),
DEC(p, s)
DECIMAL(p, s) NUMERIC(p,
s)
NVARCHAR2(n)
NCHAR VARYING(n)
NATIONAL CHAR
VARYING(n)
NATIONAL CHARACTER
VARYING(n)
LVARCHAR(min(n, 32767))
RAW(n)
BLOB
REAL
DOUBLE PRECISION
Record
ROWTYPE
Using a CREATE ROWTYPE statement.
ROWID
INTEGER
SMALLINT
SMALLINT
TIMESTAMP(p)
DATETIME YEAR TO
FRACTION(min(5, p))
If p is not specified, precision
defaults to 6.
UROWID(n)
Version 1.6
INTEGER
100
IBM Software Group
IBM Information Management
VARCHAR2(n)
VARCHAR(n)
CHAR VARYING(n)
CHARACTER VARYING(n)2
VARCHAR(n)
Where number (n) is less than
or equal to 255 (that is, n <=
255).
VARCHAR2(n)
VARCHAR(n)
CHAR VARYING(n)
CHARACTER VARYING(n)2
LVARCHAR(n)
Where number (n) is greater
than 255 (that is, n > 255).
XMLType
CLOB
Notes on specific types are below.
DOUBLE
The range of values for the DOUBLE PRECISION data type is the same as the range of the C
double data type on your computer.
VARCHAR
While Oracle VARCHAR data types have a limit of 4000 bytes, an Informix Server VARCHAR
data types has a limit of 255 bytes. An Informix Server LVARCHAR has a limit of 32,739 Bytes.
NUMBER
Oracle abstracts its numeric types from the hardware and operating system through the use of its
NUMBER type. Most numeric types, like INTEGER, are actually NUMBERs internally. When
porting to a database server like Informix which retains more of a relationship between the
operating system types and the database types, it is essentially a one-to-many mapping, and
heuristics have to be used to determine the best-fit target type. No single set of type mapping
rules will fit all use scenarios. The converter has default rules which fit the more common user
patterns.
When considering a number represented as mantissa and exponent,
mantissa x 10
exponent
precision is the number of digits in the mantissa, and scale is the negative exponent, how many
places to the right of the decimal point the least significant digit is located. Oracle NUMBERs have
a maximum precision of 38 and the maximum precision available in Informix native types is 32.
The first step in a type mapping is to truncate the target type precision to min(precision, 32). The
scale of a type can be considered its anchor point with respect to the decimal point. The most
Version 1.6
101
IBM Software Group
IBM Information Management
significant digit of a numeric type is located precision digits to the left of the decimal point and
precision-scale digits to the right of the decimal point. The start and end locations of the digits are
used to determine the closest fitting Informix type. The order of preference is INTEGER, BIGINT,
NUMERIC(p, s), and lastly, NUMERIC(p).
NUMERIC(p) in a non-ANSI mode database is a decimal type with a floating point type. In an
ANSI mode database, the scale is implicitly 0.
All Oracle integer declaration types, such as INT, INTEGER, SMALLINT become NUMBER(38)
type in the Oracle metadata. In Oracle, when precision is given, but scale is not, scale becomes 0
implicitly, which makes the type in the set of integral types.
One exception to the general mapping rules is the NUMBER type specified without precision or
scale. Strictly speaking, this has a floating point scale with 38 digits of precision, but most
commonly it is used where an integer is more appropriate. Even if the user does specify
INTEGER in a type definition, when it comes out of the Oracle catalogs, the type is NUMBER.
This is one case in particular where one type mapping will not fit well with all usage scenarios.
National language types
Oracle N*char types are allocated by number of characters, where Informix is allocated by the
number of bytes. For Oracle, the storage size of the characters varies with the encoding used,
and is always subject to the standard 32,767 limit on maximum bytes, but during declarations, n
always means the number of characters.
Oracle PL/SQL supports explicit and implicit data type conversions. These explicit and implicit
data types are converted to syntax by using Informix Dynamic Server's explicit and implicit data
type conversion mechanism.
ROWID
Oracle databases support a pseudo-column named ROWID, such that every row in every table is
assigned an auto-generated ID. Oracle also allows you to define a column of type ROWID, which
can be used as a foreign key to a ROWID pseudo-column. Oracle ROWID columns contain data
that if converted to a string are 18 characters long, for example ‘AAAQ+jAAEAAAAAeAAN’. It is
probably not advisable to migrate this data to an Informix database, and instead use the Informix
type, which is an integer. If there is a dependency on the values themselves, and therefore need
migrate the data, then an integer type would not hold the values.
%TYPE
In PL/SQL, you can refer to the type of an existing variable, field, or column by using the %TYPE
attribute. The converter replaces this reference directly by the type it refers to.
%ROWTYPE
In PL/SQL, you can refer to the record type that represents a row of a table, a cursor, or a cursor
variable. PL/SQL scripts containing the %ROWTYPE attribute are handled in the same way as a
record type that has been previously declared.
FLOAT
Oracle FLOAT type is a floating point number capable of storing up to 38 decimal digits, or 126
binary digits. It has a floating point scale that can exist outside the boundaries of what an Informix
DECIMAL can represent. A C language double, or Informix float type is capable of only 16 digits;
so, there is the chance that some data will be lost. Using an Informix FLOAT type makes it so that
less significant digits are lost in preference to more significant digits.
Version 1.6
102
IBM Software Group
IBM Information Management
References to subtypes declared in packages and PL/SQL blocks are converted to the Informix
Server equivalent base types.
Variables of type RECORD are not translated by the DDL Converter at the time of this writing.
They will be handled by the stored procedure converter.
XMLType
Informix does not have a built-in type for representing XML. The nearest approximation is to store
it in a CLOB. Another character type, like LVARCHAR, can be used if it can be determined that
the actual data will fit in it.
Version 1.6
103