Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
61 views

Oracle To Postgres

Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views

Oracle To Postgres

Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Porting from Oracle to PostgreSQL

by Paulo Merson February/2002

If you are starting to use PostgreSQL or you will migrate from Oracle database server, I hope this document helps. If you have Java applications and use JDBC, the Data types and JDBC section will be particularly useful. Oracle and PostgreSQL both conform to standard SQL. However, they contain several extensions and implementation details that differentiate one from the other. The most important differences are listed in this document. If you have comments about this document, please email me: pmerson@cs.cmu.edu.

1. SQL Syntax, Functions, Sequences, Etc.


Oracle
select sysdate from dual

PostgreSQL
select now::datetime

There is no dual table Unlike other RDBMS, PostgreSQL allows a select without the from clause. This use does not affect portability because the syntax to get current time is already DBMS specific.
CREATE SEQUENCE seqname [ INCREMENT BY integer ] [ MINVALUE integer ] [ MAXVALUE integer ] [ START WITH integer ] [ CACHE integer ] [ CYCLE | NOCYCLE ] CREATE SEQUENCE seqname [ INCREMENT increment ] [ MINVALUE minvalue ] [ MAXVALUE maxvalue ] [ START start ] [ CACHE cache ] [ CYCLE ]

Oracles create sequence has other arguments not listed here and not supported by PostgreSQL, but the main difference is the need of by and with after increment and start. If you dont specify MAXVALUE or if you use the parameter NOMAXVALUE, then the actual limit is 1027.

If you dont specify MAXVALUE, then the maximum value is 2147483647 for ascending sequences.

Oracle
To return the current value and increment the counter:
sequence_name.nextval;

PostgreSQL
To return the current value and increment the counter:
nextval(sequence_name);

Possible usage in a select statement:


select sequence_name.nextval from dual;

Possible usage in a select statement


select nextval(sequence_name);

Note that unlike other RDBMS, PostgreSQL allows a select without the from clause. This use does not affect portability because the sequence syntax is already DBMS specific.
SELECT product_id, DECODE (warehouse_id, 1, Southlake, 2, San Francisco, 3, New Jersey, 4, Seattle, Non-domestic) quantity_on_hand FROM inventories select employeeid, NVL(hire_date, sysdate) from employee where employeeid = 10; SELECT a, CASE WHEN a=1 THEN 'one' WHEN a=2 THEN 'two' ELSE 'other' END FROM test

select employeeid, coalesce(hire_date, 'now'::datetime) from employee where employeeid = 10;

Oracle also has a coalesce function that is a generalization of the commonly used NVL function.

Outer join (+) Hierarchical queries CONNECT BY


SELECT product_id FROM inventories MINUS SELECT product_id FROM order_items; select unique col1, col2 from table1

Doesnt support outer join. The workaround is to use a union. Nothing similar
SELECT product_id FROM inventories EXCEPT SELECT product_id FROM order_items; select distinct col1, col2 from table1

In Oracle distinct and unique keywords are synonymous in the select statement.

PostgreSQL doesnt allow select unique.

Oracle
Oracle relational operators may have a space between the characters. For example, the following select will work:
select id,name from employee where id > = 10; // There are spaces and tabs between > and =

PostgreSQL
PostgreSQL relational operators doesnt allow spaces, the characters that compound an operator must be consecutive when the command is parsed:
select id,name from employee where id >= 10;

To get the remainder of the division of 10 by 4 (modulo) use the mod function:
select mod(10,4) from dual;

To get the remainder of the division of 10 by 4 (modulo) use the % operator. (And PostgreSQL has many other arithmetic operators.)
select 10 % 4;

The ROWNUM pseudo-column returns a number indicating the order in which Oracle selects the row. ROWNUM can be used to limit the number of rows returned by a query, for example:
select * from employees where rownum < 10 order by name;

There isnt anything equivalent to Oracle ROWNUM. However, you can limit the number of rows returned by a query using the LIMIT clause:
select * from employees order by name limit 10;

ROWNUM can be used in the projection as one of the values returned by the query (first line has value 1, second line value 2, and so on):
select rownum, name from employees order by name;

In some cases, its possible that the pseudo-column OID may substitute ROWNUM, although they have different behavior. OID is a unique identifier of each line per table, while ROWNUM is always 1, 2, , N for each different query.
select oid, name from employees order by name;

And the query that uses ROWNUM can have join tables. If your select is a join youll have a different OID for each table, because each one has an OID column.

2. Database Server General Characteristics


Oracle A view can be updatable if some conditions are satisfied. PostgreSQL Views are read only.

Oracle Transactions are initiated implicitly. By default, the auto-commit behavior is disabled.

PostgreSQL BEGIN initiates a transaction disabling the default behavior, which is auto-commit enabled, i.e., a commit is performed after each user statement. In Java, we need to write: con.setAutoCommit(false)

Tables, views and other objects can be logically grouped in schemas. A schema usually maps to the user name of the user that created the objects (owner). Thus, a table can be referenced in a statement as schemaName.tableName. For example:
select * from mySchema.myTable;

There is no schema support, but its planned for a future version. The alternative is to use separate databases: You have to connect to the specific database and use that connection to execute your SQL command. However, if you have a SQL statement that uses tables in different (Oracle) schemas, you cannot use separate (PostgreSQL) databases; there is no direct workaround, youll need to rewrite the code. Interactive command prompt tool: psql PostgreSQL permissions are granted/revoked to/from users or groups. You can create groups and then alter the groups inserting/removing users.

Interactive command prompt tool: SQL*Plus Oracle permissions are granted/revoked to/from users or roles. You can create roles and grant/revoke roles to/from users. But you can create and alter groups to insert and remove users.

By default, a password is always required to connect to the database. By default, you can connect to the database simply by specifying the database name, no user ID and password are required. You should follow the instructions in the Administrators Guide to configure the pg_hba.conf file in order to use password authentication.

3. Data Types and JDBC


Oracle
NUMBER(p) where p is the precision, i.e., the number of digits

JDBC

PostgreSQL
SMALLINT - 2 bytes INTEGER - 4 bytes BIGINT - 8 bytes NUMERIC(p,s) REAL 4 bytes, 6 decimal places DOUBLE PRECISION 8 bytes, 15 decimal places

JDBC
getShort getInt getLong getBigDecimal getDouble getDouble getInt

getByte getShort getInt getLong getDouble getBigDecimal

NUMBER(p,s) where p is the total number of digits and s is the number of digits to the right of the decimal point

Nothing similar

SERIAL - 0 to +2147483647, typically used to create unique identifiers. Generates an implicit sequence that is incremented when a line is inserted in the table. getString getString CHARACTER VARYING(n) where maximum n is 1 GB VARCHAR(n) is an alias CHARACTER(n) where maximum n is 1 GB CHAR(n) is an alias Its suggested that you use TEXT if n > 10 MB TEXT variable length up to 1 GB Its suggested that you use TEXT if n > 10 MB TIMESTAMP You still can use getDate to read a TIMESTAMP column, but you will loose the time portion of the data.

VARCHAR2(size) where maximum size is 4000 CHAR(size) where maximum size is 2000

getString getString

LONG - Character data of variable length up to 2 GB DATE holds date and time

getString getDate getTime getTimestamp oracle.sql. getTIMESTAMP

getString getTimestamp

TIMESTAMP Nothing similar Nothing similar

DATE holds only the date (resolution is one day) TIME holds only the time (00:00:00.00 23:59:59.99)

getDate getTime

Oracle
RAW(size) binary data of length size bytes (max 2000) LONG RAW binary data or variable length up to 2GB Nothing similar

JDBC

PostgreSQL
BYTEA

JDBC
getBytes

getBytes

BIT(n) fixed length string of 1s and 0s BIT VARYING(n) variable length string of 1s and 0s getClob TEXT (max 1GB)

(?)

CLOB character large object (max 4GB)

getString

BLOB binary large object (max 4GB)

getBlob

BYTEA (max 1GB) BYTEA is not documented in PostgreSQL 7.1 but its fully implemented; Jdbc 7.2-1.2 is required though in order to use getBytes and setBytes. Besides TEXT and BYTEA, PostgreSQL supports large objects as separate files. They are stored in a separate table in a special format, and are referred to from regular tables by an OID value. More information: http://www.postgresql.org/idocs/index.php?larg eobjects.html http://www.postgresql.org/idocs/index.php?jdbc -lo.html Nothing similar BOOLEAN can have the value TRUE, FALSE or NULL If you store '0' and '1' in a varchar(1) or char(1) column, then the jdbc driver can correctly interpret these values as boolean false an true respectively using ResultSet.getBoolean. However, PreparedStatement.setBoolean simply does not work. If you use PostgreSQL BOOLEAN, then your Java code can use getBoolean and setBoolean.

getBytes

ROWID Nothing similar Typically, char(1) is used to store a value that is translated to Boolean in the application logic. If you store '0' and '1' in a varchar2(1) or char column, then the jdbc driver can correctly interpret these values as boolean false an true respectively using ResultSet.getBoolean and PreparedStatement.setBoolean Oracle Spatial features

oracle.sql. getROWID

getBoolean

Geometric data types: POINT, LINE, CIRCLE, etc.

org. postgresql. geometric.*

Oracle
Nothing similar

JDBC

PostgreSQL
Network address data types: INET, MACADDR, CIDR.

JDBC
(?)

JDBC note: Typically PreparedStatement.setXxx is used to set the value of arguments (or host variables) inside SQL statements. And there is a correspondent ResultSet.getXxx method to read the value returned by a query into java variables. Each get/setXXX method has a specific Java data type or class associated to it (e.g. set/getInt deals with int; set/getDate deals with java.sql.Date, etc.). Further, you can use different methods to read the same database data type, but usually there is a recommended method. For example, a BIGINT column can be read with getShort, getInt, getLong, getDouble, etc., but the recommended method is getLong. So, to indicate the proper way to use each data type in Java I simply listed the recommended getXxx JDBC method.

4. Other Considerations:
The set of operators and SQL functions is very similar though Oracle has a richer set. For example, both DBMS have the concatenation operator ||, as well as substr, upper, to_char and other functions with the same syntax. However, any Oracle function that is being used must have its syntax compared to the equivalent function in PostgreSQL, if such exists. PostgreSQL lacks the ability to query across multiple databases. PostgreSQLs PL/pgSQL is similar to Oracle PL/SQL and can be used to write stored functions. PostgreSQL doesnt have packages or procedures (only functions). More about this: http://www.postgresql.org/idocs/index.php?plpgsql-porting.html Both DBMS have triggers and the create trigger statement is similar, but the code executed by the trigger for PostgreSQL must be in a stored function written by the user, while in Oracle you have the option of writing the code in a PL/SQL block in the create trigger statement. PostgreSQL has yet an additional resource called the rule system that allows the definition of business logic that is executed upon an event. The create table statement is similar in both DBMS. One noticeable difference is that PostgreSQL doesnt have pctfree, pctused, inittrans, and maxtrans clauses. They also differ in the create database statement, mainly in the arguments and clauses that specify storage details.

5. References:
Oracle 9i documentation - http://download-east.oracle.com/otndoc/oracle9i/901_doc/nav/docindex.htm PostgreSQL documentation - http://www.postgresql.org/idocs/ Oracle to Postgre Conversion - http://openacs.org/doc/openacs/html/oracle-to-pg-porting.html PostgreSQL JDBC 2.0 compliance - http://lab.applinet.nl/postgresql-jdbc/ An important source of information is the PostgreSQL mailing lists: http://archives.postgresql.org/

You might also like