☆XQuery 親ノードへのアクセス
再び、SQL Server 2005 Express Edition、XQueryの話です。
前回、XQUERYってややこしいっ!で使ったようなXMLを格納したフィールドで、あるノードの親ノードのIDを取得する処理を考えてみました。
上記の処理で親ノードのIDを取得できたので、これをストアドかユーザー定義関数内でループさせると、あるノードまでの パスを返すことができると思い試してみましたが、ここで問題が発生しました。というのもSQL Serverでの変数は、@node_idのように@を付ける必要があり、この仕様が、XMLのPATH式での属性を示す@(attribute)とかぶってしまうからです。結局、これを解決できずにADOQureyを使って次のように処理することにしました。
前回、XQUERYってややこしいっ!で使ったようなXMLを格納したフィールドで、あるノードの親ノードのIDを取得する処理を考えてみました。
//IDが456の親ノードのIDを取得する場合 // query, parent, returnは小文字でないと動きません。 SELECT CAST(TREEXML.query(' for $RESULT1 in //item[@id=456]/parent::item, $RESULT2 in (data($RESULT1/@id)) return $RESULT2 ') as VARCHAR) FROM dbo.KUBUN
上記の処理で親ノードのIDを取得できたので、これをストアドかユーザー定義関数内でループさせると、あるノードまでの パスを返すことができると思い試してみましたが、ここで問題が発生しました。というのもSQL Serverでの変数は、@node_idのように@を付ける必要があり、この仕様が、XMLのPATH式での属性を示す@(attribute)とかぶってしまうからです。結局、これを解決できずにADOQureyを使って次のように処理することにしました。
function TDataModule1.GetParentIDs(MyID: Integer): String; const TopNodeID = 1; //一番上ノードのID var SQL: String; I: Integer; begin Result := ''; while true do begin SQL := 'SELECT CAST(TREEXML.query(''for $RESULT1 in //item[@id='; SQL := SQL + IntToStr(MyID) + ']/parent::item, '; SQL := SQL + '$RESULT2 in (data($RESULT1/@id)) return $RESULT2'') '; SQL := SQL + 'AS VARCHAR) '; SQL := SQL + 'AS MyID FROM dbo.KUBUN'; ADOQuery1.Close; ADOQuery1.SQL.Text := SQL; ADOQuery1.Open; // このSQLは指定IDを見つけてその親IDを返すため、 // 一番上ノードのIDを与えるとエラーになります。 // なので、そのIDになったときに処理を終了させます。 if ADOQuery1.Eof then Break; I := ADOQuery1.FieldValues['MyID']; if I = TopNodeID then Break; Result := Result + '/' + IntToStr(I); MyID := ADOQuery1.FieldValues['MyID']; end; ADOQuery1.Close; end;
| 固定リンク