diff options
Diffstat (limited to 'lib/odbc/doc/src/databases.xml')
-rw-r--r-- | lib/odbc/doc/src/databases.xml | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/lib/odbc/doc/src/databases.xml b/lib/odbc/doc/src/databases.xml new file mode 100644 index 0000000000..c06327e11d --- /dev/null +++ b/lib/odbc/doc/src/databases.xml @@ -0,0 +1,275 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2002</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>Databases</title> + <prepared>Ingela Anderton</prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev></rev> + <file>databases.xml</file> + </header> + + <section> + <title>Databases</title> + <p>If you need to access a relational database such as + <c>sqlserver</c>, <c>mysql</c>, <c>postgres</c>, <c>oracle</c>, + <c>cybase</c> etc. from your erlang application using the Erlang + ODBC interface is a good way to go about it.</p> + <p></p> + <p>The Erlang ODBC application should work for any relational + database that has an ODBC driver. But currently it is only + regularly tested for <c>sqlserver</c> and <c>postgres</c>.</p> + </section> + + <section> + <title>Database independence </title> + <p>The Erlang ODBC interface is in principal database + independent, e.i. an erlang program using the interface could be + run without changes towards different databases. But as SQL is + used it is alas possible to write database dependent + programs. Even though SQL is an ANSI-standard meant to be + database independent, different databases have proprietary + extensions to SQL defining their own data types. If you keep to + the ANSI data types you will minimize the problem. But + unfortunately there is no guarantee that all databases actually + treats the ANSI data types equivalently. For instance an + installation of <c>Oracle Enterprise release 8.0.5.0.0 for unix</c> will accept that you create a table column with the + ANSI data type <c>integer</c>, but when retrieving values from + this column the driver reports that it is of type + <c>SQL_DECIMAL(0, 38)</c> and not <c>SQL_INTEGER</c> as you may have + expected. </p> + <p>Another obstacle is that some drivers do not support scrollable + cursors which has the effect that the only way to traverse the + result set is sequentially, with next, from the first row to the + last, and once you pass a row you can not go back. This means + that some functions in the interface will not work together with + certain drivers. A similar problem is that not all drivers + support "row count" for select queries, hence resulting in that + the function <c>select_count/[3,4]</c> will return <c>{ok, undefined}</c> instead of <c>{ok, NrRows}</c> where + <c>NrRows</c> is the number of rows in the result set.</p> + </section> + + <section> + <title>Data types </title> + <p>The following is a list of the ANSI data types. For details + turn to the ANSI standard documentation. Usage of other data types + is of course possible, but you should be aware that this makes your + application dependent on the database you are using at the moment.</p> + <list type="bulleted"> + <item>CHARACTER (size), CHAR (size)</item> + <item>NUMERIC (precision, scale), DECIMAL (precision, scale), DEC + (precision, scale ) precision - total number of digits, scale + - total number of decimal places</item> + <item>INTEGER, INT, SMALLINT</item> + <item>FLOAT (precision)</item> + <item>REAL</item> + <item>DOUBLE PRECISION</item> + <item>CHARACTER VARYING(size), CHAR VARYING(size)</item> + </list> + <p>When inputting data using sql_query/[2,3] the values will + always be in string format as they are part of an SQL-query. + Example:</p> + <code type="none"> + odbc:sql_query(Ref, "INSERT INTO TEST VALUES(1, 2, 3)"). + </code> + <note> + <p>Note that when the value of the data to input is a string, it + has to be quoted with <c>'</c>. Example: </p> + <code type="none"> +\011odbc:sql_query(Ref, "INSERT INTO EMPLOYEE VALUES(1, 'Jane', 'Doe', 'F')"). + </code> + </note> + <p>You may also input data using <seealso marker="odbc#param_query">param_query/[3,4]</seealso> and then + the input data will have the Erlang type corresponding to the + ODBC type of the column.<seealso marker="#type">See ODBC to Erlang mapping</seealso></p> + <p> <marker id="type"></marker> + When selecting data from a table, all data + types are returned from the database to the ODBC driver as an + ODBC data type. The tables below shows the mapping between those + data types and what is returned by the Erlang API.</p> + <table> + <row> + <cell align="left" valign="middle">ODBC Data Type </cell> + <cell align="left" valign="middle">Erlang Data Type </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_CHAR(size)</cell> + <cell align="left" valign="middle">String </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_NUMERIC(p,s) <br></br> +when (p >= 0 and p <= 9 and s == 0) </cell> + <cell align="left" valign="middle">Integer </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_NUMERIC(p,s) <br></br> +when (p >= 10 and p <= 15 and s == 0) or (s <= 15 and s > 0)</cell> + <cell align="left" valign="middle">Float </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_NUMERIC(p,s) <br></br> +when p >= 16 </cell> + <cell align="left" valign="middle">String </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_DECIMAL(p,s) <br></br> +when (p >= 0 and p <= 9 and s == 0) </cell> + <cell align="left" valign="middle">Integer </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_DECIMAL(p,s) <br></br> +when (p >= 10 and p <= 15 and s == 0) or (s <= 15 and s > 0)</cell> + <cell align="left" valign="middle">Float </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_DECIMAL(p,s) <br></br> +when p >= 16 </cell> + <cell align="left" valign="middle">String </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_INTEGER </cell> + <cell align="left" valign="middle">Integer </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_SMALLINT </cell> + <cell align="left" valign="middle">Integer </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_FLOAT </cell> + <cell align="left" valign="middle">Float </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_REAL </cell> + <cell align="left" valign="middle">Float </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_DOUBLE</cell> + <cell align="left" valign="middle">Float</cell> + </row> + <row> + <cell align="left" valign="middle">SQL_VARCHAR(size) </cell> + <cell align="left" valign="middle">String </cell> + </row> + <tcaption>Mapping of ODBC data types to the Erlang data types returned to the Erlang application.</tcaption> + </table> + <table> + <row> + <cell align="left" valign="middle">ODBC Data Type </cell> + <cell align="left" valign="middle">Erlang Data Type </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_TYPE_DATE </cell> + <cell align="left" valign="middle">String </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_TYPE_TIME </cell> + <cell align="left" valign="middle">String </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_TYPE_TIMESTAMP </cell> + <cell align="left" valign="middle">String </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_LONGVARCHAR </cell> + <cell align="left" valign="middle">String</cell> + </row> + <row> + <cell align="left" valign="middle">SQL_BINARY</cell> + <cell align="left" valign="middle">String </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_VARBINARY</cell> + <cell align="left" valign="middle">String </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_LONGVARBINARY</cell> + <cell align="left" valign="middle">String </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_TINYINT </cell> + <cell align="left" valign="middle">Integer </cell> + </row> + <row> + <cell align="left" valign="middle">SQL_BIT</cell> + <cell align="left" valign="middle">Boolean </cell> + </row> + <tcaption>Mapping of extended ODBC data types to the Erlang data types returned to the Erlang application.</tcaption> + </table> + <note> + <p>To find out which data types will be returned for the + columns in a table use the function <seealso marker="odbc#describe_table">describe_table/[2,3]</seealso></p> + </note> + </section> + + <section> + <title>Batch handling</title> + <p>Grouping of SQL queries can be desirable in order to reduce + network traffic. Another benefit can be that the data source + sometimes can optimize execution of a batch of SQL queries.</p> + <p>Explicit batches an procedures described below will result + in multiple results being returned from sql_query/[2,3]. + while with parameterized queries only one result will be returned + from param_query/[2,3].</p> + + <section> + <title>Explicit batches</title> + <p>The most basic form of a batch is created by semicolons + separated SQL queries, for example:</p> + <code type="none"> +"SELECT * FROM FOO; SELECT * FROM BAR" or +"INSERT INTO FOO VALUES(1,'bar'); SELECT * FROM FOO" + </code> + </section> + + <section> + <title>Procedures </title> + <p>Different databases may also support creating of procedures + that contains more than one SQL query. For example, the + following SQLServer-specific statement creates a procedure that + returns a result set containing information about employees + that work at the department and and a result set listing the + customers of that department. </p> + <code type="none"> + CREATE PROCEDURE DepartmentInfo (@DepartmentID INT) AS +\011SELECT * FROM Employee WHERE department = @DepartmentID +\011SELECT * FROM Customers WHERE department = @DepartmentID + </code> + </section> + + <section> + <title>Parameterized queries</title> + <p>To effectively perform a batch of similar queries, you can use + parameterized queries. This means that you in your SQL query + string will mark the places that usually would contain values + with question marks and then provide lists of values for each + parameter. For instance you can use this to insert multiple + rows into the <c>EMPLOYEE</c> table while executing only a + single SQL statement, for example code see <seealso marker="getting_started#param_query">"Using the Erlang API"</seealso> section in the "Getting Started" chapter.</p> + </section> + </section> +</chapter> + + |