Mysql
 sql >> Datenbank >  >> RDS >> Mysql

F#-Anfänger:Abrufen eines Arrays von Daten von einem Server

Der Seq-Typ hat eine nette Funktion zur Behandlung von Datenbank-Cursoren namens generate_using (siehe F#-Handbuch und das Kapitel „Datenzugriff“ in Grundlagen von F# ). Dies ist eine Funktion höherer Ordnung, die eine Funktion zum Öffnen des Cursors und eine andere (wiederholt aufgerufen) zum Verarbeiten von Datensätzen vom Cursor benötigt. Hier ist ein Code, der generate_using verwendet, um eine SQL-Abfrage auszuführen:

let openConnection (connectionName : string) =
    let connectionSetting = ConfigurationManager.ConnectionStrings.Item(connectionName)
    let connectionString = connectionSetting.ConnectionString
    let connection = new OracleConnection(connectionString)
    connection.Open()
    connection

let generator<'a> (reader : IDataReader) =
    if reader.Read() then
        let t = typeof<'a>
        let props = t.GetProperties()
        let types = props
                    |> Seq.map (fun x -> x.PropertyType)
                    |> Seq.to_array
        let cstr = t.GetConstructor(types)
        let values = Array.create reader.FieldCount (new obj())
        reader.GetValues(values) |> ignore
        let values = values
                     |> Array.map (fun x -> match x with | :? DBNull -> null | _ -> x)
        Some (cstr.Invoke(values) :?> 'a)
    else
        None

let executeSqlReader<'a> (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

Um beispielsweise alle Tabellen in einer Oracle-Datenbank aufzulisten, müssen wir einen Spaltendefinitionstyp definieren und executeSqlReader wie folgt aufrufen:

type ColumnDefinition = {
    TableName : string;
    ColumnName : string;
    DataType : string;
    DataLength : decimal;                
}

let tableList = executeSqlReader<ColumnDefinition>
    "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"