F #

2012-07-26 3 views
2

으로 삽입 문 작성하기 몇 달에 한 번 F #을 사용하고 그 사이에 모든 것을 잊어 버린 것 같아서 내 무지를 용서할 수 있기를 바랍니다. 아래 코드는 Yahoo에서 데이터를 가져 오는 것입니다. 그것은 내가해야 할 일을 나타내는 좋은 예입니다. 반환 된 첫 번째 행에는 열 머리글이 있습니다. 데이터 (목록의 꼬리)를 취해 데이터베이스에 삽입해야합니다. 반환 된 열 머리글을 기반으로 삽입 문을 생성하는 가장 좋은 방법은 무엇입니까 (열 머리글은 데이터베이스 열 이름과 일치합니까)?F #

아래 예에서는 데이터 헤더가 있습니다. [0] "날짜, 열기, 높음, 낮음, 닫음, 볼륨, 닫음"을 포함합니다. 그 문자열을 가져 와서 표제 주위에 괄호를 넣어 삽입을 만들어야합니까? 그런 다음 insertData에서 값을 매개 변수로 추가 하시겠습니까? 보다 우아한 솔루션이 있습니까?

let url = System.String.Format("http://ichart.finance.yahoo.com/table.csv?s={0}&g=d&ignore=.csv", "FB") 

let splitLineIntoArray (line : string) = 
    line.Split(",".ToCharArray()) 

let insertData (data : string[]) = 
    // insert data 
    () 

let client = new WebClient() 
let dataWithHeaders = 
    client.DownloadString(url).Split(Environment.NewLine.ToCharArray()) 

let data = 
    dataWithHeaders 
    |> Array.toList 
    |> List.tail 
    |> List.map(splitLineIntoArray) 
    |> List.iter insertData 
+0

ORM 사용에 대해 생각해 보셨습니까? 나는 syme가 SQL 스크립트를 생성하기 위해 여기서 인용문을 사용하고 있다고 생각한다. http://blogs.msdn.com/b/dsyme/archive/2011/04/16/soma-sql-oriented-mapping-framework-for-f.aspx –

+0

SQL Server에 데이터를로드하고 있습니까? – Daniel

+0

ORM이 지나치게 많을 지 알지 못했습니다. 이것은별로 정교하지 않습니다. SQL Server에 데이터를로드하고 있습니다. 나는 타입 제공자를 사용할 수 있기를 고대하고있다. 비록 이것이이 경우 도움이 될지 모르겠다. – nickfinity

답변

8

당신은 SQL 서버에 데이터가있는 this excellent CSV reader (무료)을 사용할 수 있으며, SqlBulkCopy 클래스를로드하는 경우. 간단하고 효율적입니다.

let loadStockPrices ticker = 
    use client = new WebClient() 
    let url = sprintf "http://ichart.finance.yahoo.com/table.csv?s=%s&g=d&ignore=.csv" ticker 
    use stringReader = new StringReader(client.DownloadString(url)) 
    use csvReader = new CsvReader(stringReader, hasHeaders=true) 
    use con = new SqlConnection("<connection_string>") 
    con.Open() 
    use bulkCopy = new SqlBulkCopy(con, DestinationTableName="<destination_table>") 
    bulkCopy.WriteToServer(csvReader) 

대상 테이블에는 들어오는 데이터 (OHLC 등)와 동일한 열이 있어야합니다.

+0

고마워요, 그게 속임수를 쓰는 것처럼 보입니다. 나는 오라클이나 다른 DB에서 이런 식으로 움직이는 경우에도 여전히 다른 접근법에 관심이있다. – nickfinity

+0

['OracleBulkCopy'] (http://docs.oracle.com/cd/E11882_01/win.112/e23174/OracleBulkCopyClass.htm)가 있습니다. 나는 대부분의 데이터베이스 시스템과 비슷한 것이 있다고 생각한다. 한 번에 한 행씩 INSERT하는 것은 대단히 비효율적입니다. – Daniel

+0

+1은 SqlBulkCopy의 단순함을 나타냅니다. –

4

편집 : 유형 공급자 갈 수있는 좋은 방법이 될 수도 있지만 SqlBulkCopy의 데프이다. 그것의 간명을 위해 cognised. 삽입에 대한

유형 제공자 코드 : http://msdn.microsoft.com/en-us/library/hh361033(v=vs.110).aspx#BKMK_UpdateDB

type dbSchema = SqlDataConnection<"Data Source=MYSERVER\INSTANCE;Initial Catalog=MyDatabase;Integrated Security=SSPI;"> 
let db = dbSchema.GetDataContext() 

// Enable the logging of database activity to the console. 
db.DataContext.Log <- System.Console.Out 

let newRecord = new dbSchema.ServiceTypes.Table1(Id = 100, 
               TestData1 = 35, 
               TestData2 = 2.0, 
               Name = "Testing123") 
let newValues = 
    [ for i in [1 .. 10] -> 
      new dbSchema.ServiceTypes.Table3(Id = 700 + i, 
              Name = "Testing" + i.ToString(), 
              Data = i) ] 
// Insert the new data into the database. 
db.Table1.InsertOnSubmit(newRecord) 
db.Table3.InsertAllOnSubmit(newValues) 
try 
    db.DataContext.SubmitChanges() 
    printfn "Successfully inserted new rows." 
with 
    | exn -> printfn "Exception:\n%s" exn.Message 

나는 비슷한 일을했다. Luca Bolognese를 보면서 내가 작성한이 코드는 F #에 대한 프리젠 테이션을 제공합니다. 이것은 실제로 야후의 피드를 긁어 모으고 표준 dev를 반환합니다. 주가 변동. 여기

전체 프로젝트 : https://github.com/djohnsonm/Stock-Ticker-App

open System.Net 
open System.IO 

let internal loadPrices ticker = async { 
let url = @"http://ichart.finance.yahoo.com/table.csv?s=" + ticker + "&d=6&e=22&f=2011&g=d&a=2&b=13&c=1986&ignore=.csv" 
let req = WebRequest.Create(url) 
let resp = req.GetResponse() 
let stream = resp.GetResponseStream() 
let reader = new StreamReader(stream) 
let csv = reader.ReadToEnd() 
let prices = 
    csv.Split([|'\n'|]) 
    |> Seq.skip 1 
    |> Seq.map (fun line -> line.Split([|','|])) 
    |> Seq.filter(fun values -> values |> Seq.length = 7) 
    |> Seq.map(fun values -> 
     System.DateTime.Parse(values.[0]), 
     float values.[6]) 
return prices} 

type StockAnalyzer (lprices, days) = 
    let prices = 
     lprices 
     |> Seq.map snd 
     |> Seq.take days 
    static member GetAnalyzers (tickers, days) = 
     tickers 
     |> Seq.map loadPrices 
     |> Async.Parallel 
     |> Async.RunSynchronously 
     |> Seq.map (fun prices -> new StockAnalyzer(prices, days)) 
    member s.Return = 
     let lastPrice = prices |> Seq.nth 0 
     let startPrice = prices |> Seq.nth(days-1) 
     lastPrice/startPrice - 1. 
    member s.StdDev = 
     let logRets = 
      prices 
      |> Seq.pairwise 
      |> Seq.map (fun (x,y) -> log(x/y)) 
     let mean = logRets |> Seq.average 
     let sqr x = x * x 
     let var = logRets |> Seq.averageBy (fun r -> sqr (r-mean)) 
     sqrt var