2011-09-12 15 views
7
DECLARE @str VARCHAR (MAX); 

SELECT @str = COALESCE(@str + CHAR(10), '') + 
     'EXECUTE CreateDeno ' + CAST(ID AS VARCHAR) 
FROM GL_To_Batch_Details 
WHERE TYPE = 'C' AND 
     Deno_ID IS NULL; 

--PRINT @str;--SELECT @str; 
**EXEC(@str);** 

切り捨てEDITEDT-SQL VARCHAR(MAX)

EXECUTE文はPRINTのような8,000文字までの文字列を切り捨てていますか? 8,000文字以上の動的SQL文を実行するにはどうすればよいですか?

何かアドバイスをいただければ幸いです。

+3

は、私はあなたが混乱していると思う、あなたは 'その@strが、私は問題のより具体的に質問を編集した – Lamak

+0

切り捨てされているという意味ではありませんので、8000個の以上の文字をPRINT'することはできません。実際にEXECUTEでエラーが発生したときは、PRINTを使用して動的T-SQLが生成されたものを確認しました。どちらの場合も、nvarchar(MAX)値は切り捨てられていました。何か案は? –

答えて

12
がそうであるように、これは長さを印刷し実行します

PRINTの出力は8kに制限されています。

SSMSの結果ペインにも8kの制限があります。 >オプション - -

ツールへ

ゴー>クエリは、オプションを表示する

結果。

は、実際のデータの長さを確認するには、チェック:

SELECT LEN(@str)

+0

EXECの代わりにPRINTを使用して、実際の問題点を確認します。 –

+0

@Nick Bennet:[MSDN](http://msdn.microsoft.com/en-us/library/ms188332(v = SQL.90).aspx):以前のバージョンのSQL Serverでは、文字列は8,000バイト。これには、動的実行のために大きな文字列を連結する必要があります。 SQL Server 2005では、varchar(max)およびnvarchar(max)データ型を指定することで、文字列を最大2ギガバイトのデータにすることができます。 – Andomar

+0

NVARCHAR(MAX)データ型とsp_executesqlを併用する必要がありました。 sp_executesqlを使用せずに同じことが達成できることを確認してください。ありがとう。 –

2

varchardefault lengthは30文字です。

CAST (ID AS VARCHAR) 

はそれが可能idが30文字より長いということですか?

+0

いいえ、IDが30文字を超えることはできません。 –

+1

デフォルトの長さを決して使用しないことをお勧めします。デフォルトのlenが1の場合もあります。 – HLGEM

2

出力の長さ(またはvarchar(max))にかかわらず、コマンドは確かに8000文字に制限されています。あなたの編集への答えでは、幹部は、文字列の長さを制限しません。これを回避するには、出力に<8000文字


更新のチャンクで文字列を必要としています。私はこれを表示するために一緒に次の例を入れている:

DECLARE @str VARCHAR (MAX); 


;WITH CTE_Count AS 
(
    select counter = 1 
    union all 
    select counter = counter+1 
    from CTE_Count 
    Where counter < 2000 

) 
SELECT    
    @str=COALESCE(@str + CHAR (10) , 
     '') + 'select value=' + CAST (counter AS VARCHAR) 
from 
    CTE_Count 

Option (MAXRECURSION 0) 

PRINT len(@str);--SELECT @str; 

exec (@str) 

は34892の文字、およびすべての2000実行文が実行(!警告され、それが数分かかる場合があります)

0

1つのvarchar型(最大)の結果が病気「暗黙のキャスト」VARCHARすること(ない場合は、リテラルを連結するときに発生8000)。

リテラルvarchar(max)を生成するには、すべてのパートがvarchar(max)でなければなりません。 注:varchar(max)カラムのアップデートを行ったことがありましたが、EXECコマンドでテストしたことはありませんでした。

また、以前の回答に記載されているように、printコマンドには制限がありますが、その代わりにその変数を選択してみてください。

1

文字列を連結し、結果がVARCHAR(MAX)タイプで8000文字以上の場合、少なくとも1つのパラメータおよび/または要素連結で使用されている場合は、VARCHAR(MAX)型にする必要があります。そうしないと、結果の文字列に切り捨てが発生し、EXEC文では実行できません。

例:MSDN

DECLARE @sql AS VARCHAR(MAX); 
/* DECLARE @someItem AS VARCHAR(100); -- WILL CAUSE TRUNCATION WHEN @sql HAS LEN > 8000 */ 
DECLARE @someItem AS VARCHAR(MAX); -- All string variables need to be VARCHAR(MAX) when concatenating to another VARCHAR(MAX) 

SET @someItem = 'Just assume the resulting @sql variable goes over 8000 characters...'; 
SET @sql = 'SELECT Something FROM Somewhere WHERE SomeField = ''' + @someItem + ''''; 

EXEC (@sql); 
--PRINT @sql; 

詳細情報。連結 ストリングの少なくとも一方が大きい値型である場合

「文字列の連結の結果は 8,000バイトの制限を超える場合、結果は切り捨てられているが、切り捨てが は発生しません"

0

私はまた、私がExecに送信していたものを見たいと思っており、PRINTの制限によって混乱しました。 procをチャンクで印刷する必要がありました。

CREATE PROCEDURE [dbo].[KFX_PrintVarcharMax] 
    @strMax varchar(max) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE 
     @index int = 0, 
     @start int = 1, 
     @blkSize int = 2000; 


    WHILE @Start < LEN(@strMax) 
    BEGIN 
     IF @start + @blkSize >= LEN(@strMax) 
     BEGIN 
      -- If remainder is less than blocksize print the remainder, and exit. 
      PRINT SUBSTRING(@strMax, @start, @blkSize) 
      BREAK; 
     END 
     -- Else find the next terminator (beyond the blksize) 
     SET @index = CHARINDEX(CHAR(10), @strMax, @start + @blkSize); 
     if @index >= @start 
     BEGIN 
      PRINT SubString(@strMax, @start, @index - @start + 1) 
      SET @start = @index + 1; 
      SET @blkSize = CASE WHEN @start + 2000 < LEN(@strMax) THEN 2000 
          ELSE LEN(@strMax) - @start + 1 END 
     END 
     ELSE 
     BEGIN 
      -- No char(10) found. Just print the rest. 
      PRINT SUBSTRING(@strMax, @start, LEN(@strMax)) 
      BREAK; 
     END 
    END 

END