2

以下のSSISスクリプトタスクは、ティッカーシンボルと取得したい日付範囲を受け取り、価格履歴の抽出に使用できるCSV形式のダウンロードを返しますが、機能せず、理由がわかりません。このSSISのよく考えられた概念に関する完全な情報は、以下のリンクにあります。

SSIS / ETLの例–Yahooのエクイティと投資信託の価格履歴

以下のリンクからサンプルSSISパッケージをダウンロードできます。

SkyDriveのサンプルパッケージ

次のSSISスクリプトタスクにはエラーはありませんが、ファイルはダウンロードされません。

私はこのコードを理解し始めたばかりで、このリンクはここのようなコンポーネントに細分化されているようで、正しい値で機能する必要がありますが、ファイルを取得しない理由がわかりません。

ichart.finance.yahoo.com/table.csv?s={symbol}&a={startMM}&b={startDD}&c=
{‌​startYYYY}&d={endMM}&e={endDD}&f={endYYYY}&g={res}&ignore=.csv

私が使用しているスクリプトタスクコード:

using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Configuration;
using System.Collections.Generic;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Net;
using System.Collections.Specialized;
using System.Linq;

using Hash = System.Collections.Generic.Dictionary<string, string>;

namespace ST_361aad0e48354b30b8152952caab8b2b.csproj
{
    [System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {

        #region VSTA generated code
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
        #endregion

        static string dir;
        static DateTime end;
        const string CSV_FORMAT = "Id,Cusip,Date,Open,High,Low,Close,Volume,Adj Close";

        public void Main()
        {
            // end date is today minus one day (end of day)
            end = DateTime.Now;

            // output directory stored in SSIS variable
            // which can be set at runtime
            dir = System.IO.Path.Combine(Dts.Variables["OutputCSV"].Value.ToString(), end.ToString("yyyyMMdd"));
            if (!System.IO.Directory.Exists(dir))
                System.IO.Directory.CreateDirectory(dir);

            // connection string to our database
            var connectionString = Dts.Variables["ConnectionString"].Value.ToString();

            // the sql command to execute
            var sql = Dts.Variables["PriceHistorySqlCommand"].Value.ToString();

            var list = new List<Hash>();
            using (var cnn = new SqlConnection(connectionString))
            {
                cnn.Open();
                using (var cmd = new SqlCommand(sql, cnn))
                {
                    cmd.CommandTimeout = 0;
                    var dr = cmd.ExecuteReader();
                    while (dr.Read())
                    {
                        // store result in temporary hash
                        var h = new Hash();
                        h["cusip"] = dr["cusip"].ToString();
                        h["symbol"] = dr["symbol"].ToString();
                        h["product_id"] = dr["product_id"].ToString();
                        h["last_price_dt_id"] = dr["last_price_dt_id"].ToString();

                        list.Add(h);

                        // process batches of 100 at a time 
                        // (This requires System.Threading.dll (CTP of parallel extensions) to be installed in the GAC)
                        if (list.Count >= 100)
                        {
                            System.Threading.Tasks.Parallel.ForEach(list, item =>
                            {
                                var dt = item["last_price_dt_id"].TryGetDateFromDateDimensionId(end.AddYears(-100));
                                DownloadPriceHistory(item["product_id"], item["cusip"], item["symbol"], dt);
                            });
                            list.Clear();
                        }
                    }
                }
            }


            // TODO: Add your code here
            Dts.TaskResult = (int)ScriptResults.Success;
        }

        static void DownloadPriceHistory(string id, string cusip, string symbol, DateTime begin)
        {
            // get write path
            var path = System.IO.Path.Combine(dir, cusip + ".csv");
            var url = String.Format("http://ichart.finance.yahoo.com/table.csv?s={0}&d={1}&e={2}&f={3}&g=d&a={4}&b={5}&c={6}&ignore=.csv",
                symbol.ToUpper(),
                (end.Month - 1).ToString("00"), end.Day.ToString("00"), end.Year,
                (begin.Month - 1).ToString("00"), begin.Day.ToString("00"), begin.Year);
            string csv;

            using (WebClient web = new WebClient())
            {
                try
                {
                    var text = web.DownloadString(url);
                    var lines = text.Split('\n');
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    int i = 0;
                    foreach (var line in lines)
                    {
                        // skip first line its a header
                        if (i == 0)
                            sb.AppendLine(CSV_FORMAT);
                        // ensure line being added is not null
                        else if (false == String.IsNullOrEmpty(line) && false == String.IsNullOrEmpty(line.Trim()))
                            sb.AppendLine(id + "," + cusip + "," + line);
                        i++;
                    }
                    // add header and body
                    csv = sb.ToString();
                }
                catch (System.Net.WebException)
                {
                    // 404 error
                    csv = CSV_FORMAT;
                }
            }

            System.IO.File.WriteAllText(path, csv);
        }
    }

    /// <summary>
    /// Some simple extension methods.
    /// </summary>
    public static class ExtensionMethods
    {
        /// <summary>
        /// Gets a datetime object from a dimension id string for example '20090130' would be translated to
        /// a proper datetime of '01-30-2009 00:00:00'. If the string is empty than we default to the passed
        /// in <paramref name="defaultIfNull"/>.
        /// </summary>
        /// <param name="str">The string</param>
        /// <param name="defaultIfNull">The default null.</param>
        /// <returns>Returns the datetime.</returns>
        public static DateTime TryGetDateFromDateDimensionId(this string str, DateTime defaultIfNull)
        {
            if (String.IsNullOrEmpty(str)) return defaultIfNull;
            return DateTime.Parse(str.Substring(4, 2) + "/" + str.Substring(6, 2) + "/" + str.Substring(0, 4));
        }
    }
}
4

1 に答える 1

15

SSISを使用してYahooFinanceChartWebサイトからティッカー価格履歴をインポートします。

SSISを使用して、ティッカーシンボルの価格履歴をYahooChartWebサイトからデータベースにインポートする別の方法があります。SSIS 2008 R2これは、データベースを使用して作成されたサンプルパッケージです。SQL Server 2008 R2

データベースに接続する接続マネージャー/データソースをSO_14797886.dtsx使用して(たとえば)という名前のSSISパッケージBusiness Intelligence Development Studio (BIDS)を作成します。このサンプルでは、​​インスタンスを実行しているローカルマシンのデータベースに接続するOLE DBデータソースを使用します。はマシン名、はインスタンス名です。OLEDB_Sora.dsSoraKIWI\SQLSERVER2008R2KIWISQLSERVER2008R2

データベースで以下のスクリプトを実行して、2つのテーブルを作成します。

  • dbo.TickerSymbolsには、ティッカーシンボルのリストと、価格ファイルをインポートする開始日と終了日、およびインポートの解像度に関する情報が保持されます。解像度には、 ;のようdな値を含めることができます。のために; のために; および。_daywweeklymmonthlyyyearly

  • dbo.TickerPriceHistoryには、Yahoo FinanceChartWebサイトからダウンロードしたシンボルの価格履歴情報が保持されます。

  • 挿入スクリプトは、ティッカーシンボルの4つのレコードを追加しましたAAPLApple); MSFTMicrosoft); GOOGGoogle); およびYHOOYahoo)。各レコードは、異なる日付範囲と解像度で設定されます。

テーブルを作成し、いくつかのティッカーシンボルデータを挿入するスクリプト:

CREATE TABLE dbo.TickerSymbols
(
        Id int IDENTITY(1,1) NOT NULL
    ,   Symbol varchar(10) NOT NULL
    ,   StartDate datetime NOT NULL
    ,   EndDate datetime NOT NULL
    ,   Resolution char(1) NOT NULL
    ,   CONSTRAINT [PK_TickerSymbols] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO

CREATE TABLE dbo.TickerPriceHistory
(
        Id int IDENTITY(1,1) NOT NULL
    ,   Symbol varchar(10) NOT NULL
    ,   PriceDate datetime NOT NULL
    ,   PriceOpen numeric(18,2) NULL
    ,   PriceHigh numeric(18,2) NULL
    ,   PriceLow numeric(18,2) NULL
    ,   PriceClose numeric(18,2) NULL
    ,   Volume bigint NULL
    ,   AdjustmentClose numeric(18,2) NULL
    ,   CONSTRAINT [PK_TickerPriceHistory] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO

INSERT INTO dbo.TickerSymbols (Symbol, StartDate, EndDate, Resolution) VALUES
        ('AAPL', '2012-02-01', '2012-02-04', 'd')
    ,   ('GOOG', '2013-01-01', '2013-01-31', 'w')
    ,   ('MSFT', '2012-09-01', '2012-11-30', 'm')
    ,   ('YHOO', '2012-01-01', '2012-12-31', 'y')
    ;
GO

SSISパッケージで、次の変数を作成します。

  • EndDate:パッケージは、このデータ型の変数を使用DateTimeして、レコードセットリストでループスルーされているシンボルの終了日を保持します。

  • FileExtension:このデータ型の変数はString、ダウンロードされたファイルに使用するファイル拡張子を保持します。これはオプションです。

  • FileName:このデータ型の変数はString、特定のシンボルのファイル名を保持します。名前は、以前にダウンロードしたファイルが上書きされないように、タイムスタンプに基づいて生成されます。変数をクリックし、F4キーを押してプロパティを表示します。EvaluateAsExpressionプロパティをに変更しますTrue式に対して省略記号ボタンをクリックして、式ビルダーを開きます。を次の値に設定します。この式は、のような値に評価されます。ここで、MSFTはシンボルであり、残りの情報はフォーマットのパッケージ開始時刻であり、ファイル拡張子です。ExpressionMSFT_20130210_092519.csvyyyMMdd_hhmmss.csv

@ [User :: Symbol] + "_" +(DT_WSTR、4)YEAR(@ [System :: StartTime])+ RIGHT( "00" +(DT_WSTR、2)MONTH(@ [System :: StartTime])、 2)+ RIGHT( "00" +(DT_WSTR、2)DAY(@ [System :: StartTime])、2)+ "_" + RIGHT( "00" +(DT_WSTR、2)DATEPART( "hh"、@ [System :: StartTime])、2)+ RIGHT( "00" +(DT_WSTR、2)DATEPART( "mi"、@ [System :: StartTime])、2)+ RIGHT( "00" +(DT_WSTR、2 )DATEPART( "ss"、@ [System :: StartTime])、2)+ @ [User :: FileExtension]

  • FilePath:このデータ型の変数はString、特定のシンボルのダウンロードされたファイルの完全なパスを保持します。変数をクリックし、F4キーを押してプロパティを表示します。EvaluateAsExpressionプロパティをに変更しますTrue。式に対して省略記号ボタンをクリックして、式ビルダーを開きます。Expressionを値に設定します@[User::RootFolder] + "\\" + @[User::FileName]。このエクスプレスを使用して

  • Resolution:パッケージは、このデータ型の変数を使用Stringして、レコードセットリストでループスルーされているシンボルの解決情報を保持します。

  • RootFolder:このデータ型の変数はString、ファイルのダウンロード先となるルートフォルダーを保持します。

  • SQL_GetSymbols:このデータ型の変数にはString、データベースからティッカーシンボル情報をフェッチするためのT-SQLクエリが含まれます。値をに設定しますSELECT Symbol, StartDate, EndDate, Resolution FROM dbo.TickerSymbols

  • StartDate:パッケージは、このデータ型の変数を使用DateTimeして、レコードセットリストでループスルーされるシンボルの開始日を保持します。

  • Symbol:パッケージは、このデータ型の変数を使用Stringして、レコードセットリスト内の各レコードをループするときにティッカーシンボルを保持します。

  • SymbolsList:パッケージは、このデータ型の変数を使用Objectして、データベースに格納されているティッカーシンボルの結果セットを保持します。

  • URLYahooChart:このデータ型の変数はString、クエリ文字列の適切な値を入力するためのプレースホルダーを含むYahoo FinanceChartWebサイトへのURLを保持します。値をに設定しますhttp://ichart.finance.yahoo.com/table.csv?s={0}&a={1}&b={2}&c={3}&d={4}&e={5}&f={6}&g={7}&ignore=.csv

変数

パッケージで、[接続マネージャー]タブを右クリックし、 [Flat File Connection...

フラットファイル接続マネージャー

Flat File Connection Manager EditorGeneralページで、次のアクションを実行します。

  • 名前をに設定しますFILE_TickerPriceHistory

  • 説明をに設定しますRead the ticker symbol price history.

  • すでにサンプルファイルがある場合は、ファイルの場所をポイントします。SSISは、ファイル内のデータから設定を推測します。この場合、私はすでにURLhttp://ichart.finance.yahoo.com/table.csv?s=MSFT&a=9&b=1&c=2012&d=11&e=30&f=2012&g=m&ignore=.csvをナビゲートしてファイルをダウンロードし、その名前で保存しましたC:\Siva\StackOverflow\Files\14797886\Data\\MSFT_20130210_092519.csv

  • Formatがに設定されていることを確認してくださいDelimited

  • ヘッダー行の区切り文字がに設定されていることを確認してください{CR}{LF}

  • チェックボックスをオンにしますColumn names in the first data row

  • [列]ページをクリックします

Flat FileConnectionManagerエディター-一般

Flat File Connection Manager EditorColumnsページで、行区切り文字がに設定され、列区切り文字がに設定されていることを確認します。[詳細ページ]をクリックします。{LF}Comma {,}

Flat FileConnectionManagerエディター-列

Flat File Connection Manager EditorAdvancedページでは、ファイル情報に基づいて列が作成されます。列名がデータベース内の名前と一致するように、以下に示すように値を変更します。このようにして、列のマッピングが簡単になります。最後の列を除くすべての列で、ColumnDelimiterをに設定する必要があります。Lsst列では、ColumnDelimiterをに設定する必要があります。Comma {,}{LF}

Column              Data type                            DataPrecision DataScale
------------------- ------------------------------------ ------------- ---------
PriceDate           date [DT_DATE]
PriceOpen           numeric [DT_NUMERIC]                      18          2
PriceHigh           numeric [DT_NUMERIC]                      18          2
PriceLow            numeric [DT_NUMERIC]                      18          2
PriceClose          numeric [DT_NUMERIC]                      18          2
Volume              eight-byte unsigned integer [DT_UI8]      
AdjustmentClose     numeric [DT_NUMERIC]                      18          2

Flat FileConnectionManagerエディター-高度

これで、パッケージの下部に両方の接続マネージャーが表示されます。

作成された接続マネージャー

[コントロールフローExecute SQL Task]タブにドラッグアンドドロップし、 [全般]タブで次のアクションを実行します。

  • 名前をに設定しますGet symbols from database
  • 説明をに設定しますFetch the list of symbols and its download settings from database.
  • クエリがレコードセットを返すため、ResultSetをに設定します。Full result set
  • ConnectionTypeをに設定しますOLE DB
  • 接続をに設定しますOLEDB_Sora
  • SQLSourceTypeVariableから選択
  • SourceVariableUser::SQL_GetSymbolsから選択
  • [結果セット]ページをクリックします。

SQLタスクの実行-一般

[ SQLタスクの実行]の[結果セット]ページで、[追加]をクリックし、[結果名]を結果セットのインデックスを示すように設定します。変数名から選択して、結果セットをオブジェクト変数に格納します。0User::SymbolsList

SQLタスクの実行-結果セット

Foreachループコンテナをドラッグアンドドロップして、SQL実行タスクの後に配置します。SQLタスクの実行の緑色の矢印をForeachループコンテナーに接続します。Foreach Loop Containerをダブルクリックして、ForeachLoopEditorを表示します。以下に示すように、 ForEachループエディターを構成します。

ForEachループエディター-コレクション

ForEachループエディターの[変数マッピング]ページで、次のように構成します。

ForEachループエディター-変数マッピング

Script TaskForEachループコンテナ内をドラッグアンドドロップします。スクリプトタスクをダブルクリックして、スクリプトタスクエディタを開きます。スクリプトタスクエディタの[スクリプト]ページで、に対して省略記号ボタンをクリックしReadOnlyVariables、以下にリストされている変数を選択します。これらはスクリプトタスクコード内で使用する必要があります。

  • User :: EndDate
  • User :: FileExtension
  • User :: FileName
  • User :: FilePath
  • ユーザー::解決
  • User :: RootFolder
  • User :: StartDate
  • ユーザー::シンボル
  • User :: URLYahooChart

スクリプトタスクエディタ-スクリプト

スクリプトタスクエディタEdit Script...のボタンをクリックして、以下のコードを入力します。コードを入力したら、スクリプトタスクエディターを閉じます。

C#のスクリプトタスクコード:

using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Net;

namespace ST_5fa66fe26d20480e8e3258a8fbd16683.csproj
{
    [System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {
        #region VSTA generated code
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
        #endregion

        public void Main()
        {
            try
            {
                string symbol = Dts.Variables["User::Symbol"].Value.ToString();
                DateTime startDate = Convert.ToDateTime(Dts.Variables["User::StartDate"].Value);
                DateTime endDate = Convert.ToDateTime(Dts.Variables["User::EndDate"].Value);
                string resolution = Dts.Variables["User::Resolution"].Value.ToString();
                string urlYahooChart = Dts.Variables["User::URLYahooChart"].Value.ToString();

                string rootFolder = Dts.Variables["User::RootFolder"].Value.ToString();;
                string fileExtension = Dts.Variables["User::FileExtension"].Value.ToString();
                string fileName = Dts.Variables["User::FileName"].Value.ToString();
                string downloadPath = Dts.Variables["User::FilePath"].Value.ToString();

                if (!System.IO.Directory.Exists(rootFolder))
                    System.IO.Directory.CreateDirectory(rootFolder);

                urlYahooChart = string.Format(urlYahooChart
                                        , symbol
                                        , startDate.Month
                                        , startDate.Day
                                        , startDate.Year
                                        , endDate.Month
                                        , endDate.Day
                                        , endDate.Year
                                        , resolution);

                bool refire = false;
                Dts.Events.FireInformation(0, string.Format("Download URL of {0}", symbol), urlYahooChart, string.Empty, 0, ref refire);

                WebClient webClient = new WebClient();
                webClient.DownloadFile(urlYahooChart, downloadPath);

                Dts.TaskResult = (int)ScriptResults.Success;
            }
            catch (Exception ex)
            {
                Dts.Events.FireError(0, "Download error", ex.ToString(), string.Empty, 0);
            }
        }
    }
}

スクリプトタスクの後で、 ForeachループコンテナData Flow Task内にドラッグアンドドロップします。スクリプトタスクからの緑色の矢印をデータフロータスクに接続します。[制御フロー]タブは次のようになります。

制御フロータブ

データフロータスクで、フラットファイルソースをドラッグアンドドロップし、以下に示すように構成して、価格履歴のCSVファイルを読み取ります。

フラットファイルソース-接続マネージャー

フラットファイルソース-列

をドラッグアンドドロップして、式で名前がDerived Column Transformation付けられた新しい列を作成し、データパイプラインにシンボルを追加します。Symbol(DT_STR,10,1252)@[User::Symbol]

派生列変換

OLE DB変換先をドラッグアンドドロップし、以下に示すように構成して、データをデータベースに挿入します。

OLEDB変換先-接続マネージャー

OLEDB変換先-マッピング

[データフロー]タブは次のようになります。

[データフロー]タブ

パッケージを実行する前に、フォルダー内にファイルがないためにデザインタイムビューで警告やエラーが発生しないように、いくつかの変更を加える必要があります。

フラットファイル接続マネージャーFILE_TickerPriceHistoryをクリックし、を押しF4てプロパティを表示します。DelayValidationプロパティをに変更しますTrue。これにより、実行時にファイルの存在の検証が確実に行われます。式に対して省略記号ボタンをクリックし、プロパティを値に設定します。これにより、各ファイルがWebサイトからダウンロードされるときに、ファイルパスが変更されます。ConnectionString@[User::FilePath]

Flat FileConnectionManager-遅延検証

データフロータスクをクリックし、を押しF4てプロパティを表示します。DelayValidationプロパティをに変更しますTrue。これにより、実行時にファイルの存在の検証が確実に行われます。

データフロータスク-DelayValidation

[データフロー]タブに移動し、[フラットファイルソース]をクリックして、を押しF4てプロパティを表示します。ValidateExternalMetadataプロパティをに変更しますFalse。これにより、実行時にフラットファイルの存在の検証が確実に行われます。

フラットファイルソース-ValidateExternalMetadata

C:\Siva\StackOverflow\Files\14797886ダウンロードしたファイルが保存されるフォルダに移動してみましょう。空です。フォルダは空である必要はありません。これは実行チェック用です。

空のフォルダをダウンロード

データベースに対して次のSQLステートメントを実行して、テーブル内のデータを確認します。2番目のテーブルは空である必要があります。

SELECT * FROM dbo.TickerSymbols;
SELECT * FROM dbo.TickerPriceHistory;

実行前のテーブルデータ

パッケージを実行します。すべてが正しく設定されている場合、パッケージは正常に実行され、表にリストされている各シンボルのファイルをダウンロードする必要があります。dbo.TickerSymbols

制御フローの実行

データフローの実行

ファイルはフォルダに正常に保存されているはずですC:\Siva\StackOverflow\Files\14797886。各ファイルは、パッケージで提供されている式に基づいて適切に名前が付けられていることに注意してください。

ダウンロードしたファイル

データベースに対して次のSQLステートメントを実行して、テーブル内のデータを確認します。これで、Webサイトからダウンロードした価格ファイルのデータがテーブルdbo.TickerPriceHistoryに含まれるはずです。

SELECT * FROM dbo.TickerPriceHistory;

実行後のテーブルデータ

上記のサンプルパッケージは、特定のティッカーシンボルのリストについてYahoo Finance Chart Webサイトから価格ファイルをダウンロードし、データベースにロードする方法を示しています。

于 2013-02-10T17:02:00.350 に答える