web-dev-qa-db-ja.com

ビュー列には8000文字の制限がありますか?

SQL Server 2008 R2では、更新可能なビューを使用してvarchar(max)列を更新しています。列をテキストで更新してから文字数を確認すると、更新に含まれる文字数が多くても、8000文字の長さが表示されています。

ビューが更新のために受け取ることができる文字数に何らかの制限はありますか?

わかりました私はこれについてアプリケーション開発チームと協力していて、彼らは彼らがそれを回避する方法を見つけたので、彼らがテストケースとして使用していたコードを破棄しました一般的なことをお伝えできるように頑張ります。更新ステートメントは次のようになります。

UPDATE vorders
set [description] = '<br> This is some text about the order </br>' 
    + CHAR(34) + 'This is more text' + CHAR(34) + 'and on it goes'
where orderid = 12345

次に、次のクエリを実行して、フィールドに入力された文字の長さを確認します

SELECT LEN([description])
  FROM vorders
 WHERE orderid = 12345

アプリケーションの連中が見つけたのは、コードの+ CHAR(34)+部分を削除すると、長さが最大8700文字になるということです。 + CHAR(34)+を使用すると、コードの一部でテキストが8000文字に切り捨てられました。これは、ある種の暗黙の変換であると私に疑わせました。ただし、1つまたは2つの+ CHAR(34)+を配置しても切り捨てが発生しないことがわかりました。元の文には30のようなものがありました。

何がこれを引き起こしているのか、どんな考えでも、私はこれで途方に暮れています。

2
Lumpy

列の長さを正確にチェックしていないと思います(Management StudioでのPRINTまたはSELECTの出力の検査と同様に、ツールによって切り捨てられ、データベースに実際にあるものを正確に反映していない)。 。ビューで公開または更新できる文字数に制限はありません。ただし、それらを紹介しない限り、_INSTEAD OF_トリガーを使用しているか、どこかで暗黙的な変換が行われているか、データが切り捨てbefore更新。詳細がわからないとわかりにくいので、ご提供いただければ幸いです。

その間、これを試してください:

_USE tempdb;
GO

CREATE TABLE dbo.foobar(x VARCHAR(MAX));
GO

CREATE VIEW dbo.v_foobar 
WITH SCHEMABINDING
AS
  SELECT x FROM dbo.foobar;
GO

INSERT dbo.v_foobar(x) VALUES('c');
GO

UPDATE dbo.v_foobar 
  SET x = REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 8000)
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 8000);
GO

SELECT LEN(x), DATALENGTH(x)
  FROM dbo.v_foobar;
GO
_

結果:

_-----    -----
16000    16000
_

また、CHAR(34)が原因であるとは確信していません。

_UPDATE dbo.v_foobar 
  SET x = CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x'
        + REPLICATE(CHAR(34), 400)
        + 'x'
        + REPLICATE(CHAR(34), 400)
        + 'x' 
        + REPLICATE(CHAR(34), 400)
        + 'x' + CHAR(34)
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 8000);

GO
SELECT LEN(x), DATALENGTH(x)
  FROM dbo.v_foobar;
_

結果:

_-----    -----
17226    17226
_

この文字列が生成されているとき、またはコマンドがSQL Serverに渡される前に、この文字列に何か他のことが起こっているのではないかと思います。

5
Aaron Bertrand

SQL Serverの管理スタジオには表示の制限があり、それが問題になる可能性があります。別のアプリケーションでこれらの大きなフィールドを確認する必要があります。 SSMSには、使用できるアドオンもいくつかあります。これはあなたを助けるかもしれません http://www.ssmsboost.com/

3
druzin