6

xml データを格納するために使用されるテーブルに varchar 列があります。ええ、使用すべき xml データ型があることは知っていますが、これは xml データ型が利用可能になる前に設定されたと思うので、今のところ varchar を使用する必要があります。:)

格納されたデータは次のようになります。

<xml filename="100100_456_484351864768.zip"  
     event_dt="10/5/2009 11:42:52 AM">
    <info user="TestUser" />
</xml>

ファイル名を解析して、2 つのアンダースコアの間の数字を取得する必要があります。この場合は「456」になります。ファイル名の最初の部分の長さは「変更すべきではありません」が、中間の数字は変更されます。最初の部分の長さが変わった場合に機能する解決策が必要です(「変更しないでください」は常に変更されることを意味しているように見えるため、変更されることはわかっています)。

今のところ、XQuery を使用してファイル名を取得しています。これはおそらく単純な文字列操作よりも優れていると考えたからです。これを行うために文字列を xml にキャストしましたが、私は XQuery の専門家ではないので、もちろん問題が発生しています。XQuery (substring-before) の関数を見つけましたが、機能させることができませんでした (その関数が SQL Server で機能するかどうかさえわかりません)。これを簡単に行うための XQuery 関数があるかもしれませんが、あるとしても私は知りません。

したがって、次のようなクエリを使用して、テーブルからファイル名を取得します。

select CAST(parms as xml).query('data(/xml/@filename)') as p
from Table1

これから、これを文字列にキャストしてから、 instring または charindex 関数を実行してアンダースコアがどこにあるかを把握し、そのすべてを部分文字列関数にカプセル化して部分を選択できると想定します私は欲しい。これに深く入り込まなくても、最終的にはこの方法で実行できると確信していますが、もっと簡単な方法が必要であることはわかっています。この方法では、SQL ステートメントに読み取り不可能な巨大なフィールドが作成され、それを関数に移動したとしても、何が起こっているのかを理解しようとすると混乱します。

単純な文字列操作のように見えるので、これよりも簡単な方法があると確信しています。おそらく、誰かが私を正しい方向に向けることができます。ありがとう

4

3 に答える 3

7

これには XQuery を使用できます。ステートメントを次のように変更するだけです。

SELECT
   CAST(parms as xml).value('(/xml/@filename)[1]', 'varchar(260)') as p
FROM 
   dbo.Table1

これにより、有効なファイル名とパスを保持するのに十分な長さの VARCHAR(260) が得られます。これで文字列が得られ、SUBSTRING などで作業できます。

マルク

于 2009-10-10T07:33:36.490 に答える
4

これを行う簡単な方法は、SUBSTRING と CHARINDEX を使用することです。ファイル名の最初の部分の長さは変わらないが、XQuery を使用してファイル名を見つけたいと仮定すると (賢明であろうとなかろうと)、必要なことを行う短い再現を次に示します。

declare @t table (
  parms varchar(max)
);
insert into @t values ('<xml filename="100100_456_484351864768.zip" event_dt="10/5/2009 11:42:52 AM"><info user="TestUser" /></xml>');

with T(fName) as (
  select cast(cast(parms as xml).query('data(/xml/@filename)') as varchar(100)) as p
  from @t
)
  select
    substring(fName,8,charindex('_',fName,8)-8) as myNum
  from T;

REPLACE や PARSENAME や REVERSE などの他の文字列関数を使用する卑劣なソリューションもありますが、これほど効率的で読みやすいものはありません。考慮すべき 1 つの可能性は、正規表現処理を SQL に組み込む CLR ルーチンを作成することです。

ところで、xml が常にこのように単純である場合、XQuery を使用する理由は特にありません。必要な数値を抽出する 2 つのクエリを次に示します。xml 文字列の余分な空白や、ファイル名の最初の部分の長さが変わる可能性を制御できない場合は、2 番目の方が安全です。

  select
    substring(parms,23,charindex('_',parms,23)-23) as myNum
  from @t;

  select
    substring(parms,charindex('_',parms)+1,charindex('_',parms,charindex('_',parms)+1)-charindex('_',parms)-1) as myNum
  from @t;
于 2009-10-10T03:20:06.667 に答える
1

残念ながら、SQL Serverは準拠したXQuery実装ではなく、XQuery仕様のドラフトバージョンのかなり限定されたサブセットです。がないだけでなく、を使用して自分で行う必要fn:substring-beforeもありません。したがって、私が知る限り、ここではSQLに固執しています。fn:index-offn:substringfn:string-to-codepoints

于 2009-10-09T23:02:49.337 に答える