以下のSSISスクリプトタスクは、ティッカーシンボルと取得したい日付範囲を受け取り、価格履歴の抽出に使用できるCSV形式のダウンロードを返しますが、機能せず、理由がわかりません。このSSISのよく考えられた概念に関する完全な情報は、以下のリンクにあります。
SSIS / ETLの例–Yahooのエクイティと投資信託の価格履歴
以下のリンクからサンプルSSISパッケージをダウンロードできます。
次の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));
}
}
}