SQL Server 2008 Management Studioでtextまたはvarchar(MAX)列の完全なコンテンツを表示するにはどうすればよいですか?


94

このライブSQL Server 2008(ビルド10.0.1600)データベースにEventsは、textという名前の列を含むテーブルがありますDetails。(はい、これは実際にはvarchar(MAX)列であるべきだと思いますが、このデータベースをセットアップした人は誰もそうしませんでした。)

この列には、SQL Server Management Studioを介してアクセスしようとしている非常に大きな例外のログと関連するJSONデータが含まれていますが、グリッドからテキストエディターに結果をコピーするたびに、43679文字で切り捨てられます。

インターネット上のさまざまな場所で、XMLデータに対して取得する最大Tools > Options > Query Results > SQL Server > Results To Grid文字数を無制限に設定して、次のようなクエリを実行できることを確認しました。

select Convert(xml, Details) from Events
where EventID = 13920

(データは列ではなくXMLであることに注意してください。CONVERT列をXMLに変換することは、SSMSがtextor varchar(MAX)列からデータを取得することでSSMSが持っている制限を回避するために他の誰かが使用していたことをグーグルから見つけた回避策にすぎません。)

しかし、上記のオプションを設定してクエリを実行し、結果のリンクをクリックしても、次のエラーが発生します。

XMLを表示できません。次のエラーが発生しました:予期しないファイルの終わりが発生しました。行5、位置220160。

1つの解決策は、XMLデータ用にサーバーから取得する文字数を増やすことです。この設定を変更するには、[ツール]メニューの[オプション]をクリックします。

では、このデータにアクセスする方法について何か考えはありますか?列を変換してvarchar(MAX)私の問題を修正しますか?

回答:


97

SSMSは、XMLデータに対して無制限のデータのみを許可します。これはデフォルトではなく、オプションで設定する必要があります。

ここに画像の説明を入力してください

非常に限られた状況で機能する1つのトリックは、列に以下のような特別な方法で名前を付けるだけで、XMLデータとして扱われます。

DECLARE @S varchar(max) = 'A'

SET @S =  REPLICATE(@S,100000) + 'B' 

SELECT @S as [XML_F52E2B61-18A1-11d1-B105-00805F49916B]

SSMS(少なくともバージョン2012から18.3の現在)では、次のように結果が表示されます

ここに画像の説明を入力してください

それをクリックすると、XMLビューアに完全な結果が表示されます。右にスクロールすると、Bの最後の文字が保持されていることを示します。

ただし、これにはいくつかの重大な問題があります。クエリに列を追加すると効果がなくなり、追加の行はすべて最初の列と連結されます。最後に、文字列に<XMLビューアを開くなどの文字が含まれている場合、解析エラーで失敗します。

SQL Serverは変換の問題を回避これを行うための、より堅牢な方法<&lt;起因するこれらの文字になどまたは失敗は(下にあるここではクレジットアダムMachanic)。

DECLARE @S varchar(max)

SELECT @S = ''

SELECT @S = @S + '
' + OBJECT_DEFINITION(OBJECT_ID) FROM SYS.PROCEDURES

SELECT @S AS [processing-instruction(x)] FOR XML PATH('')

2
ConvertステートメントへのCDATAの追加が機能しました!どうもありがとう。:)
adamjford

追加CDATAは機能しますが、データに制御文字が含まれている場合は、置換操作を実行する必要があります。私の場合、データ内で単位区切り文字、ASCIIコード31を使用していました。REPLACE(details, char(31), '&x1f;')あちらこちらでその一文字だけを使っていたので、シンプルで十分。不明な文字やさまざまな文字を置き換える必要がある場合は、別の解決策を見つける必要があったかもしれません。
ザレフェス2014年

@Zarepheth-それCDATAは私の最初の提案でした。AS [processing-instruction(x)]後者はそれを回避します。
マーティン・スミス

1
@MartinSmith素晴らしい答え!私はあなたの答えからどれだけ学ぶのだろう。1
キン・シャー


25

1つの回避策は、結果セットを右クリックして、[名前を付けて結果を保存...]を選択することです。これにより、列の内容全体を含むCSVファイルにエクスポートされます。完璧ではありませんが、私には十分うまくいきました。

回避策


10

この簡単な解決策を試しましたか?わずか2クリックで!

クエリウィンドウで、

  1. クエリオプションを「Results to Grid」に設定し、クエリを実行します
  2. グリッドの隅にある結果タブを右クリックし、結果をファイルとして保存します

ファイルに表示するすべてのテキストが表示されます!!! varchar(MAX)フィールドの結果に130,556文字が表示される

結果はファイルになります


1
ストレート-簡単-そして、再びそれが必要になるまで常に忘れられます:)
Dimi Takis

5

私が見つけた最も簡単な回避策は、テーブルをバックアップしてスクリプトを表示することです。これをする

  1. データベースを右クリックして、Tasks> を選択します。Generate Scripts...
  2. 「はじめに」ページクリック Next
  3. 「オブジェクトの選択」ページ
    1. を選択し、Select specific database objectsテーブルを選択します。
    2. クリック Next
  4. 「スクリプトオプションの設定」ページ
    1. 出力タイプを Save scripts to a specific location
    2. Save to file関連するオプションを選択して入力します
    3. クリックAdvancedボタンを
    4. General> Types of data to scriptData onlyまたはに設定Schema and Dataして[OK]をクリックします
    5. クリック Next
  5. 「概要ページ」次へ
  6. SQLスクリプトは、4.2で設定したオプションに基づいて生成する必要があります。このファイルを開いて、データを表示します。

3

データ型TEXTは古く、もう使用するべきではありません。TEXT列からデータを選択するのは面倒です。

ntext、text、およびimage(Transact-SQL)

ntext、text、およびimageデータ型は、Microsoft SQL Serverの将来のバージョンで削除される予定です。新しい開発作業でこれらのデータ型を使用することは避け、現在それらを使用しているアプリケーションの変更を計画してください。代わりにnvarchar(max)、varchar(max)、およびvarbinary(max)を使用してください。

テキストデータを取得するには、TEXTPTR(Transact-SQL)を使用する必要があります。

テキストデータタイプの処理に関するこの記事も参照してください。


varchar(MAX)SSMSがデータを切り捨てないように列を変換しますか?
adamjford

最初にSSMSを使用してスクリプトを生成し、TEXT列をvarchar(max)に変換します。そこからさらにXML列に変換するかどうかを評価できます。SSMSの表示制限については、グリッドへの結果は、列あたり最大65,535文字の非xmlデータを表示するように設定でき、無制限の量のxmlデータを表示できます(fyi、XMLタイプのテーブル列は2 GBしか保存できません)。テキストへの結果は、列あたり8192文字に制限されています。これらのデフォルトの最大制限を設定するには、(SSMSで)[ツール]メニュー、[オプション...]、[クエリ結果]、[SQLサーバー]、[RESULTS TO GRID]または[RESULTS TO TEXT]の順に移動します。
和基。

3

Xmlが正しく形成されていないようです。その場合、Xmlとしてキャストできなくなり、Management Studioで返すことができるテキストの量が制限されます。ただし、次のようにテキストを小さなチャンクに分割できます。

With Tally As
    (
        Select ROW_NUMBER() OVER ( ORDER BY s1.object_id ) - 1 As Num
        From sys.sysobjects As s1
            Cross Join sys.sysobjects As s2
    )
Select Substring(T1.textCol, T2.Num * 8000 + 1, 8000)
From Table As T1
    Cross Join Tally As T2
Where T2.Num <= Ceiling(Len(T1.textCol) / 8000)
Order By T2.Num

その後、それらを再度手動で組み合わせる必要があります。

編集

textXmlパーサーが気に入らない文字がデータに含まれているようです。これらの値をエンティティに変換してから、Convert(xml, data)トリックを試すことができます。だから次のようなもの:

Update Table
Set Data = Replace(Cast(Data As varchar(max)),'<','&lt;')

(置換関数はtext列で機能しないため、varchar(max)にキャストする必要がありtextましたvarchar(max)。これらの列をに変換できなかった理由はありません。)


ああ、私は列がまったくXMLではないことを言及する必要があると思います。列をXMLに変換することは、Sogがtextor varchar(MAX)列からデータを取得することによるSSMSの制限を回避するために他の誰かが使用していたことをグーグルから見つけた回避策にすぎません。
adamjford

1
上記のコードの編集; Tally As(Select ROW_NUMBER()OVER(ORDER BY s1.id)-1 As Num From sys.sysobjects As s1 Cross Join sys.sysobjects As s2)Select Substring(T1.YourTextCol、T2.Num * 8000 + 1、8000)YourTable From T1 Cross Join Tally As T2 Where T2.Num <= Ceiling(datalength(T1.YourTextCol)/ 8000)Order By T2.Num
Ian Quigley

TSQLこの答えに基づいて@IanQuigleyのfromを使用すると、うまくいきました。基本的に結果(最終的には11レコード)を取り、メモ帳に貼り付けました。完璧に働きました。このスクリプトを保存する必要があります。無効な文字を含んだクレイジーな長いXMLがありました。
atconway 2013

1

私は、SSMSでセルごとに列をクリックできるようにするこの単純なXMLハックを好みます。この方法を使用すると、SSMSの表形式ビューでデータをすばやく表示し、特定のセルをクリックして、興味があるときに完全な値を表示できます。これは、XMLエラーを回避することを除いて、OPの手法と同じです。

SELECT
     e.EventID
    ,CAST(REPLACE(REPLACE(e.Details, '&', '&amp;'), '<', '&lt;') AS XML) Details
FROM Events e
WHERE 1=1
AND e.EventID BETWEEN 13920 AND 13930
;

一部の文字はXML 1.0では無効ですが、NVARCHAR/ では有効ですVARCHAR。たとえば、NUL文字(NULLフィールドの値とは異なります)。このような埋め込み値を持つ文字列のキャストは失敗します。
ビンキ

1

SSMS 18.2以降、グリッドの結果で最大200万文字を表示できるようになりました。ソース

より多くのデータが表示され(結果がテキスト)、セルに格納される(結果がグリッド)。SSMSでは現在、両方で最大200万文字を使用できます。

以下のコードで確認しました。

DECLARE @S varchar(max) = 'A'

SET @S =  REPLICATE(@S,2000000) + 'B' 

SELECT @S as a

1
最大文字数は実際には2097152ですSSMSバージョン15.0.18333.0の場合)。
ストーマ

0

あなたは運が悪いと思います。他のすべての回答に焦点が当てられているように見えるため、問題はSQLレベルの問題ではなく、単にユーザーインターフェイスの1つにすぎません。Management Studioは、汎用の汎用データアクセスインターフェイスではありません。インターフェイスではなく管理領域があり、バイナリデータと大きなテストデータの処理には重大な制限があります。指定された使用プロファイル内で使用すると、この問題が発生しないためです。

大きなテキストデータを表示することは、計画された使用法ではありません。

唯一の選択肢は、テキスト入力を受け取り、行ごとに行を切り取るテーブル値関数です。これにより、Management Studioは単一の行ではなく行のリストを取得します。


この答えは当て推量であると思いますが、「計画的な使用」のソースはありますか?SQLの「管理スタジオ」の場合、少なくともデータベースのコンテンツを表示できる必要があります。絶対にひどいUI。
1

この回答は適用されなくなったため、削除する必要があります
Caius Jard
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.