[SQL] NVARCHAR (최대) 아직 잘리지
SQLNVARCHAR (최대) 아직 잘리지
나는 MS SQL Server 2008의 저장 프로 시저를 쓰고 있어요 그래서 그것은 정말로 긴 쿼리 내가 @query라는 변수를 생성하고 유형 NVARCHAR (MAX)의 그것을 만들 그래서 나는 동적으로 작성해야합니다. 지금, 나는이 SQL 서버, NVARCHAR (MAX)의 현대 버전에서 원래 4000 문자 최대보다 더 많은 방법을 데이터의 말도 안되는 금액을 보유 할 수 있다고 들었습니다. 나는 그것을 밖으로 인쇄 할 때, @query는 여전히 4000 자로 잘립니다지고있다.
DECLARE @Query NVARCHAR(max);
SET @Query = 'SELECT...' -- some of the query gets set here
SET @Query = @Query + '...' -- more query gets added on, etc.
-- later on...
PRINT LEN(@Query) -- Prints out 4273, which is correct as far as I can tell
PRINT @Query -- Truncates value to 4000 characters
EXEC sp_executesql @Query -- totally crashes due to malformed (truncated) query
오전 내가 잘못 일을하고, 아니면 NVARCHAR (MAX)가 어떻게 작동하는지에 대해 완전히 잘못입니까?
해결법
-
==============================
1.생성 된 동적 SQL을 보려면 텍스트 모드로 변경 (바로 가기 : Ctrl 키-T), 다음 SELECT를 사용
생성 된 동적 SQL을 보려면 텍스트 모드로 변경 (바로 가기 : Ctrl 키-T), 다음 SELECT를 사용
PRINT LEN(@Query) -- Prints out 4273, which is correct as far as I can tell --SET NOCOUNT ON SELECT @Query
sp_executesql에 관해서는,이 (텍스트 모드),이 세 가지 AAAAA를 표시해야합니다 시도 ... SELECT ... '추가'와 가장 긴되는 가운데 일이야 '를. 제 2 출력의 단부 (4510)을 도시 우측 하단에있는 상태 바의 LN ... .. 골 표시 시계.
declare @n nvarchar(max) set @n = REPLICATE(convert(nvarchar(max), 'a'), 4500) SET @N = 'SELECT ''' + @n + '''' print @n -- up to 4000 select @n -- up to max exec sp_Executesql @n
-
==============================
2.문제는 SET 문으로 관련이있는 것으로 보인다. 나는 표현의 크기는 4,000 바이트되지 않을 수 있다고 생각합니다. 당신이하려고하는 모든 이상 4,000 자 동적으로 생성 된 문을 지정하는 경우 모든 설정을 변경할 필요가 없습니다. 당신이해야하는 과제를 분할하는 것입니다. 당신의 문은 6,000 자하는 경우, 동일한 변수에 대한 논리적 브레이크 포인트 다음 CONCATENATE 하반기을 찾을 수 있습니다. 예를 들면 :
문제는 SET 문으로 관련이있는 것으로 보인다. 나는 표현의 크기는 4,000 바이트되지 않을 수 있다고 생각합니다. 당신이하려고하는 모든 이상 4,000 자 동적으로 생성 된 문을 지정하는 경우 모든 설정을 변경할 필요가 없습니다. 당신이해야하는 과제를 분할하는 것입니다. 당신의 문은 6,000 자하는 경우, 동일한 변수에 대한 논리적 브레이크 포인트 다음 CONCATENATE 하반기을 찾을 수 있습니다. 예를 들면 :
SET @Query = 'SELECT ....' [Up To 4,000 characters, then rest of statement as below] SET @Query = @Query + [rest of statement]
이제 정상으로 쿼리를 실행 즉 EXEC (@query)
-
==============================
3.당신이 합치되는 유니 코드가있는 경우 / NCHAR / NVARCHAR는 값, 다음 SQL Server는 암시 적으로 NVARCHAR (4000)로 문자열을 변환 것이며, 당신의 문자열을 자르거나 심지어 당신에게 데이터가되었다는 경고를 줄 것이다 실현하기 위해 불행하게도 너무 바보 그 문제에 관해서 잘립니다! 긴 문자열 합치하는 경우 (또는 당신이 느끼는 문자열을 할 수있을 긴) 항상 (NVARCHAR (MAX로 '')) CAST과 같이 사용하여 문자열 건물을 사전에 연결할 :
당신이 합치되는 유니 코드가있는 경우 / NCHAR / NVARCHAR는 값, 다음 SQL Server는 암시 적으로 NVARCHAR (4000)로 문자열을 변환 것이며, 당신의 문자열을 자르거나 심지어 당신에게 데이터가되었다는 경고를 줄 것이다 실현하기 위해 불행하게도 너무 바보 그 문제에 관해서 잘립니다! 긴 문자열 합치하는 경우 (또는 당신이 느끼는 문자열을 할 수있을 긴) 항상 (NVARCHAR (MAX로 '')) CAST과 같이 사용하여 문자열 건물을 사전에 연결할 :
SET @Query = CAST('' as nVarChar(MAX))--Force implicit conversion to nVarChar(MAX) + 'SELECT...'-- some of the query gets set here + '...'-- more query gets added on, etc.
어떤 고통과 무서운 것은이 SQL 서버가 작동 얼마나 생각합니다. :( 나는 / 여러 SET로 코드를 헤어 여러 변수를 사용하여 할당을 선택 말하는 웹에있는 다른 해결 방법을 알고 있지만,이 위의 솔루션을 제공 할 필요가 없습니다. 이 암시 적으로 VARCHAR (8000)로 변환 그래서 더 유니 코드 없었기 때문에 8000 문자 최대 히트 사람들을 위해, 아마이었다. 설명: 어떤 무대 뒤에서 일어나는 것은 당신이 사용 (MAX)에 할당하는 변수, SQL Server는 값의 오른쪽을 평가합니다 비록 당신이 NVARCHAR (4000) 또는 VARCHAR (8000) (따라 먼저 및 기본 할당하는 것입니다 )이 합치하는지에. 이 값을 알아내는 이루어집니다 (그리고 당신을 위해 그것을 절단 후) 그 다음으로 변환 한 후에 (MAX)하지만 너무 늦기하여, 당신의 변수에 할당 할 때.
-
==============================
4.텍스트 결과는 8192 자까지 가능합니다.
텍스트 결과는 8192 자까지 가능합니다.
나는이 방법을 사용
DECLARE @Query NVARCHAR(max); set @Query = REPLICATE('A',4000) set @Query = @Query + REPLICATE('B',4000) set @Query = @Query + REPLICATE('C',4000) set @Query = @Query + REPLICATE('D',4000) select LEN(@Query) SELECT @Query /*Won't contain any "D"s*/ SELECT @Query as [processing-instruction(x)] FOR XML PATH /*Not truncated*/
-
==============================
5.첫 번째 문제는 PRINT 문의 제한 사항입니다. 나는 sp_executesql에 실패하는 이유를 모르겠어요. 그것은 입력의 거의 모든 길이를 지원해야한다.
첫 번째 문제는 PRINT 문의 제한 사항입니다. 나는 sp_executesql에 실패하는 이유를 모르겠어요. 그것은 입력의 거의 모든 길이를 지원해야한다.
아마도 쿼리가 잘못되었습니다 이유는 절단 이외이다.
-
==============================
6.4000 개 문자에 8000, NVARCHAR (MAX)로 자릅니다에게 VARCHAR (MAX)를 인쇄합니다.
4000 개 문자에 8000, NVARCHAR (MAX)로 자릅니다에게 VARCHAR (MAX)를 인쇄합니다.
그러나;
PRINT CAST(@query AS NTEXT)
전체 쿼리를 인쇄합니다.
-
==============================
7.오늘 같은 문제가 발생하고 4000 자 제한을 넘어, 나는 두 개의 문자열로 동적 쿼리를 분할하고 쿼리를 실행할 때 그들을 연결하는 남겼습니다.
오늘 같은 문제가 발생하고 4000 자 제한을 넘어, 나는 두 개의 문자열로 동적 쿼리를 분할하고 쿼리를 실행할 때 그들을 연결하는 남겼습니다.
DECLARE @Query NVARCHAR(max); DECLARE @Query2 NVARCHAR(max); SET @Query = 'SELECT...' -- some of the query gets set here SET @Query2 = '...' -- more query gets added on, etc. EXEC (@Query + @Query2)
-
==============================
8.출력 모든이 인쇄 BIG 기능을 사용 :
출력 모든이 인쇄 BIG 기능을 사용 :
IF OBJECT_ID('tempdb..#printBig') IS NOT NULL DROP PROCEDURE #printBig GO CREATE PROCEDURE #printBig ( @text NVARCHAR(MAX) ) AS --DECLARE @text NVARCHAR(MAX) = 'YourTextHere' DECLARE @lineSep NVARCHAR(2) = CHAR(13) + CHAR(10) -- Windows \r\n DECLARE @off INT = 1 DECLARE @maxLen INT = 4000 DECLARE @len INT WHILE @off < LEN(@text) BEGIN SELECT @len = CASE WHEN LEN(@text) - @off - 1 <= @maxLen THEN LEN(@text) ELSE @maxLen - CHARINDEX(REVERSE(@lineSep), REVERSE(SUBSTRING(@text, @off, @maxLen))) - LEN(@lineSep) + 1 END PRINT SUBSTRING(@text, @off, @len) --PRINT '@off=' + CAST(@off AS VARCHAR) + ' @len=' + CAST(@len AS VARCHAR) SET @off += @len + LEN(@lineSep) END
출처:
https://www.richardswinbank.net/doku.php?id=tsql:print_big
-
==============================
9.문자열 표현식을 사용하여 동적 SQL을 만드는 문제는 SQL 4,000 문자로 문자열 식의 평가를 제한 않는다는 것입니다. 당신은 NVARCHAR (최대) 변수에 긴 문자열을 할당 할 수 있지만 당신이 표현에 + 포함 빨리으로 (예 : + CASE ... END의 +로), 다음 식의 결과는 4000 개 문자로 제한됩니다.
문자열 표현식을 사용하여 동적 SQL을 만드는 문제는 SQL 4,000 문자로 문자열 식의 평가를 제한 않는다는 것입니다. 당신은 NVARCHAR (최대) 변수에 긴 문자열을 할당 할 수 있지만 당신이 표현에 + 포함 빨리으로 (예 : + CASE ... END의 +로), 다음 식의 결과는 4000 개 문자로 제한됩니다.
이 문제를 해결하는 한 가지 방법은 + 대신 CONCAT를 사용하는 것입니다. 예를 들면 :
SET @sql = CONCAT(@sql, N' ... dynamic SQL statements ... ', CASE ... END, N' ... dynamic SQL statements ... ')
@Sql은 NVARCHAR (최대)로 선언되는 경우.
from https://stackoverflow.com/questions/4833549/nvarcharmax-still-being-truncated by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL 서버 : 어떻게 INFORMATION_SCHEMA에서 외래 키 참조를 얻으려면? (0) | 2020.04.04 |
---|---|
[SQL] 어디 | DataDirectory를 | 한정된? (0) | 2020.04.04 |
[SQL] 서브 쿼리가 존재합니다 도입되지 않은 경우 하나 개의 표현이 선택 목록에 지정할 수 있습니다 (0) | 2020.04.04 |
[SQL] 다른 테이블을 기반으로 테이블의 모든 행을 삭제 (0) | 2020.04.04 |
[SQL] 엑셀 VBA에서 액세스 SQL 데이터베이스 (0) | 2020.04.03 |