<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>がんふぃーるど室長の不定期ブログ</title><link>http://blogs.wankuma.com/ganfield/</link><description>ただいま助手と悪戦苦闘中！</description><managingEditor>がんふぃーるど(ganfield@wankuma.com)</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>がんふぃーるど(ganfield@wankuma.com)</dc:creator><title>ODP.NETを使用して無名ブロックを実行しようとしたときに改行コードLF/CRLFは環境依存？ - Oracle</title><link>http://blogs.wankuma.com/ganfield/archive/2008/09/16/156709.aspx</link><pubDate>Tue, 16 Sep 2008 23:30:00 GMT</pubDate><guid>http://blogs.wankuma.com/ganfield/archive/2008/09/16/156709.aspx</guid><wfw:comment>http://blogs.wankuma.com/ganfield/comments/156709.aspx</wfw:comment><comments>http://blogs.wankuma.com/ganfield/archive/2008/09/16/156709.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/ganfield/comments/commentRss/156709.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/ganfield/services/trackbacks/156709.aspx</trackback:ping><description>&lt;p&gt;Oracle 11g のWindows試用版を入れてみたら、改行コードがCRLFでも無名ブロック（Non-Stored Procedure)の実行がODP.NETで出来てしまった。&lt;/p&gt; &lt;p&gt;Unix版の10.2gや10.1gではCRを認識できないためにエラーが発生して、わざわざCRを空文字に置換したり、\nだけ書いていたのだが…&lt;/p&gt; &lt;p&gt;環境依存な事柄なのかな？？？それとも11gで改心（？）したのかな？&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/ganfield/aggbug/156709.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>がんふぃーるど(ganfield@wankuma.com)</dc:creator><title>「オブジェクト指向入門　第二版　方法論・実践」が発売されています</title><link>http://blogs.wankuma.com/ganfield/archive/2008/08/30/154714.aspx</link><pubDate>Sat, 30 Aug 2008 08:32:00 GMT</pubDate><guid>http://blogs.wankuma.com/ganfield/archive/2008/08/30/154714.aspx</guid><wfw:comment>http://blogs.wankuma.com/ganfield/comments/154714.aspx</wfw:comment><comments>http://blogs.wankuma.com/ganfield/archive/2008/08/30/154714.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/ganfield/comments/commentRss/154714.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/ganfield/services/trackbacks/154714.aspx</trackback:ping><description>&lt;p&gt;&lt;a title="http://seshop.com/detail.asp?pid=9505" href="http://seshop.com/detail.asp?pid=9505"&gt;http://seshop.com/detail.asp?pid=9505&lt;/a&gt;&lt;/p&gt; &lt;p&gt;すごく・・・ごついです・・・&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/ganfield/aggbug/154714.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>がんふぃーるど(ganfield@wankuma.com)</dc:creator><title>アプリケーションコンテキスト その１ - Oracle</title><link>http://blogs.wankuma.com/ganfield/archive/2008/08/18/153314.aspx</link><pubDate>Mon, 18 Aug 2008 01:38:00 GMT</pubDate><guid>http://blogs.wankuma.com/ganfield/archive/2008/08/18/153314.aspx</guid><wfw:comment>http://blogs.wankuma.com/ganfield/comments/153314.aspx</wfw:comment><comments>http://blogs.wankuma.com/ganfield/archive/2008/08/18/153314.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/ganfield/comments/commentRss/153314.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/ganfield/services/trackbacks/153314.aspx</trackback:ping><description>&lt;P&gt;Oracleにはアプリケーションコンテキストというものがあります。ASP.NETで言うところの「セッション」みたいなもので、基本はKey-Valueで構成される情報を保持しています。Oracleのマニュアルを見るとCREATE CONTEXT文というのがちゃんと用意されており、ユーザ定義のアプリケーションコンテキストを使用すればかなり柔軟なアプリケーションを作成することが可能です。&lt;/P&gt;
&lt;P&gt;今回は御触りということで、ユーザ定義のアプリケーションコンテキストは使用せずに組込みのアプリケーションコンテキスト「USERENV」を少しだけ使用します。&lt;/P&gt;
&lt;H4&gt;アプリケーションコンテキスト「USERENV」&lt;/H4&gt;
&lt;P&gt;USERENVにはセッションに関する情報がほぼ詰め込まれています。今回はこの中の「CLIENT_IDENTIFIER」を使用します。理由は至って簡単-ODP.NETのOracleConnection.ClientIdからお手軽に設定できるからです。&lt;/P&gt;
&lt;P&gt;その他の値については下記のOracleのドキュメントを参照してください。&lt;/P&gt;
&lt;P&gt;&lt;A title=http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05750-02/functions.htm#11790 href="http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05750-02/functions.htm#11790"&gt;http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05750-02/functions.htm#11790&lt;/A&gt;&lt;/P&gt;
&lt;H4&gt;アプリケーションコンテキストの確認方法&lt;/H4&gt;
&lt;P&gt;アプリケーションコンテキスト確認用の関数があるので、それを使用します。&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;SYS_CONTEXT(namespace, parameter [, length ])&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;namespaceにUSERENV&lt;/P&gt;
&lt;P&gt;parameterにCLIENT_IDENTIFIER&lt;/P&gt;
&lt;P&gt;を指定します。lengthはオプショナルな設定値なので今回は無視（デフォルト値は256）&lt;/P&gt;
&lt;P&gt;　※USERENV関数というのもありますが下位互換用です。またUSERENV関数にはCLIENT_IDENTIFIERを取得する機能は存在しないので、基本SYS_CONTEXTを使用します。&lt;/P&gt;
&lt;H4&gt;ODP.NETでCLIENT_IDENTIFIERの設定&lt;/H4&gt;
&lt;P&gt;先に言ってしまいましたが、ODP.NETの以下のプロパティを設定します。&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;OracleConnection.ClientId&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;このプロパティは接続をOpenした後にのみ設定可能です。ClientIdは接続中つねに有効になり、Closeと共に解放されます（nullが設定される）。&lt;/P&gt;
&lt;TABLE cellSpacing=0 cellPadding=2 width=800 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=798&gt;
&lt;P&gt;using (OracleConnection conn = new OracleConnection("user id=XXXX; password=YYYY; data source=xe"))&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; conn.Open(); 
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; conn.ClientId = "30";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; command = conn.CreateCommand();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; command.CommandText = "SELECT SYS_CONTEXT('USERENV', 'CLIENT_IDENTIFIER') FROM DUAL";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = command.ExecuteScalar();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(result.Equals(System.DBNull.Value) ? "null" : result.ToString());&lt;BR&gt;}&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H4&gt;アプリケーションコンテキストを使用してVIEWへ値を動的に渡す&lt;/H4&gt;
&lt;P&gt;アプリケーションコンテキストは関数を通して取得できるということで、VIEWなどに対して動的に値を渡すことが可能です。VIEWであれば、使用しているSQL側でWHERE句に条件を設定することで同じことが当然できますが、セキュリティ的な要件をVIEWでコントロールしたい場合などに役立ちます。（Oracleではセキュリティに関して、仮想プライベートデータベースという便利な機能がありますが、今回はそれを使用しません。）&lt;/P&gt;
&lt;P&gt;ためしに以下のようなVIEWをOracleのHRスキーマ上に作成します。&lt;/P&gt;
&lt;TABLE cellSpacing=0 cellPadding=2 width=800 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=800&gt;
&lt;P&gt;-- マネージャ直下の部下を参照できるVIEW&lt;BR&gt;CREATE OR REPLACE VIEW HR.EMPLOYEES_UNDER_MANAGER1&lt;BR&gt;AS&lt;BR&gt;SELECT * FROM HR.EMPLOYEES WHERE MANAGER_ID = SYS_CONTEXT('USERENV', 'CLIENT_IDENTIFIER')&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;このVIEWはClientIdに社員IDが設定されていることを前提に作られています。ClientIdの値を変えることで返却される行が変更されます。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;次回はユーザ定義のアプリケーションコンテキストの作成方法について説明しようと思います。&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/ganfield/aggbug/153314.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>がんふぃーるど(ganfield@wankuma.com)</dc:creator><title>ウィンドウ関数（分析関数） - SQL Server 2005</title><link>http://blogs.wankuma.com/ganfield/archive/2008/07/31/151200.aspx</link><pubDate>Thu, 31 Jul 2008 00:57:00 GMT</pubDate><guid>http://blogs.wankuma.com/ganfield/archive/2008/07/31/151200.aspx</guid><wfw:comment>http://blogs.wankuma.com/ganfield/comments/151200.aspx</wfw:comment><comments>http://blogs.wankuma.com/ganfield/archive/2008/07/31/151200.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/ganfield/comments/commentRss/151200.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/ganfield/services/trackbacks/151200.aspx</trackback:ping><description>&lt;p&gt;WNDPROCとかじゃアｒ （ｒｙ&lt;/p&gt; &lt;p&gt;ウィンドウ関数はSQL Serverでも使用できます。なんてったって標準SQLですから。&lt;/p&gt; &lt;h2&gt;ウィンドウ関数を使ってみる&lt;/h2&gt; &lt;p&gt;SQL Server 2005のAdventureWorksを使用して、ウィンドウ関数を使ってみます。やりたいことは&lt;a href="http://blogs.wankuma.com/ganfield/archive/2008/07/29/150723.aspx"&gt;Oracle版&lt;/a&gt;と同じようなことですが、部署IDみたいなものが無かったので性別でウィンドウを区切ってみます。&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Employeeテーブルの中で、性別ごとに生年月日順にランク付けする。&lt;/li&gt; &lt;li&gt;ランク付けしたら、同じ性別の中で何人中何位だったかわかるようにする。&lt;/li&gt; &lt;li&gt;取得する項目はEmployeeID, 性別, 順位, 性別ごとの人数&lt;/li&gt;&lt;/ul&gt; &lt;table cellspacing="0" cellpadding="2" width="800" border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="800"&gt; &lt;p&gt;SELECT&lt;br&gt; a.EmployeeID as 社員ID,&lt;br&gt; a.Gender as 性別,&lt;br&gt; Rank() OVER (PARTITION BY a.Gender ORDER BY a.BirthDate) as 順位,&lt;br&gt; Count(a.Gender) OVER (PARTITION BY a.Gender) as 人数&lt;br&gt;FROM&lt;br&gt; HumanResources.Employee a&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Oracleと同じですね。実行計画は次の通り&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="800" border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="800"&gt; &lt;p&gt;|--Nested Loops(Inner Join)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Table Spool&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Segment&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Sequence Project(DEFINE:([Expr1002]=rank))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Segment&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Segment&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Sort(ORDER BY:([a].[Gender] ASC, [a].[BirthDate] ASC))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Clustered Index Scan(OBJECT:([AdventureWorks].[HumanResources].[Employee].[PK_...] AS [a]))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Nested Loops(Inner Join, WHERE:((1)))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Compute Scalar(DEFINE:([Expr1003]=CONVERT_IMPLICIT(int,[Expr1007],0)))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Stream Aggregate(DEFINE:([Expr1007]=Count(*)))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Table Spool&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Table Spool&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&lt;strong&gt;参考文献&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/ms189461.aspx"&gt;SQL Server 2005 Books Online - OVER句&lt;/a&gt;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/ganfield/aggbug/151200.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>がんふぃーるど(ganfield@wankuma.com)</dc:creator><title>ウィンドウ関数（分析関数） - Oracle</title><link>http://blogs.wankuma.com/ganfield/archive/2008/07/29/150723.aspx</link><pubDate>Tue, 29 Jul 2008 00:35:00 GMT</pubDate><guid>http://blogs.wankuma.com/ganfield/archive/2008/07/29/150723.aspx</guid><wfw:comment>http://blogs.wankuma.com/ganfield/comments/150723.aspx</wfw:comment><comments>http://blogs.wankuma.com/ganfield/archive/2008/07/29/150723.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/ganfield/comments/commentRss/150723.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/ganfield/services/trackbacks/150723.aspx</trackback:ping><description>&lt;P&gt;WNDPROCとかじゃアリマセン。集権関数とちょっと勘違いされそうなモノなんですが、別物です。ひそかにANSI SQLでも定義されている立派な標準SQL構文です。&lt;/P&gt;
&lt;H2&gt;ウィンドウ関数とは&lt;/H2&gt;
&lt;P&gt;簡単に言うと「Group byの様にデータのグループを決められる。集計はせず、さらにその範囲の中で特定のデータのみを対象とできる」ものです。&lt;/P&gt;
&lt;P&gt;う～ん、いまいち訳分かりませんね。&lt;/P&gt;
&lt;P&gt;とりあえず、使ってみましょう。&lt;/P&gt;
&lt;H2&gt;ウィンドウ関数を使ってみる&lt;/H2&gt;
&lt;P&gt;OracleのHRスキーマを使用して、ウィンドウ関数を使ってみます。やりたいことは次の通り。&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Employeesテーブルの中で、部署（Department_id）ごとに給料の高い順にランク付けする。 
&lt;LI&gt;ランク付けしたら、部署の中で何人中何位だったわかるようにする。 
&lt;LI&gt;取得する項目は、Employee_id, 名前, 順位, 部署の人数&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;部署の人数などは、EmployeesテーブルをDepartment_idでgroup byした結果をさらにEmployeesテーブルのDepartment_idと結合してたり&amp;#8230;なんてことでも取れますが、そんな面倒なことをしなくてもウィンドウ関数を使えば楽勝です。&lt;/P&gt;
&lt;TABLE cellSpacing=0 cellPadding=2 width=800 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=800&gt;
&lt;P&gt;SELECT&lt;BR&gt;a.EMPLOYEE_ID,&lt;BR&gt;a.FIRST_NAME || ', ' || a.LAST_NAME ,&lt;BR&gt;a.DEPARTMENT_ID,&lt;BR&gt;RANK() OVER (PARTITION BY a.DEPARTMENT_ID ORDER BY a.SALARY DESC),&lt;BR&gt;COUNT(a.DEPARTMENT_ID) OVER (PARTITION BY a.DEPARTMENT_ID)&lt;BR&gt;FROM &lt;BR&gt;HR.EMPLOYEES a&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;ポイントは5行目と6行目。 &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;関数(expr) OVER (PARTITION BY XXX)&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;というのが、ウィンドウ関数の基本的な構文です。PARTITION BY のXXXX項目でグループを指定します（group byみたいな感じ）&lt;/P&gt;
&lt;P&gt;5行目では、部署（Department_id）別にウィンドウを設定し、給料の高い順にランク付けします。6行目では、部署別にカウントを取ります。&lt;/P&gt;
&lt;P&gt;これだけで完了。実行計画もすっきり。&lt;/P&gt;
&lt;TABLE cellSpacing=0 cellPadding=2 width=800 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=800&gt;
&lt;P&gt;SELECT STATEMENT&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WINDOW SORT&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TABLE ACCESS FULL EMPLOYEES &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;毎回毎回使うようなものではありませんが、かゆい所に手が届くといった感じで結構便利です。&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;参考文献&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/functions.html#25267"&gt;Oracle Database SQL リファレンス 10.2 - 分析ファンクション&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://codezine.jp/a/article/aid/1269.aspx"&gt;CodeZine - 分析関数の衝撃&lt;/A&gt;&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/ganfield/aggbug/150723.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>がんふぃーるど(ganfield@wankuma.com)</dc:creator><title>Flets接続ツール「IPv6リゾルバサービス」のバグ？</title><link>http://blogs.wankuma.com/ganfield/archive/2008/07/23/149816.aspx</link><pubDate>Wed, 23 Jul 2008 00:44:00 GMT</pubDate><guid>http://blogs.wankuma.com/ganfield/archive/2008/07/23/149816.aspx</guid><wfw:comment>http://blogs.wankuma.com/ganfield/comments/149816.aspx</wfw:comment><comments>http://blogs.wankuma.com/ganfield/archive/2008/07/23/149816.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/ganfield/comments/commentRss/149816.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/ganfield/services/trackbacks/149816.aspx</trackback:ping><description>&lt;p&gt;DNSのアドレスが使用しているクライアントPCのアドレスになる…嫌がらせですか？&lt;/p&gt; &lt;p&gt;しかも、サービスを起動している限り何度でも書き換える。&lt;/p&gt; &lt;p&gt;な・ん・ど・で・も♪&lt;/p&gt; &lt;p&gt;普段はどうってことなかったので、二つのネットワーク（有線と無線）を同時に有効にしたから駄目だったのかな？どうでもいいツールだからあまり確認していないけど。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;とりあえず、ボトムズを全話見るために入れたのですでに用無し。サービスをさっさと止めて解決。。。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/ganfield/aggbug/149816.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>がんふぃーるど(ganfield@wankuma.com)</dc:creator><title>行ロック以外に起因するデッドロック - Oracle</title><link>http://blogs.wankuma.com/ganfield/archive/2008/07/16/149050.aspx</link><pubDate>Wed, 16 Jul 2008 01:21:00 GMT</pubDate><guid>http://blogs.wankuma.com/ganfield/archive/2008/07/16/149050.aspx</guid><wfw:comment>http://blogs.wankuma.com/ganfield/comments/149050.aspx</wfw:comment><comments>http://blogs.wankuma.com/ganfield/archive/2008/07/16/149050.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/ganfield/comments/commentRss/149050.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/ganfield/services/trackbacks/149050.aspx</trackback:ping><description>&lt;H2&gt;デッドロック&lt;/H2&gt;
&lt;P&gt;業務アプリを作成していると、必ずデッドロックというものは意識すると思います。リレーショナルDBを使用しているのであれば尚更だと思います。&lt;/P&gt;
&lt;P&gt;基本的にはテーブルの更新順序に対する標準を作っておけば、起こることはありません。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;少なくともOracleでは起こらないと思ってました。(；&amp;#180;Д｀)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;SQLServerだとロックエスカレーションによってページロックが発生してデッドロック！なんてことが稀にありますが、Oracleでもマルチプロセス、もしくはパラレルDMLによる大量更新時にITLの確保待ちによるデッドロックが発生する場合があります。（記述が紛らわしいですが、SQLServerのページロックとはまったく別物です）&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;ITL&lt;/H2&gt;
&lt;P&gt;ITLとは（Interested Transaction List)の略で、変更情報や行ロックに関する情報を管理しています。リストというぐらいなので、当然複数持っています。いくつかというと、初期状態ではCREATE文のINITRANSの個数分だけ確保され、必要に応じて最大MAXTRANSの個数まで拡張されます。&lt;/P&gt;
&lt;P&gt;ただし、ブロックに空き容量がない場合は、拡張されません。（拡張できません）&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;リストの内容はセッションごとに管理されているので、ブロックの情報を2つのセッションで同時に操作する場合は2つ必要です。3つのセッションで同時に操作する場合は3つ必要となります。ただ、ITLは有限個しかないので、大量のセッションから同時に操作されたときに、ITLを拡張できない状態にあるとどうなるかというと、ITLの開放待ちになります。&lt;/P&gt;
&lt;P&gt;&amp;#8230;開放待ちになります&amp;#8230;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;デッドロック発生までの流れ&lt;/H2&gt;
&lt;P&gt;まずは、ブロックに対してITLの拡張ができないほど空きがなく、且つ、ITLが1つしかないものとします。その状態で&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;セッションAがブロック１の情報を更新 
&lt;LI&gt;セッションBがブロック２の情報を更新 
&lt;LI&gt;セッションAがブロック２の情報を更新しようとしてITL開放待ち 
&lt;LI&gt;セッションBがブロック１の情報を更新しようとしてITL開放待ち&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;でデッドロックが発生します。ちなみに、セッションA、Bが更新する内容で行レベルのロックは一つも被っていませんが、まったくもって有り難くないORA-00060が発生しちゃいます。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;&lt;/H2&gt;
&lt;H2&gt;調査方法&lt;/H2&gt;
&lt;P&gt;正直、分かりにくいです。普通にORA-00060が発生するので、一般的なデッドロックと判別がつきません。V$LOCKやV$LOCKED_OBJECTをリアルタイムに参照するのも難しいことから、唯一分かる情報としては「udump」に吐かれるトレース情報ぐらいです。&lt;/P&gt;
&lt;P&gt;ここにはデッドロック時に「待ち」が発生していたセッション情報も含めて、大量の情報が記録されています。この中に「ITL Entry」に対するブロッキングが発生していた旨があった場合、ほぼ間違いなくITLデッドロックだと思います。&lt;/P&gt;
&lt;P&gt;また、ITLデッドロックはテーブルだけでなく、インデックスに対しても発生するため、ロック対象のROW IDやOBJECT IDにインデックスのOBJECT IDが含まれていたら、ITLデッドロックなどのアプリデッドロック以外を疑ったほうがよいです。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;解決方法&lt;/H2&gt;
&lt;P&gt;基本的にINITRANSに適切な値を設定することで回避できる問題なので、マルチプロセスでの大量更新・登録系って聞いた瞬間にINITRANSを適切に設定してやることで回避できます。ただし、INITRANSは1つ増やすごとに24バイトのブロックヘッダを消費するので、ご利用は計画的に。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;参考文献&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.shift-the-oracle.com/table/ITL.html"&gt;SHIFT The Oracle - Interested Transaction List&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.dba-oracle.com/t_parallel_dml_deadlock_detected.htm"&gt;Oracle parallel DML: Deadlock Detected: ORA-00060&lt;/A&gt;&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/ganfield/aggbug/149050.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>がんふぃーるど(ganfield@wankuma.com)</dc:creator><title>ローカル同一キーパーティション索引</title><link>http://blogs.wankuma.com/ganfield/archive/2008/07/15/148879.aspx</link><pubDate>Tue, 15 Jul 2008 01:21:00 GMT</pubDate><guid>http://blogs.wankuma.com/ganfield/archive/2008/07/15/148879.aspx</guid><wfw:comment>http://blogs.wankuma.com/ganfield/comments/148879.aspx</wfw:comment><comments>http://blogs.wankuma.com/ganfield/archive/2008/07/15/148879.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/ganfield/comments/commentRss/148879.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/ganfield/services/trackbacks/148879.aspx</trackback:ping><description>&lt;P&gt;の落とし穴（？）にハマりました&amp;#8230;&lt;/P&gt;
&lt;P&gt;パーティションキーを固定（バインド変数）で渡すような場合に、Oracleが強引にローカルパーティション索引の使用とパーティションプルーニングを行おうとした結果、非効率的な実行計画を立ててくれる場合がありました。&lt;/P&gt;
&lt;P&gt;駆動表が他にあるので、そいつと結合するときにハッシュ結合すれば高速に動くのですが、わざわざネステッドループをかましてConsitents getsが１千万弱に&amp;#8230;嫌がらせでつか？(つД｀)&lt;/P&gt;
&lt;P&gt;統計情報の取り直しや、ヒント文の付与、SharedPoolとバッファキャッシュのクリアなどを行ったが、全然効果なし。&lt;/P&gt;
&lt;P&gt;ローカルパーティション索引のカーディナリティが高いわけでもなく、結合条件などを含めたら他にカーディナリティの高い索引があるのに&amp;#8230;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;とりあえず、レコード件数が億を余裕で超えている表だったので、索引項目を増やしたりはせず、索引をグローバルパーティション索引に変更。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;原因がいまいちハッキリしていないので気持ち悪いのですが、今回はちょっぴり残念な結果に&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/ganfield/aggbug/148879.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>がんふぃーるど(ganfield@wankuma.com)</dc:creator><title>NVelocity - テキストのテンプレートエンジン</title><link>http://blogs.wankuma.com/ganfield/archive/2008/07/10/148258.aspx</link><pubDate>Thu, 10 Jul 2008 01:57:00 GMT</pubDate><guid>http://blogs.wankuma.com/ganfield/archive/2008/07/10/148258.aspx</guid><wfw:comment>http://blogs.wankuma.com/ganfield/comments/148258.aspx</wfw:comment><comments>http://blogs.wankuma.com/ganfield/archive/2008/07/10/148258.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/ganfield/comments/commentRss/148258.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/ganfield/services/trackbacks/148258.aspx</trackback:ping><description>&lt;p&gt;.NETで使用できるテキストテンプレートエンジンです。&lt;/p&gt; &lt;p&gt;最近やっている仕事の関係上、開発用ツールを作成したくなる場合が多く、ちょっとしたデータベースのDDL文などのテキストファイルを作成する場合が多く、もうちっと楽＆美しく（？）作りたいな～なんて思っているときに発見しました。&lt;/p&gt; &lt;p&gt;上手に使用すればメール本文を作成するテンプレートエンジンとしても利用可能にできそうです。&lt;/p&gt; &lt;p&gt;ちょっとおしゃれに（無駄にｗ）テキストファイルを作ってみたいときは使ってみて下さい。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="https://svn.castleproject.org/svn/castle/trunk/Tools/NVelocity/"&gt;NVelocity (SVNリポジトリ)&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://codezine.jp/a/article/aid/373.aspx"&gt;CodeZine : テンプレートエンジンNVelocityを活用してテキストを生成する&lt;/a&gt;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/ganfield/aggbug/148258.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>がんふぃーるど(ganfield@wankuma.com)</dc:creator><title>ユーザー定義集計関数&amp;hellip;とは微妙に違うCSV形式で文字列を集計 - LINQ</title><link>http://blogs.wankuma.com/ganfield/archive/2008/07/02/146658.aspx</link><pubDate>Wed, 02 Jul 2008 02:05:00 GMT</pubDate><guid>http://blogs.wankuma.com/ganfield/archive/2008/07/02/146658.aspx</guid><wfw:comment>http://blogs.wankuma.com/ganfield/comments/146658.aspx</wfw:comment><comments>http://blogs.wankuma.com/ganfield/archive/2008/07/02/146658.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/ganfield/comments/commentRss/146658.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/ganfield/services/trackbacks/146658.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/ganfield/archive/2008/06/30/146270.aspx"&gt;前回&lt;/a&gt;はSQL Serverでその前がOracleだったので、ぢゃあ次はLINQってことで試してみました。&lt;/p&gt; &lt;p&gt;LINQの場合（というかC# 3.0の場合）は、Aggregateメソッドとラムダ式でうにゃうにゃっと書けば結構できてしまうので、細かいとこは省いてしまいます。&lt;/p&gt; &lt;h2&gt;基本&lt;/h2&gt; &lt;p&gt;基本は以下のラムダ式があればほぼ問題無いみたいです。（表現が間違っていたらごめんなさい＆指摘して下さい）&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="700" border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="700"&gt; &lt;p&gt;(TAccumulate, TSource) =&amp;gt; 処理&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;ということで、実際に集計処理をしてみましょう。&lt;/p&gt; &lt;h2&gt;集計処理&lt;/h2&gt; &lt;p&gt;サンプルでは適当な家族(family)の匿名型を利用して、性別ごとに家族の名前をカンマ区切りで集計します。&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="700" border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="700"&gt; &lt;p&gt;var family = new []{ &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new { Name = "父", Age = 40, Sex = "男" },&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new { Name = "母", Age = 40, Sex = "女" },&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new { Name = "娘", Age = 10, Sex = "女" },&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new { Name = "爺ちゃん", Age = 70, Sex = "男" },&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new { Name = "曾婆ちゃん", Age = 100, Sex = "女" },&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new { Name = "曾曾婆ちゃん", Age = 125, Sex = "女" }&lt;br&gt;};  &lt;p&gt;string startVal = string.Empty;&lt;br&gt;var AggNamePerSex = from f in family&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; group f by f.Sex into g&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select new {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sex = g.Key,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AggName = g.Aggregate(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; startVal // 初期値&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , (running, next) =&amp;gt; running += next.Name + "," // 集計処理&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , result =&amp;gt; result == string.Empty ? result : result.Substring(0, result.Length -1) // 終了処理&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };  &lt;p&gt;foreach (var sexGroup in AggNamePerSex)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(sexGroup.Sex + " : " + sexGroup.AggName);&lt;br&gt;} &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;実行結果はこんな感じ&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="700" border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="700"&gt; &lt;p&gt;男 : 父,爺ちゃん&lt;br&gt;女 : 母,娘,曾婆ちゃん,曾曾婆ちゃん&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;処理の方をよく見てみると、初期値（初期化）→集計処理→終了処理　とOracleやSQL Serverと似ていますね。パラレル実行などがないため、マージはありませんが（ｗ&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;P.S. ソースを見てみると、もはやC#のソースに見えない…というか、なぜ「C」って付いているんだろうｗ&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/ganfield/aggbug/146658.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>