Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The Seq type has a neat function for handling database cursors called generate_using (see <a href="http://research.microsoft.com/fsharp/manual/FSharp.PowerPack/Microsoft.FSharp.Compatibility.Seq.html" rel="nofollow noreferrer">F# Manual</a> and the Data Access chapter in <a href="http://apress.com/book/view/9781590597576" rel="nofollow noreferrer">Foundations of F#</a>). This is a higher order function that takes one function to open the cursor and another (called repeatedly) to process records from the cursor. Here is some code that uses generate_using to execute a sql query:</p> <pre class="lang-fs prettyprint-override"><code>let openConnection (connectionName : string) = let connectionSetting = ConfigurationManager.ConnectionStrings.Item(connectionName) let connectionString = connectionSetting.ConnectionString let connection = new OracleConnection(connectionString) connection.Open() connection let generator&lt;'a&gt; (reader : IDataReader) = if reader.Read() then let t = typeof&lt;'a&gt; let props = t.GetProperties() let types = props |&gt; Seq.map (fun x -&gt; x.PropertyType) |&gt; Seq.to_array let cstr = t.GetConstructor(types) let values = Array.create reader.FieldCount (new obj()) reader.GetValues(values) |&gt; ignore let values = values |&gt; Array.map (fun x -&gt; match x with | :? DBNull -&gt; null | _ -&gt; x) Some (cstr.Invoke(values) :?&gt; 'a) else None let executeSqlReader&lt;'a&gt; (connectionName : string) (sql : string) : 'a list = let connection = openConnection connectionName let opener() = let command = connection.CreateCommand(CommandText = sql, CommandType = CommandType.Text) command.ExecuteReader() let result = Seq.to_list(Seq.generate_using opener generator) connection.Close() connection.Dispose() result </code></pre> <p>For example to list all the tables in an Oracle database we need to define a column definition type and invoke executeSqlReader as follows:</p> <pre class="lang-fs prettyprint-override"><code>type ColumnDefinition = { TableName : string; ColumnName : string; DataType : string; DataLength : decimal; } let tableList = executeSqlReader&lt;ColumnDefinition&gt; "MyDatabase" "SELECT t.table_name, column_name, data_type, data_length FROM USER_TABLES t, USER_TAB_COLUMNS c where t.TABLE_NAME = c.table_name order by t.table_name, c.COLUMN_NAME" </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload