web-dev-qa-db-ja.com

結果をXMLにエクスポートする

SQLクエリからXMLファイルを作成しようとしています。出力は下の画像のようになります

enter image description here

BranchIDに関連付けられているSubParentBranchIDが複数ある場合、タグSubBranchIDBranchIDとして再び表示されます。下の画像では、BranchID 94には2つのSubBranchID 63と64があります。

このSQLクエリを管理しました

SELECT
a.[heading_id] as BranchID,
c.[name] as BranchName,
a.[business_id] as SubBranchID, 
a.[heading_id] as SubParentBranchID,
b.[name] as SubBranchName
   FROM [BUSINESSHEADINGLINK] as a
   join [BUSINESS] as b on a.business_id = b.business_id
   join [HEADING] as c on   a.heading_id = c.heading_id 
FOR XML PATH ('Branch'), ROOT('BranchInfo')

これは私に次のXMLを与えます

enter image description here

ここでは、<SubBranches>タグも<SubBranch>タグもないことがわかります。また、私は<SubParentBranchID>を持っていません。 XMLファイルは次のようになります。

enter image description here

誰かがSQLコードを手伝ってくれる?

また、実行後にC:/tempに保存したいと思います。

6
itsAftab

パート1:適切なXML構造

フラットなXMLレイアウト以外のものを取得するには、_FOR XML EXPLICIT_モードまたはネストされた_FOR XML AUTO_クエリを使用する必要があります。例を含む詳細については、次のMSDNセクションを参照してください。

また、_<SubParentBranchID>_要素は完全に不要であるため、生成する必要はありません。 XMLの良い点の1つは、現在の場所から親ノードを取得できることです:)。

パート2:ファイルへのエクスポート

これは、変数(またはクエリ)の内容をテキストファイルに保存する単純なSQLCLR関数でかなり簡単に実行できます。

_[Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = false, IsPrecise = true)]
public static SqlString SaveXmlToFile([SqlFacet(MaxSize = 4000)] SqlString FilePath,
    SqlXml XmlData)
{
    try
    {
        File.WriteAllText(FilePath.Value, XmlData.Value, Encoding.Unicode);
    }
    catch (Exception __Exception)
    {
        return __Exception.Message;
    }

    return String.Empty;
}
_

また、_RETURNS NULL ON NULL INPUT_オプションを使用しているため、.IsNull()を使用して入力パラメータのNULLチェックを行う必要はありません。

_CREATE FUNCTION [dbo].[SaveXmlToFile](@FilePath NVARCHAR(4000), @XmlData XML)
RETURNS NVARCHAR(4000)
WITH EXECUTE AS CALLER,
     RETURNS NULL ON NULL INPUT
AS EXTERNAL NAME [SomeAssemblyName].[FileUtils].[SaveXmlToFile];
_

その後、次のように使用できます:

_DECLARE @Output XML;

SET @Output = (
   SELECT ...
   FOR XML ...;
);

DECLARE @ErrorMessage NVARCHAR(4000);
SET @ErrorMessage = dbo.SaveXmlToFile(N'path/to/file.xml', @Output);
_

上記のSQLCLR関数を機能させるためのいくつかの簡単な手順(および_EXTERNAL_ACCESS_またはUNSAFEを必要とする、作成するほとんどのアセンブリ):

  1. 議会に署名する必要があります。 Visual Studioで、[プロジェクトのプロパティ]-> [SQLCLR]タブ-> [署名...]ボタンに移動します。

  2. 「CLR統合」を有効にする必要があります。

    _EXEC sp_configure 'clr enabled', 1;
    RECONFIGURE;
    _
  3. DLLから_[master]_に 非対称キー を作成します。

    _USE [master];
    CREATE ASYMMETRIC KEY [KeyName]
    FROM EXECUTABLE FILE = 'Path\to\SomeAssemblyName.dll';
    _
  4. DLLからログイン_[master]_を作成します。

    _CREATE LOGIN [SomeLoginName]
    FROM ASYMMETRIC KEY [KeyName];
    _
  5. キーベースのログインに適切な権限を付与します。

    _GRANT EXTERNAL ACCESS Assembly TO [SomeLoginName];
    _

これらの手順のどれもTRUSTWORTHYのデータベースプロパティをONに変換しなかったことに注意してください。


コーディング、コンパイル、非対称キーやログインの作成などを行わずにこのSQLCLR関数を取得する別の方法は、インストールしたライブラリを事前に取得することです。 SQL# ライブラリにはいくつかのファイルシステム関数が含まれており、上記のすべての手順を省略します。私はSQL#の作成者であり、無料バージョンがありますが、ファイルシステム機能は完全バージョンでのみ使用できます。

9
Solomon Rutzky

構造の深さが2レベルしかない場合は、ネストされた1つのfor xmlクエリを使用して、次のようなサブブランチパーツを作成できます。

select H.heading_id as 'BranchID',
       H.name as 'BranchName',
       (
       select B.business_id as 'SubBranchID',
              H.heading_id as 'SubParentBrachID',
              B.name as 'SubBranchName'
       from dbo.BUSINESS as B
         inner join dbo.BUSINESSHEADINGLINK as L
           on B.business_id = L.business_id
       where L.heading_id = H.heading_id
       for xml path('SubBranch'), root('SubBranches'), type
       )
from dbo.HEADING as H
for xml path('Branch'), root('BranchInfo'), type;

SQLフィドル

3
Mikael Eriksson