What are the differences between Microsoft Access and Oracle?

There are many differences between Oracle and Access. First, you need to know that Oracle and Access are both relational database engines. Oracle is sold by Oracle Corporation and Access is sold by Microsoft. The biggest differences between the two are the size and number of users each supports. Oracle is a scalable enterprise database engine that supports from one to many (tens to hundreds of thousands) of simultaneous users. Access on the other hand is most commonly used as a single-user database but since the release of Access 97, can be augmented with Visual Basic code and can easily support 100+ simultaneous users (Top limit of 200 users). Oracle can support very large databases (Tens of Terabytes in size or larger), while Access is designed for much smaller databases in the 1 to 2 gigabyte size range. Oracle has a wide range of support features that can be used to monitor and tune database performance - Access is much more limited in its performance tuning capabilities. Microsoft's SQL Server rdbms is a direct competitor with Oracle and has a great many more similarities with Oracle. There are numerous incompatibilities between Access/Jet SQL and Oracle SQL, including, but not limited to the following:

1. The date delimiter is "#" in Access and " ' " (single quote) in Oracle and SqlServer.

2. In CHAR Datatype, Oracle returns trailing spaces. Access does not return trailing spaces in String data type. In Oracle, use VarChar2 Datatype.

3. Jet allows use of the "Join" keyword. Oracle uses "(+)" following the joined field(s). Join is not a recognized word in Oracle.

4. IIF() is allowed in Jet but in Oracle, you must use the DECODE function. See Oracle documentation.

5. The following functions in Jet must be translated in Oracle.

Mid(fld, 2, 2) - Substr(fld, 2, 2)

Left(2) - Substr(fld, 1, 2)

Right(n) - Substr( fld, Instr(...),n)

Len() - LENGTH()

Year(Fld) = 1997 - to_char(Fld, 'yyyy') = '1997'

Month(Fld) = 6 - to_char(fld, 'mm') = '06'

Trim(Fld) - LTrim() or RTrim()

6. Generally, you need to use "to_date('01/23/1978', 'mm/dd/yyyy')" to format a date for comparison in Oracle SQL whereas in Jet Sql you could simply use "#01/23/1978#".

7. "RENAME" is a reserved word in Oracle and is therefore an illegal field or table name, but not in Jet.

8. If a memory variable is used in a SQL statement, and the variable is a string with trailing spaces, Jet will trim the value before comparing to the database field. Oracle will not! Therefore, the following will work in Jet but not Oracle, assuming the Oracle field in VARCHAR[2].

Sql = " ... where fldname = 'abc ' ...."

9. Oracle SQL will not find uppercase data in the database if the value in the SQL statement is lowercase. Assume that the LastName field contains the value 'SMITH' in the Oracle table Policy. Access will make a find on the following SQL and Oracle will not (Like character would be "*" for Access.

select * from Policy where LastName Like 'smith%'

10. Conversion of Memo (Jet) fields to Oracle can be a problem. The only data type in Oracle that is analogous to the Memo in Jet is the Long. Although it can hold up to 2gb of string data, you cannot append more than approximately 5,000 characters to the existing Long field because you exceed the length of the maximum string length in an Oracle SQL Statement.

Additionally, you cannot use such expressions, as the following, usable in Jet, in Oracle. They result in the error, "Invalid use of Long Datatype."

select distinct LONGFLD


It seems impossible to use a query to determine rows where there is data in the Long field since a Long field that has '' in it is not Null.

Oracle 8 has Append and Get Chunk commands, but the documentation in the Oracle 7.2 Book does not mention these functions, nor are there any examples of how to update a Long field that exceeds 5,000+ characters.

11. Use of the following sql can be extremely slow in Oracle.

select * from table where policy in

(select policy2 from table2 where .....)

Try using the Oracle Minus operator instead. It uses indexes where the "in (select...)" does not. See the Oracle documentation for usage of the Minus.

12. It is normal, when using Jet, to fill the recordsource property of a data control at design time, even if you are going to fill it with a specific SQL sometime after Form_Load. This is done in order to use the Grid Designer when a data control is bound to a Grid or Combo, etc. However, when the form loads, all such data controls are refreshed. If you have the table name as the data control recordsource, which would be normal for designer use, and assuming that dbSQLPassThrough is being used, the entire table is returned to the client machine and refreshed into the grid, even if the grid is not visible, i.e., on a different tab. In Jet, this will not be the case if "UseExactRow" property is not set and therefore will not take an inordinate amount of time, but in Oracle it could be disastorous!

An easy way to deal with this is to set the recordsource to "" in the Form_Load event, especially if you are connected to Oracle. Later on, your code will set the recordsource to the specific SQL as required. Note that this must be done in the Form_Load because the Grid will be refreshed by the time the Activate Event is fired.

13. Be aware that, when using dbSQLPassThrough, the entire recordset, specified by the SQL, is returned to the client machine, and is therefore readonly. At this point the recordset belongs to the client, and Oracle is out of the picture. In praticality, there is no difference between a Snapshot and Dynaset in passthrough mode.

14. Use of apostrophes (') in names and abbreviations are a problem in SQL. In Access, it may be circumvented by use of the double quote (") to encapsulate string data in the SQL statement instead of the apostrophe, thus allowing the use of the (') in the string. In Oracle, you can use two single quotes ('') to denote an apostrophe. The string below is valid in Oracle Sql.

... Set Lastname = 'O''Toole',...

15. In Access, an empty string ("") is not Null. Oracle's default parameter for Null is set to '' (double single quotes or empty string). In other words, Oracle, by default, treats an empty string field as Null. Therefore, the following code which works in Access, does not work in Oracle.

...Where RTrim(Fld) <> ''.....

In Oracle, change the SQL to:

... Where Fld is not null....

Also, the following sql will not work if a field is Null.

... Where THSTATE <> 'Z'...

Even though the field is null, and therefore <> 'Z', the row containing the Null field will not be returned. In order to get the row, you must enhance the SQL as:

...where (THSTATE <> 'Z' or THSTATE is Null)...


16. When using dbSQLPassThrough with DAO, the RecordsAffected Property will always return -1, and there is apparently no way to determine whether any records were affected by an action sql or not.

17. When printing an error message from ODBC, if you print Error, as in the errors object, you will print "ODBC Call Failed", which is useless. Instead, print Errors(0).Description (or both) and you will get the true error description returned from the ODBC data source.

18. If you are having trouble with a bound data control returning less than the correct number of row, i.e., returns 100 rows when it should have returned 200 or more, set the DefaultCursorType to 1 (ODBC Cursor). For some reason this is not always required, but it will solve the problem of truncated recordsets in a data control connected to Oracle.

19. Access allows an Order By clause at the end of a query that uses a Union, but if you try this in Oracle, it will not work because Oracle ignores the column names in the result set from the Union. Not to worry! You can Order By column positions from the select statement. In other words, if Policy is returning in column 3 of the result set, and you want to order by Policy, then use "Order By 3..."