<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>icocTech &#187; ohshima</title>
	<atom:link href="http://icoctech.icoc.co.jp/blog/?author=5&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://icoctech.icoc.co.jp/blog</link>
	<description>株式会社アイコック　システム部の技術関連ブログ</description>
	<lastBuildDate>Mon, 01 Aug 2016 03:45:32 +0000</lastBuildDate>
	<language>ja</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.0</generator>
	<item>
		<title>SQLServerで複数レコードの文字列を結合</title>
		<link>http://icoctech.icoc.co.jp/blog/?p=998</link>
		<comments>http://icoctech.icoc.co.jp/blog/?p=998#comments</comments>
		<pubDate>Fri, 08 Jan 2016 12:23:27 +0000</pubDate>
		<dc:creator><![CDATA[ohshima]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icoctech.icoc.co.jp/blog/?p=998</guid>
		<description><![CDATA[SQLServerにて、複数レコードの文字列を 結合して、単一フィールドの値として取得します。 例：グループに所属するユーザーを列挙する 以下の様なテーブルでユーザーとユーザーが所属するグループを管理している場合。 テー [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>SQLServerにて、複数レコードの文字列を<br />
結合して、単一フィールドの値として取得します。</p>
<p>例：グループに所属するユーザーを列挙する<br />
以下の様なテーブルでユーザーとユーザーが所属するグループを管理している場合。</p>
<p>テーブル名：test_user（ユーザーマスタ）<br />
<a href="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000001.png"><img class="alignnone size-full wp-image-1000" src="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000001.png" alt="WS000001" width="235" height="93" /></a></p>
<p>テーブル名：test_group（グループマスタ）<br />
<a href="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000002.png"><img class="alignnone size-full wp-image-1001" src="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000002.png" alt="WS000002" width="224" height="66" /></a></p>
<p>テーブル名；group_user（グループとユーザーの連結情報）<br />
<a href="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000003.png"><img class="alignnone size-full wp-image-1002" src="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000003.png" alt="WS000003" width="227" height="95" /></a></p>
<p>グループに所属するユーザーを取得しようと考える場合、<br />
以下の様なSQLになるかと思います。</p>
<pre><code>
 SELECT A.group_code, A.group_name, C.user_name
 FROM test_group A
 INNER JOIN group_user B ON A.group_code = B.group_code
 INNER JOIN test_user C ON B.user_code = C.user_code
 ORDER BY A.group_code, C.user_code
 </code></pre>
<p>結果はこの様になります。<br />
<a href="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000004.png"><img class="alignnone size-medium wp-image-1003" src="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000004-300x87.png" alt="WS000004" width="300" height="87" /></a></p>
<p>これはこれでいいのですが、<br />
ユーザー名を羅列して、１フィールドの値として扱いたい場合、<br />
ストアドプロシージャでカーソルを利用し、<br />
user_nameを結合する必要が有ります。<br />
もしくは、プログラムでこの結果を取得した後、<br />
ループ処理を行うなど、何かしらの処理が必要になります。</p>
<p>もし、結合した結果を取得できれば、<br />
上記の様な処理を記述する必要もなくなります。</p>
<p>SQLServerには結果をXML形式で取得する、<br />
FOR XML句という記述形式が有ります。<br />
<a title="FOR XML (SQL Server)" href="https://msdn.microsoft.com/ja-jp/library/ms178107(v=sql.120).aspx" target="_blank">FOR XML (SQL Server)</a><br />
上記の例を使用し、以下のSQLを実行します。</p>
<pre><code>
 SELECT A.group_code, A.group_name,
 (SELECT '・' + D.user_name
 FROM test_group B
 INNER JOIN group_user C
 ON B.group_code = C.group_code
 INNER JOIN test_user D
 ON C.user_code = D.user_code
 WHERE B.group_code = A.group_code
 ORDER BY D.user_code
 FOR XML PATH(''),TYPE).value('.', 'VARCHAR(MAX)') AS group_user_name
 FROM test_group as A
 </code></pre>
<p>結果はこの様になります。<br />
<a href="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000005.png"><img class="alignnone size-medium wp-image-1004" src="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000005-300x55.png" alt="WS000005" width="300" height="55" /></a></p>
<p>普通の結合では2レコードになるGroupAのユーザーを<br />
1レコードで取得しています。</p>
<p>FOR XML句を使い、XML形式で出力したSQLの結果に対して、<br />
value()メソッドを使い、Varchar型で取得し、<br />
サブクエリとして呼び出しております。</p>
<p>サブクエリでの処理について解説します。<br />
まずは、SELECT ～ ORDER BY D.user_codeまでは普通のSQLです。<br />
SELECT句で「&#8217;・&#8217;」とuser_nameを結合しており、<br />
WHEREでサブクエリ内のgroup_codeを指定しておりますので、<br />
出力文字列はA.group_code=&#8217;G001&#8217;のときは、「・アイチャン」「・ワークン」<br />
A.group_code=&#8217;G002&#8217;のときは「・アイコック 太郎」となります。</p>
<p>通常のSQLで処理し、行で取得した際には、「・アイチャン」「・ワークン」は<br />
2レコードで出力されますが、<br />
FOR XML句を使用しておりますので、XML形式で出力されます。<br />
PATH(&#8221;)として、属性を付けておりませんので、<br />
出力内容はこの様になります。<br />
<a href="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000006.png"><img class="alignnone size-full wp-image-1005" src="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000006.png" alt="WS000006" width="246" height="36" /></a></p>
<p>もし、PATH(&#8216;name&#8217;)と属性名を与えた場合、出力されるXMLはこの様になります。<br />
<a href="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000007.png"><img class="alignnone size-full wp-image-1006" src="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2016/01/WS000007.png" alt="WS000007" width="281" height="47" /></a><br />
（ちなみに、属性名を付けていても、上記のSQLの結果は変わらないので、属性名を付ける付けないはお好みで良いかと思います）</p>
<p>FOR XML句で出力した値はXML形式で出力されるため、他のフィールドとは扱いが異なりますので、<br />
value()メソッドを使い、通常のSQL型に変換します。<br />
サブクエリを表す()の後に「.value(&#8216;.&#8217;, &#8216;VARCHAR(MAX)&#8217;)」と記述しております。<br />
value()メソッドの第一引数はXQuery式で、第二引数はSQL型となります。</p>
<p>第一引数の「&#8217;.&#8217;」はXQuery式「self::node()」の省略形、<br />
第二引数では、ユーザー名を扱い、出力文字数の制限をしたくないので、<br />
VARCHAR(MAX)としており、<br />
出力されたXML形式のデータからvalue値を取得するため、<br />
属性が指定されていようが関係なく、「・アイチャン・ワークン」といったvalue値を取得し、<br />
第二引数で指定されたVARCHARとして、SQL型の結果を返します。<br />
<a title="value() メソッド (xml データ型)" href="https://msdn.microsoft.com/ja-jp/library/ms178030(v=sql.120).aspx" target="_blank">value() メソッド (xml データ型)</a></p>
<p>こうすることで、複数レコードを結合したデータを単一のレコードとして扱う事が可能になります。</p>
<p>ユーザー名をカンマ区切りで表示したい場合なんかは、<br />
サブクエリのSELECT句を「SELECT user_name + &#8216;,&#8217;」と記述することで<br />
可能となります。<br />
ただし、文字列の最後にカンマがついている状態なので、<br />
SUBSTRING()メソッドを使い、最後の文字を除外するなどの一手間は必要になります。</p>
<p>サブクエリをスカラー値関数として作成し、<br />
抽出条件を引数として指定できるようにしておけば、<br />
上記のカンマ区切りを実現するためのSUBSTRING()メソッドも書きやすくなるのではないかと思います。</p>
<p>文章で書くと難しくなりがちですが、<br />
文字列を結合する程度の事であれば、簡単にできるため、<br />
使う機会が有れば、試してみてはいかがでしょうか。</p>
]]></content:encoded>
			<wfw:commentRss>http://icoctech.icoc.co.jp/blog/?feed=rss2&#038;p=998</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LDAPサーバへのユーザーの一括登録について</title>
		<link>http://icoctech.icoc.co.jp/blog/?p=921</link>
		<comments>http://icoctech.icoc.co.jp/blog/?p=921#comments</comments>
		<pubDate>Fri, 16 Oct 2015 00:57:27 +0000</pubDate>
		<dc:creator><![CDATA[ohshima]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icoctech.icoc.co.jp/blog/?p=921</guid>
		<description><![CDATA[LDAPのユーザー情報はLDIFというファイル形式でのインポート・エクスポートが 一般的で、CSVでのインポート・エクスポートはあまりサポートされていません。 LDIFファイルでは、ユーザーの情報を複数行で記述します。  [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>LDAPのユーザー情報はLDIFというファイル形式でのインポート・エクスポートが<br />
一般的で、CSVでのインポート・エクスポートはあまりサポートされていません。<br />
LDIFファイルでは、ユーザーの情報を複数行で記述します。<br />
例を挙げれば、<br />
<code><br />
dn: cn=user1,ou=users,dc=icoc,dc=co,dc=jp<br />
cn: user1<br />
objectClass: organizationalRole<br />
objectClass: simpleSecurityObject<br />
userPassword: user1Password</code></p>
<p>dn: cn=user2,ou=users,dc=icoc,dc=co,dc=jp<br />
cn: user2<br />
objectClass: organizationalRole<br />
objectClass: simpleSecurityObject<br />
userPassword: user2Password</p>
<p>このような形式になります。<br />
dnからuserPasswordまでで1ユーザーの情報となっています。</p>
<p>ある程度の数のユーザーを一括で登録したい場合、<br />
CSVは横方向に情報を持つため、EXCELなどを使用することで<br />
複数ユーザーに対して、一括での追加、編集が容易に行えますが、<br />
LDIFでは縦方向に情報を持つので、複数ユーザーに対しての一括追加、編集は<br />
CSVに比べると、容易には行えません。</p>
<p>これを考慮すると、<br />
データの作成はEXCELなどを用いて作成し、<br />
インポートを行う時にLDIFに変換できれば、<br />
大量のユーザーを扱う際でも手間ではなくなります。</p>
<p>そこでCSVをLDIFに変換するツールは無いものかと探したところ、<br />
csv2ldif2というスクリプトがありました。<br />
<a href="http://sourceforge.net/projects/csv2ldif2/">http://sourceforge.net/projects/csv2ldif2/</a></p>
<p>上記URLから「csv2ldif2-1.1.tar.gz」をダウンロードします。<br />
圧縮形式はtar.gzなので、Windowsで使用する場合、<br />
解凍ソフトを用いる必要があります。</p>
<p>ファイル解凍後、フォルダが作成されますので任意の位置に配置します。<br />
コマンドラインからは以下の様に実行します。<br />
<code><br />
cd フォルダの配置場所<br />
perl csv2ldif2.pl "ou=users,dc=icoc,dc=co,dc=jp" &lt; tsuika.csv &gt; tsuika.ldif<br />
</code></p>
<p>perlで書かれているため、perlを宣言後、スクリプトファイルを指定します。<br />
ファイル名の後、LDAP上でユーザーを配置するディレクトリを指定します。<br />
上記の&#8221;ou=users,dc=icoc,dc=ac,dc=jp&#8221;という箇所です。<br />
その後、変換元のファイル名を記述します。<br />
このとき必ず<code>&lt;&gt;</code>で囲む必要が有ります。<br />
最後に変換後のファイル名を記述し、実行すると、変換が行われます。</p>
<p>例えば、以下の内容を持つCSVを変換すると、<br />
<code><br />
cn,objectClass,objectClass,userPassword<br />
user1,organizationalRole,simpleSecurityObject,user1Password<br />
</code><br />
<code><br />
dn: cn=user1,ou=users,dc=icoc,dc=co,dc=jp<br />
cn: user1<br />
objectClass: organizationalRole<br />
objectClass: simpleSecurityObject<br />
userPassword: user1Password<br />
</code></p>
<p>このように変換されます。<br />
変換したLDIFをLDAPへインポートすれば、ユーザーの一括登録が行えます。</p>
]]></content:encoded>
			<wfw:commentRss>http://icoctech.icoc.co.jp/blog/?feed=rss2&#038;p=921</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQLServerエージェントが使用するアカウント</title>
		<link>http://icoctech.icoc.co.jp/blog/?p=836</link>
		<comments>http://icoctech.icoc.co.jp/blog/?p=836#comments</comments>
		<pubDate>Fri, 31 Jul 2015 07:53:52 +0000</pubDate>
		<dc:creator><![CDATA[ohshima]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icoctech.icoc.co.jp/blog/?p=836</guid>
		<description><![CDATA[SQLServerエージェントを使用すると、 時間を指定して、exeファイルが実行できます。 この設定を行う際の注意することがあり、 スケジュール実行するexeが外部ファイル（例えばログファイルなど）に書き込みを行う場合 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>SQLServerエージェントを使用すると、<br />
時間を指定して、exeファイルが実行できます。</p>
<p>この設定を行う際の注意することがあり、<br />
スケジュール実行するexeが外部ファイル（例えばログファイルなど）に書き込みを行う場合や、<br />
フォルダ内にファイルを生成する場合には、<br />
SQLServerエージェントが対象となるファイルやフォルダに対して、<br />
アクセス許可を有する必要が有ります。</p>
<p>アクセス許可の編集は、対象のファイルやフォルダのプロパティで行えますが、<br />
その際、必要になる情報としてユーザー名が必要になります</p>
<p>通常のユーザーであれば、ユーザー名が分からなくても、<br />
アクセス許可の編集画面でユーザーの検索が可能なので、問題は有りませんが、<br />
SQLServerエージェントが使用するログオンユーザーは上記の検索では表示されません。</p>
<p>では、どの様にSQLServerエージェントのユーザーを確認するのかというと、<br />
「SQLServer構成マネージャー」を使用します。</p>
<p><a href="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2015/07/WS000000.png"><img class="alignnone size-medium wp-image-839" src="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2015/07/WS000000-300x85.png" alt="WS000000" width="300" height="85" /></a></p>
<p>これはSQLServer構成マネージャーを起動し、左側のペインからSQLServerのサービスを選択した画面です。<br />
右側のペインにSQLServerが使用しているサービスが表示されています。<br />
この最下行に「SQL Serve エージェント（MSSQLSERVER)」があり、その隣の列にログオンという列が有ります。<br />
このログオン列に記載されている内容がサービスが使用するログオンアカウントであり、<br />
アクセス許可で使用するユーザー名となります</p>
<p><a href="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2015/07/WS000002.png"><img class="alignnone size-medium wp-image-838" src="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2015/07/WS000002-300x154.png" alt="WS000002" width="300" height="154" /></a></p>
<p><a href="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2015/07/WS000003.png"><img class="alignnone size-medium wp-image-840" src="http://icoctech.icoc.co.jp/blog/wp-content/uploads/2015/07/WS000003-300x153.png" alt="WS000003" width="300" height="153" /></a></p>
<p>調べたログオンアカウントをアクセス許可のユーザー検索で名前の確認をすることで、<br />
アクセス許可にユーザーの追加が可能になります</p>
<p>追加後は、他のアカウント同様に権限の設定を行います。</p>
]]></content:encoded>
			<wfw:commentRss>http://icoctech.icoc.co.jp/blog/?feed=rss2&#038;p=836</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DataTable間の操作について</title>
		<link>http://icoctech.icoc.co.jp/blog/?p=587</link>
		<comments>http://icoctech.icoc.co.jp/blog/?p=587#comments</comments>
		<pubDate>Wed, 12 Nov 2014 08:31:34 +0000</pubDate>
		<dc:creator><![CDATA[ohshima]]></dc:creator>
				<category><![CDATA[プログラム]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://icoctech.icoc.co.jp/blog/?p=587</guid>
		<description><![CDATA[今回はC#で開発した際の話です。 あるDataTableから必要なフィールドのみを選択し、 新規のDataTableを作る必要が有りました。 そこで、今回は以下の様に対応しました。 元となるDataTable：table [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>今回はC#で開発した際の話です。</p>
<p>あるDataTableから必要なフィールドのみを選択し、<br />
新規のDataTableを作る必要が有りました。</p>
<p>そこで、今回は以下の様に対応しました。</p>
<p>元となるDataTable：table1<br />
必要なフィールドのみを持つ新規DataTable：table2<br />
必要なフィールドのインデックス：0,1,3,4,7</p>
<pre><code>
// 必要なフィールドの列名を配列化します。
string[] requiredColumns = {dt.Columns[0].ToString(),
                            dt.Columns[1].ToString(),
                            dt.Columns[3].ToString(),
                            dt.Columns[4].ToString(),
                            dt.Columns[5].ToString(),
                           };

// 元のテーブルから必要なフィールドのみを抽出して、テーブルを新規作成します。
System.Data.DataTable table2 = table1.DefaultView.ToTable(true, requiredColumns);
</code>
</pre>
<p>ToTableの最初の引数は、重複する行を含むかどうかをBool値で指定します。<br />
Trueなら重複しない行のみ格納され、Falseでは重複する行も格納されます。<br />
二つ目の引数は、抽出する列名を指定します。<br />
ここでは、事前に配列化しておいた変数をセットしました。</p>
<p>場合によっては、新規作成したテーブルの構造と値をそのまま別のテーブルで使用したい場合には、<br />
以下の様に行います。</p>
<pre><code>
// table2の構造と値をtable3へコピーします。
System.Data.DataTable table3 = table2.Copy();

//table2の構造のみをtable4へコピーします。
System.Data.DataTable table4 = table2.Clone();
</code>
</pre>
<p>Cloneは構造のみをコピーするので、<br />
table2と同じ構造を持ち、値は異なる、といったデータの保持が可能になります。</p>
<p>また、元のテーブルと同じ構造を持ち、元のテーブル特定行のみを移したい場合、<br />
ImportRow()メソッドを使用します。</p>
<pre><code>
System.Data.DataTable table4 = table2.Clone();
table4.ImportRow(table2.Rows[0]);
</code>
</pre>
<p>とすることで、table2の1行目のデータをtable4へインポートできます。</p>
]]></content:encoded>
			<wfw:commentRss>http://icoctech.icoc.co.jp/blog/?feed=rss2&#038;p=587</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DB内のオブジェクトを更新日が新しい順に取得</title>
		<link>http://icoctech.icoc.co.jp/blog/?p=609</link>
		<comments>http://icoctech.icoc.co.jp/blog/?p=609#comments</comments>
		<pubDate>Mon, 10 Nov 2014 13:43:45 +0000</pubDate>
		<dc:creator><![CDATA[ohshima]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[SQLServer]]></category>

		<guid isPermaLink="false">http://icoctech.icoc.co.jp/blog/?p=609</guid>
		<description><![CDATA[今回は、SQLServerに関する話です。 稼働中のシステムを改修し、本番環境へ反映する際に、 プログラムの入替のみではなく、 データベースの更新作業が必要なことがあります。 あまり考えたくありませんが、 例えば、テーブ [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>今回は、SQLServerに関する話です。</p>
<p>稼働中のシステムを改修し、本番環境へ反映する際に、<br />
プログラムの入替のみではなく、<br />
データベースの更新作業が必要なことがあります。</p>
<p>あまり考えたくありませんが、<br />
例えば、テーブルやビューにフィールドの追加や<br />
新しく作成したストアドプロシージャやユーザー関数を追加などです。</p>
<p>確実なのは、作業リストを作成し、<br />
改修した機能について、どのテーブル・ビューなどが改修されたか記録を取ることでしょう。</p>
<p>ただし、改修に時間が掛かったり、<br />
複数の機能改修をまとめて反映する際には、<br />
記録漏れが出ることも有ります。</p>
<p>これを回避するため、<br />
DB内のテーブル・ビュー・ユーザー関数を更新された順に取得したいと思います。</p>
<p>該当のDBに対し、以下のSQLを実行します。</p>
<pre><code>
SELECT name, modify_date
FROM sys.objects
WHERE type in ('V', 'U', 'FN', 'P')
ORDER BY modify_date desc
</code>
</pre>
<p>sys.objects はデータベース内のオブジェクトを管理しているテーブルです。</p>
<p>SELECT句にはオブジェクト名(name), 更新日(modify_date)を指定します。<br />
WHERE句には抽出する条件を指定します。<br />
今回は、新しく更新された順に、<br />
テーブル名・ビュー名・関数名・ストアドプロシージャが取得できればよいので、<br />
U：テーブル(ユーザー定義)<br />
V：ビュー<br />
FN：スカラー関数<br />
P：ストアドプロシージャ<br />
の4文字をtypeに指定します。<br />
ORDER BYにて、変更日の降順に出力すれば、<br />
変更日が新しい順に更新したテーブル等が確認できる、ということになります。</p>
<p>typeはこれ以外にもありますが、<br />
改修時に変更の頻度が高いのは上記の4つかな、と思いましたので、<br />
この様に記述しています。</p>
<p>sys.objectsについて、詳しくはこちらに記述が有ります。<br />
<a href="http://msdn.microsoft.com/ja-jp/library/ms190324.aspx" target="_blank">sys.objects（Transact-SQL）</a></p>
]]></content:encoded>
			<wfw:commentRss>http://icoctech.icoc.co.jp/blog/?feed=rss2&#038;p=609</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RAIDレベルについて</title>
		<link>http://icoctech.icoc.co.jp/blog/?p=580</link>
		<comments>http://icoctech.icoc.co.jp/blog/?p=580#comments</comments>
		<pubDate>Sun, 19 Oct 2014 22:30:30 +0000</pubDate>
		<dc:creator><![CDATA[ohshima]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icoctech.icoc.co.jp/blog/?p=580</guid>
		<description><![CDATA[RAID構成はRAIDレベルとも呼ばれ、 RAID0からRAID6まで7種類有ります。 すでにRAIDの構成を行ったことが有る方は、 「そんなに有ったか？」と思う方もいらっしゃるかもしれません。 と言うのも、現行のRAI [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>RAID構成はRAIDレベルとも呼ばれ、<br />
RAID0からRAID6まで7種類有ります。<br />
すでにRAIDの構成を行ったことが有る方は、<br />
「そんなに有ったか？」と思う方もいらっしゃるかもしれません。<br />
と言うのも、現行のRAIDコントローラやソフトウェアRAIDでは、<br />
RAID0, RAID1, RAID5, RAID6の扱いが主で<br />
RAID2～4は目にすることはまずありません。<br />
理由は様々ですが、実用性が無かったり、<br />
他の構成に比べ、メリットが少なかったりなどが原因です。</p>
<p>●各レベルの簡単な構成とメリット・デメリットについて。</p>
<p>・RAID0<br />
複数台のHDDにデータを分散して書き込む。<br />
RAID後の容量はHDDの最低容量 × HDD数となります。<br />
300GBと500GBのHDDをRAID0で構成すると、<br />
300GB × 2台 = 600GBとなります。<br />
500GBのHDDで未使用領域である200GB分は使用不可となります。<br />
（以降のRAIDレベルでも同様）</p>
<p>メリット<br />
・HDDの数が増えるに従い、アクセス速度が上がります。<br />
デメリット<br />
・冗長化されない<br />
・HDDが1台でも故障すれば、データは全て喪失します。</p>
<p>・RAID1<br />
複数台(偶数)のHDDに同時に同じ内容のデータを書き込む。<br />
RAID後の容量はHDDの最低容量 × HDD数 ÷ 2 となります。<br />
300GBと500GBのHDDをRAID1で構成すると、<br />
300GB × 2台 ÷ 2 = 300GBとなります。</p>
<p>メリット<br />
・故障がHDD数-1台であれば、正常なHDDと入れ替えることで、復旧が可能。<br />
デメリット<br />
・ディスク容量は実容量の半分となる。</p>
<p>・RAID5<br />
複数台のHDDにデータを分散して書き込み、その内1台には、誤り訂正用のデータを書き込む。<br />
この訂正用のデータが結果として、1ドライブ分のデータ容量を使用するため、<br />
RAID後の容量はHDDの最低容量 × (HDD数-1) となります。<br />
300GBと500GB（2台）のHDDをRAID5で構成すると、<br />
300GB × (3台-1）= 600GBとなります。</p>
<p>メリット<br />
・RAID0に比べて障害性が高く、RAID1に比べて容量が多い。<br />
デメリット<br />
・読込は早いが、書込は遅い<br />
・HDDが1台壊れても使用できるが、信頼性は低下し、アクセス速度も低下する。</p>
<p>以上、使用頻度が高い3レベルについて簡単に触れました。</p>
<p>RAIDは便利な仕組みですが、目的に沿った選択をしないと、デメリットに悩まされることにもなります。</p>
<p>他にも、RAID6といった今回記載していないレベルや、<br />
RAID0とRAID1を組み合わせたRAID0 + 1やRAID1+0 なども存在しますが、<br />
そちらについては、また機会があれば。</p>
]]></content:encoded>
			<wfw:commentRss>http://icoctech.icoc.co.jp/blog/?feed=rss2&#038;p=580</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RAIDの機能について</title>
		<link>http://icoctech.icoc.co.jp/blog/?p=526</link>
		<comments>http://icoctech.icoc.co.jp/blog/?p=526#comments</comments>
		<pubDate>Fri, 26 Sep 2014 08:31:08 +0000</pubDate>
		<dc:creator><![CDATA[ohshima]]></dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://icoctech.icoc.co.jp/blog/?p=526</guid>
		<description><![CDATA[RAIDとは複数のHDDを用いて1つのHDDとして扱うことで、 ディスクの故障に対する耐性やデータ書き込み処理の高速化を 実現する技術であることは、前回の記事で少しだけ触れました。 前回はRAIDを提供するハードウェアと [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>RAIDとは複数のHDDを用いて1つのHDDとして扱うことで、<br />
ディスクの故障に対する耐性やデータ書き込み処理の高速化を<br />
実現する技術であることは、前回の記事で少しだけ触れました。</p>
<p>前回はRAIDを提供するハードウェアとソフトウェアについて、<br />
記しましたので、<br />
今回は、RAID構成を話す予定でしたが、<br />
その前に、RAIDにより提供される機能について話を行いたいと思います。</p>
<p>RAIDにより提供される機能は<br />
大きく二つあります。</p>
<p>1つはHDD故障への耐性です。<br />
通常、HDDが1台しかないと、<br />
HDDの故障とデータの喪失はほぼ同意ですが、<br />
HDDを複数配置して冗長化することにより<br />
もしHDDの一つに故障が発生した場合でも、<br />
残りのHDDに故障が無ければ、データの損失は無く、<br />
故障したHDDを正常なHDDに交換することで、<br />
故障したHDDに配置されていたデータを復元できます。<br />
またRAIDコントローラによっては、<br />
サーバやNASの電源を入れたまま、HDDを交換できる機能である<br />
ホットスワップを有する物もあります。<br />
また、これとは別に、予備のHDDを機器に接続しておいて、<br />
故障が発生した際には、予備のHDDを使用する機能を<br />
ホットスペアといいます。</p>
<p>もう一つはデータ処理の高速化です。<br />
ファイルが一つあったとして、<br />
これがHDDに保存される際には、<br />
いくつものブロックに分けられます。</p>
<p>ファイルA = ブロックA1 + ブロックA2 + ブロックA3 ＋ …… + ブロックn</p>
<p>これをブロック単位でHDDに保存・読込を行います。<br />
1つのHDDに対して、ブロックA1～ブロックnまで配置した場合と<br />
2つのHDDに対して、ブロックA1～ブロックnまでを分散させて配置した場合、<br />
HDD1台当たりのブロック数は後者の方が少ないため、<br />
データへのアクセス速度などが上がります。</p>
<p>次回はRAIDレベルなど話をしたいと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://icoctech.icoc.co.jp/blog/?feed=rss2&#038;p=526</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RAIDって何？</title>
		<link>http://icoctech.icoc.co.jp/blog/?p=458</link>
		<comments>http://icoctech.icoc.co.jp/blog/?p=458#comments</comments>
		<pubDate>Tue, 16 Sep 2014 10:04:56 +0000</pubDate>
		<dc:creator><![CDATA[ohshima]]></dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://icoctech.icoc.co.jp/blog/?p=458</guid>
		<description><![CDATA[以前、ESXiのインストールを行った際にハマった記事に 少しだけ書いたRAIDを今回のテーマにしたいと思います。 RAIDとは、複数のHDDを1つのHDDのように認識・表示させる技術です。 なぜ、この様な事を行うのか。  [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>以前、ESXiのインストールを行った際にハマった記事に<br />
少しだけ書いたRAIDを今回のテーマにしたいと思います。</p>
<p>RAIDとは、複数のHDDを1つのHDDのように認識・表示させる技術です。<br />
なぜ、この様な事を行うのか。<br />
これは、システムにハードディスクが一つしかない場合、<br />
ハードディスクが壊れたとき、対応が取れない、というのが、大きな要因です。<br />
また、この他にも、一つのデータを複数のハードディスクに分けて書き込むことが<br />
可能になるため、データ書き込みの高速化も実現可能になります。</p>
<p>主に、企業でサーバやストレージに利用されている技術でしたが、<br />
HDDレコーダーやBlu-rayレコーダーの普及に合わせて、<br />
NAS（ネットワークハードディスクの一種）が普及したため、<br />
消費者向けとしても関連のある技術となりました。</p>
<p>さて、RAIDにはハードウェアRAIDとソフトウェアRAIDがあります。<br />
ハードウェアRAIDはRAIDコントローラや<br />
マザーボード上のチップにコントローラが含まれているオンボードRAIDなどがあります。<br />
（オンボードRAIDはRAIDコントローラに比べて、機能制限があることが多く、<br />
ソフトウェアRAIDとして扱われることもあります）<br />
こちらはRAID管理を行うための処理を機器やチップが行うため、<br />
ソフトウェアRAIDに比べて、高速です。<br />
また、ハードウェアRAIDにより構成されたディスクは、Windowsの様なOS側から<br />
ディスクを確認すると1つのディスクとしか表示されません。<br />
例えば、HDDが2台搭載されているサーバが有るとします。<br />
(ディスクAとディスクBとします)<br />
この2台のHDDでRAID構成をすると、仮想的にHDDができます。<br />
（ディスクV1とします）<br />
Windows側からはディスクV1のみがHDDとして認識されます。</p>
<p>これに対して、ソフトウェアRAIDはWindowsの様なOSの機能の1つとして、<br />
RAIDが提供されます。<br />
こちらはRAID管理を行うための処理をOSが担当しますので、<br />
他の稼働プロセスと同様に処理されるため、<br />
ハードウェアRAIDに比べると、ディスクの書き込みは低速となります。<br />
OSの機能としてRAID構成を行うため、<br />
HDDはサーバに搭載されている分が表示されます。<br />
上述の例でいえば、ディスクAとディスクBが認識されており、<br />
ソフトウェアRAIDとして構成することで、ディスクV1として認識されますが、<br />
ディスクの管理機能で確認すると、表示上はディスクAとディスクBと表示されます。</p>
<p>今回は、RAIDについて、提供する機器・機能からの話をしましたが、<br />
次回は、RAID構成について、もう少し詳しく記述します。</p>
]]></content:encoded>
			<wfw:commentRss>http://icoctech.icoc.co.jp/blog/?feed=rss2&#038;p=458</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>特定のクラスのみ操作したい</title>
		<link>http://icoctech.icoc.co.jp/blog/?p=441</link>
		<comments>http://icoctech.icoc.co.jp/blog/?p=441#comments</comments>
		<pubDate>Tue, 16 Sep 2014 10:02:49 +0000</pubDate>
		<dc:creator><![CDATA[ohshima]]></dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://icoctech.icoc.co.jp/blog/?p=441</guid>
		<description><![CDATA[今回はC#とASP.NETの話です。 Webページで登録画面を作成していて、 必須入力項目への入力確認に、 RequiredFieldValidatorクラスを使用しました。 バリデーションを行うコントロール名とエラーメ [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>今回はC#とASP.NETの話です。</p>
<p>Webページで登録画面を作成していて、<br />
必須入力項目への入力確認に、<br />
RequiredFieldValidatorクラスを使用しました。</p>
<p>バリデーションを行うコントロール名とエラーメッセージをセットすれば、<br />
指定したコントロールに対して、入力がなされたかクライアント側で確認することができます。</p>
<p>ただし、今回作成している画面が少し厄介で、<br />
ドロップダウンリストの選択した値によって、<br />
必須入力が変更される、という仕様を盛り込んでいました。</p>
<p>そこで、SelectedIndexChangedイベントを使用し、<br />
選択した値が変更した時に、RequiredFieldValidatorの設定を切り替えるようにしました。</p>
<p>初めは、選択した値ごとに、RequiredFieldValidatorのEnabledプロパティに<br />
TrueやFalseをセットしていたのですが、<br />
これだと、Falseのセット漏れが出たりするなぁ、と思い、<br />
一度、ページ内の全てのRequiredFieldValidatorにFalseをセットした後、<br />
必要なコントロールのみ、Trueを設定しようと考えました。</p>
<p>では、どの様にして、全てのRequiredFieldValidatorコントロールに<br />
Falseをセットするのか、考えました。<br />
ASP.NETの各コントロールが継承するクラスにControlクラスが有ります。<br />
このControlクラスには、FindControlというメソッドが有りますが、<br />
これはコントロールのIDでしか探せません。<br />
それに加え、コントロールは階層配置されており、<br />
FindControlメソッドでは、呼出元のコントロールが有する子コントロールが<br />
対象となります。</p>
<p>そこで、下記の記事を参考にし、再帰的に呼び出されるメソッドを作成しました。<br />
下記記事では、IDを使用していますが、今回はクラス名で検索する様にします。</p>
<p>方法: ID を使用してサーバー コントロールにアクセスする</p>
<p>http://msdn.microsoft.com/ja-jp/library/y81z8326(v=vs.100).aspx</p>
<p>上記記事内に記載されているメソッドからの変更点は、<br />
１．引数のIDをクラス名に変更する。<br />
２．コントロールとIDの照合を<br />
コントロールのクラス名と１で変更した引数と照合する。</p>
<pre><code>
    public static Control FindControlRecursive(Control rootControl,
                                               string findControlClassName)
    {
        if (rootControl.GetType().Name == findControlClassName)
        {
            return rootControl;
        }

        foreach (System.Web.UI.Control searchControl in rootControl.Controls)
        {
            Control controlToReturn =
                FindControlRecursive(searchControl, findControlClassName);
            if (controlToReturn != null)
            {
                return controlToReturn;
            }
        }
        return null;
    }
</code></pre>
<p>このメソッドを実行することで、rootControl以下のコントロールから<br />
検索対象とするクラス名を有するコントロールを取得できます。<br />
後は、取得したコントロールのparentプロパティで、<br />
直近の親コントロールを取得し、<br />
親コントロールが持つ子コントロールをforeachで回し、<br />
GetType().Name で同一のクラス名を持つコントロールのEnabledプロパティに<br />
FALSEをセットすれば、Webページ内のRequiredFieldValidatorオブジェクトを<br />
無効化できます。</p>
<p>ちなみに、呼出元は以下の様なコードを書きました。</p>
<pre><code>
    // ページ内のコントロールを対象とする。
    foreach (Control pageChild in Page.Controls)
    {
        // RequiredFieldValidatorクラスのコントロールを検索する。
        var findControl = FindControlRecursive(pageChild,
                                  "RequiredFieldValidator");

        if (findControl != null)
        {
            // 検索結果のコントロールの親コントロールを取得する。
            var parentControl = findControl.Parent;

            // 親コントロールの全てのvalidatorを無効にする。
            foreach (Control childControl in parentControl.Controls)
            {
                If (childControl.GetType().Name == "RequiredFieldValidator")
                {
                    RequiredFieldValidator requiredFieldControl =
                        (RequiredFieldValidator)childControl;
                    requiredFieldControl.Enabled = false;
                }
            }
        }
    }
</code></pre>
<p>サーバサイドで同一のクラスを持つコントロールに<br />
一律の操作をする際に、使えると思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://icoctech.icoc.co.jp/blog/?feed=rss2&#038;p=441</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VMWare ESXiのセットアップで苦戦した話（２）</title>
		<link>http://icoctech.icoc.co.jp/blog/?p=438</link>
		<comments>http://icoctech.icoc.co.jp/blog/?p=438#comments</comments>
		<pubDate>Tue, 16 Sep 2014 10:00:36 +0000</pubDate>
		<dc:creator><![CDATA[ohshima]]></dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://icoctech.icoc.co.jp/blog/?p=438</guid>
		<description><![CDATA[前回の続きです。 開発用のサーバにVMWare ESXiをインストールさせようとしている社員Ｏ氏。 RAIDの設定に四苦八苦しながらも、なんとかRAIDの設定は行えましたが、 まだまだ続きます。 というより、むしろここか [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>前回の続きです。</p>
<p>開発用のサーバにVMWare ESXiをインストールさせようとしている社員Ｏ氏。<br />
RAIDの設定に四苦八苦しながらも、なんとかRAIDの設定は行えましたが、<br />
まだまだ続きます。<br />
というより、むしろここからがインストール作業です。</p>
<p>空の環境にインストールする際、特に難しいことはありません。（ないはずでした……）<br />
１．ブート時にCDからインストールするか確認<br />
２．規約事項の確認<br />
３．インストールするハードディスクの確認<br />
この順に確認が出ますので、<br />
それぞれ入力を行います。</p>
<p>が、今回は楽にはいきませんでした。<br />
今回の問題は３のハードディスクでした。</p>
<p>どのハードディスクにインストールするか確認する画面が表示されるのですが、<br />
RAID構成したはずのディスクなのに、物理ハードディスクが二つ見える……</p>
<p>RAID構成が崩れた？　と思い、サーバを再起動させて確認する。<br />
RAID構成は崩れていない。<br />
とりあえず、そのままインストールを続行してみました。<br />
その後の起動で確認すると、RAID構成は崩れたままです。</p>
<p>どういうことだ？　と考える。<br />
まさか、オンボードRAID（＝ソフトウェアRAID）だとよろしくないのか、と思い、<br />
ESXi5.5のインストールマニュアルを探す。<br />
やはりというか、下調べが足りてないというか、<br />
ESXi5.5ではソフトウェアRAIDはサポートしていない、という一文が。<br />
そうですか、マザーボードに載っているタイプのRAIDもアウトですか……</p>
<p>しかし、原因さえわかってしまえば、回避できます。<br />
ということで、BIOSを立ち上げ、HDDモードをAHCIへ。<br />
その後、正常にインストールは完了しました。</p>
<p>正直、ここまで苦戦することになるとは考えてもいませんでした。<br />
ESXiも（バージョンが異なるとはいえ）インストールしたことはありましたから。</p>
<p>それでは、今回の教訓です。<br />
インストールする環境はきちんとマニュアルに目を通しましょう。</p>
<p>前回といい、今回といい、事前に情報さえ持っておけば、<br />
回避できる状況に対し、前にやったことあるし、大丈夫大丈夫と<br />
安易に考えたために、結果として、大火傷してしまいました。</p>
<p>事前準備ってホント重要ですね……</p>
]]></content:encoded>
			<wfw:commentRss>http://icoctech.icoc.co.jp/blog/?feed=rss2&#038;p=438</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
