2011-09-12 33 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) rút gọn

Liệu EXECUTE tuyên bố cắt ngắn chuỗi đến 8.000 ký tự như PRINT? Làm thế nào tôi có thể thực hiện một câu lệnh SQL động có hơn 8.000 ký tự?

Mọi đề xuất sẽ được đánh giá cao.

+3

Tôi nghĩ rằng bạn đang bối rối, bạn không thể 'PRINT' hơn 8000 ký tự, điều đó không có nghĩa rằng @str đang được cắt ngắn – Lamak

+0

Tôi đã chỉnh sửa câu hỏi để được cụ thể hơn về vấn đề này. Thực ra khi EXECUTE tạo ra lỗi, tôi đã sử dụng PRINT để xem T-SQL động được tạo ra như thế nào. Trong cả hai trường hợp, giá trị nvarchar (MAX) đã bị cắt ngắn. Bất kỳ ý tưởng? –

Trả lời

12

PRINT bị giới hạn ở 8k ở đầu ra.

Ngoài ra còn có giới hạn 8k trong ngăn kết quả SSMS.

Đến

công cụ -> Tùy chọn -> kết quả truy vấn

để xem các tùy chọn.

Để xác minh độ dài của dữ liệu thực tế, kiểm tra:

SELECT LEN(@str)

+0

OK. IN được sử dụng ở đây thay vì EXEC để xem vấn đề thực tế là gì. –

+0

@Nick Bennet: [MSDN nói] (http://msdn.microsoft.com/en-us/library/ms188332 (v = SQL.90) .aspx): Trong các phiên bản trước của SQL Server, các chuỗi ký tự được giới hạn trong 8.000 byte. Điều này đòi hỏi phải ghép nối các chuỗi lớn để thực thi động. Trong SQL Server 2005, các kiểu dữ liệu varchar (max) và nvarchar (max) có thể được chỉ định cho phép các chuỗi ký tự có thể lên đến 2 gigabyte dữ liệu. – Andomar

+0

Tôi đã phải sử dụng loại dữ liệu NVARCHAR (MAX) cùng với sp_executesql để làm cho nó hoạt động. Bạn có thể vui lòng xác nhận cùng một điều có thể đạt được mà không cần sử dụng sp_executesql? Cảm ơn. –

2

Các default length của một varchar là 30 ký tự:

CAST (ID AS VARCHAR) 

Có thể rằng id dài hơn 30 ký tự?

+0

Không, ID không thể dài hơn 30 ký tự. –

+1

Đó là một thực hành tốt để không bao giờ sử dụng độ dài mặc định, có những lúc mà len mặc định là 1. – HLGEM

2

Lệnh PRINT chắc chắn bị giới hạn ở 8000 ký tự, không phụ thuộc vào độ dài của đầu ra (hoặc cho dù đó là varchar (max)). Để làm việc xung quanh này, bạn cần để sản xuất các chuỗi trong khối của <8000 chars


Cập nhật: Trong câu trả lời cho bạn chỉnh sửa, exec không giới hạn độ dài chuỗi. Tôi đã tổng hợp các ví dụ sau đây cho thấy điều này:

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) 

Chạy này in theo chiều dài như 34.892 ký tự, và tất cả 2000 thực hiện báo cáo không chạy (được cảnh báo, có thể mất một vài phút!)

0

Nó xảy ra khi bạn nối literals nếu người ta không là một varchar (max) kết quả bệnh có "tiềm ẩn đúc" để varchar (8000).

Để tạo một varchar chữ (tối đa) tất cả các phần phải là varchar (max). Lưu ý: Đã xảy ra với tôi khi cập nhật các cột varchar (max), không bao giờ được kiểm tra bằng lệnh EXEC.

Cũng như được nêu trong các câu trả lời trước, lệnh in giữ giới hạn nhưng bạn có thể thử chọn biến đó thay vì in. (cũng có giới hạn về độ dài chọn mà bạn có thể định cấu hình trên MS-SMS)

1

Khi ghép chuỗi và kết quả là loại VARCHAR (MAX) và hơn 8000 ký tự, ít nhất một tham số và/hoặc phần tử được sử dụng trong việc ghép nối cần phải có kiểu VARCHAR (MAX) nếu không cắt ngắn sẽ xuất hiện trong chuỗi kết quả và sẽ không thể thực thi được trong một câu lệnh EXEC.

Ví dụ:

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; 

Thông tin thêm về MSDN.

"Nếu kết quả của phép nối của chuỗi vượt quá giới hạn của 8.000 byte, kết quả được cắt ngắn. Tuy nhiên, nếu ít nhất một trong những dây nối là một loại giá trị lớn, cắt ngắn không xảy ra . "

0

Tôi cũng muốn xem những gì tôi đã gửi cho Exec và bị nhầm lẫn với giới hạn IN. Đã phải viết một proc để in theo khối.

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 
Các vấn đề liên quan