pet*_*ter 94 sql t-sql sql-server sql-server-2005 sql-server-2008
我有一个代码是:
DECLARE @Script VARCHAR(MAX)
SELECT @Script = definition FROM manged.sys.all_sql_modules sq
where sq.object_id = (SELECT object_id from managed.sys.objects
Where type = 'P' and Name = 'usp_gen_data')
Declare @Pos int
SELECT @pos=CHARINDEX(CHAR(13)+CHAR(10),@script,7500)
PRINT SUBSTRING(@Script,1,@Pos)
PRINT SUBSTRING(@script,@pos,8000)
Run Code Online (Sandbox Code Playgroud)
脚本的长度大约是10,000个字符,因为我使用的print语句最多只能容纳8000个.所以我使用了两个打印语句.
问题是,当我有一个脚本,比如18000个字符,然后我习惯使用3个打印语句.
那么有没有办法可以根据脚本的长度设置打印语句的数量?
alf*_*oks 188
我知道这是一个老问题,但我所做的并没有在这里提到.
对我来说,以下工作.
DECLARE @info NVARCHAR(MAX)
--SET @info to something big
PRINT CAST(@info AS NTEXT)
Run Code Online (Sandbox Code Playgroud)
Jir*_*ika 93
以下解决方法不使用该PRINT
语句.它与SQL Server Management Studio结合使用效果很好.
SELECT CAST('<root><![CDATA[' + @MyLongString + ']]></root>' AS XML)
Run Code Online (Sandbox Code Playgroud)
您可以单击返回的XML以在内置XML查看器中展开它.
显示的大小对客户端有一个非常慷慨的限制.Tools/Options/Query Results/SQL Server/Results to Grid/XML data
如果需要,转到调整它.
小智 38
这是应该如何做到的:
DECLARE @String NVARCHAR(MAX);
DECLARE @CurrentEnd BIGINT; /* track the length of the next substring */
DECLARE @offset tinyint; /*tracks the amount of offset needed */
set @string = replace( replace(@string, char(13) + char(10), char(10)) , char(13), char(10))
WHILE LEN(@String) > 1
BEGIN
IF CHARINDEX(CHAR(10), @String) between 1 AND 4000
BEGIN
SET @CurrentEnd = CHARINDEX(char(10), @String) -1
set @offset = 2
END
ELSE
BEGIN
SET @CurrentEnd = 4000
set @offset = 1
END
PRINT SUBSTRING(@String, 1, @CurrentEnd)
set @string = SUBSTRING(@String, @CurrentEnd+@offset, LEN(@String))
END /*End While loop*/
Run Code Online (Sandbox Code Playgroud)
Kel*_*sey 17
您可以WHILE
根据脚本长度的计数除以8000 来执行循环.
例如:
DECLARE @Counter INT
SET @Counter = 0
DECLARE @TotalPrints INT
SET @TotalPrints = (LEN(@script) / 8000) + 1
WHILE @Counter < @TotalPrints
BEGIN
-- Do your printing...
SET @Counter = @Counter + 1
END
Run Code Online (Sandbox Code Playgroud)
Edy*_*dyn 13
遇到这个问题,想要更简单的东西...尝试以下方法:
SELECT [processing-instruction(x)]=@Script FOR XML PATH(''),TYPE
Run Code Online (Sandbox Code Playgroud)
And*_*zov 11
这个proc正确地打印出VARCHAR(MAX)
考虑包装的参数:
CREATE PROCEDURE [dbo].[Print]
@sql varchar(max)
AS
BEGIN
declare
@n int,
@i int = 0,
@s int = 0, -- substring start posotion
@l int; -- substring length
set @n = ceiling(len(@sql) / 8000.0);
while @i < @n
begin
set @l = 8000 - charindex(char(13), reverse(substring(@sql, @s, 8000)));
print substring(@sql, @s, @l);
set @i = @i + 1;
set @s = @s + @l + 2; -- accumulation + CR/LF
end
return 0
END
Run Code Online (Sandbox Code Playgroud)
我正在寻找使用print语句来调试一些动态的sql,因为我想大多数人都是因为simliar原因而使用print.
我尝试了一些列出的解决方案,发现Kelsey的解决方案适用于小问题(@sql是我的@script)nb LENGTH不是一个有效的函数:
--http://stackoverflow.com/questions/7850477/how-to-print-varcharmax-using-print-statement
--Kelsey
DECLARE @Counter INT
SET @Counter = 0
DECLARE @TotalPrints INT
SET @TotalPrints = (LEN(@sql) / 4000) + 1
WHILE @Counter < @TotalPrints
BEGIN
PRINT SUBSTRING(@sql, @Counter * 4000, 4000)
SET @Counter = @Counter + 1
END
PRINT LEN(@sql)
Run Code Online (Sandbox Code Playgroud)
这段代码注释会在输出中添加一个新行,但是对于调试来说,这对我来说不是问题.
Ben B的解决方案是完美的,并且是最优雅的,虽然调试是很多代码行,所以我选择使用我对Kelsey的轻微修改.可能值得在msdb中为Ben B的代码创建一个类似存储过程的系统,可以在一行中重用和调用它?
不幸的是,Alfoks的代码不起作用,因为这样会更容易.
或者简单地:
PRINT SUBSTRING(@SQL_InsertQuery, 1, 8000)
PRINT SUBSTRING(@SQL_InsertQuery, 8001, 16000)
Run Code Online (Sandbox Code Playgroud)
/*
---------------------------------------------------------------------------------
PURPOSE : Print a string without the limitation of 4000 or 8000 characters.
/sf/ask/549533421/
USAGE :
DECLARE @Result NVARCHAR(MAX)
SET @Result = 'TEST'
EXEC [dbo].[Print_Unlimited] @Result
---------------------------------------------------------------------------------
*/
ALTER PROCEDURE [dbo].[Print_Unlimited]
@String NVARCHAR(MAX)
AS
BEGIN
BEGIN TRY
---------------------------------------------------------------------------------
DECLARE @CurrentEnd BIGINT; /* track the length of the next substring */
DECLARE @Offset TINYINT; /* tracks the amount of offset needed */
SET @String = replace(replace(@String, CHAR(13) + CHAR(10), CHAR(10)), CHAR(13), CHAR(10))
WHILE LEN(@String) > 1
BEGIN
IF CHARINDEX(CHAR(10), @String) BETWEEN 1 AND 4000
BEGIN
SET @CurrentEnd = CHARINDEX(CHAR(10), @String) -1
SET @Offset = 2
END
ELSE
BEGIN
SET @CurrentEnd = 4000
SET @Offset = 1
END
PRINT SUBSTRING(@String, 1, @CurrentEnd)
SET @String = SUBSTRING(@String, @CurrentEnd + @Offset, LEN(@String))
END /*End While loop*/
---------------------------------------------------------------------------------
END TRY
BEGIN CATCH
DECLARE @ErrorMessage VARCHAR(4000)
SELECT @ErrorMessage = ERROR_MESSAGE()
RAISERROR(@ErrorMessage,16,1)
END CATCH
END
Run Code Online (Sandbox Code Playgroud)
你可以用这个
declare @i int = 1
while Exists(Select(Substring(@Script,@i,4000))) and (@i < LEN(@Script))
begin
print Substring(@Script,@i,4000)
set @i = @i+4000
end
Run Code Online (Sandbox Code Playgroud)