存储过程变量定义的 nvarchar(max) 被截断为 4000 个字符

Stored procedure variable defined nvarchar(max) gets truncated to 4000 chars

当我打印 @v_sql 参数时,我得到 4000 个字符。

我该如何解决这个问题?

来源:

BEGIN
    SET NOCOUNT ON;
    DECLARE @v_sql nvarchar(max)
    SELECT @v_sql = N'';
    IF UPPER(@action)='DISABLE'
    BEGIN
        SELECT @v_sql = @v_sql + 'ALTER INDEX '+ QUOTENAME(name,'[')+' ON ' + quotename( OBJECT_SCHEMA_NAME(object_id),'[') +'.'+ quotename( OBJECT_NAME(object_id),'[') + ' DISABLE;'+char(10)
        FROM sys.indexes
        WHERE OBJECTPROPERTY([object_id], 'IsMsShipped') = 0 AND type =2;   
    END
    IF UPPER(@action)='REBUILD'
    BEGIN
        SELECT @v_sql = @v_sql + 'ALTER INDEX '+QUOTENAME(name,'[')+' ON ' +  quotename( OBJECT_SCHEMA_NAME(object_id),'[') +'.'+ quotename( OBJECT_NAME(object_id),'[') + ' REBUILD WITH(SORT_IN_TEMPDB=ON);'+char(10)
        FROM sys.indexes
        WHERE OBJECTPROPERTY([object_id], 'IsMsShipped') = 0 AND type =2;
    END
    IF @v_sql <> ''
    BEGIN
        print @v_sql
        --EXEC sp_executesql @v_sql;
    END
END

它被打印截断了 - "The varchar(max) and nvarchar(max) data types are truncated to data types that are no larger than varchar(8000) and nvarchar(4000)."

在我的例子中,我希望能够复制粘贴 sp 的结果,所以解决方案是:

1) 将 print 替换为 select 2) 在char(10)

之后添加char(13)
BEGIN
    SET NOCOUNT ON;
    DECLARE @v_sql nvarchar(max)
    SELECT @v_sql = N'';
    IF UPPER(@action)='DISABLE'
    BEGIN
        SELECT @v_sql = @v_sql + 'ALTER INDEX '+ QUOTENAME(name,'[')+' ON ' + quotename( OBJECT_SCHEMA_NAME(object_id),'[') +'.'+ quotename( OBJECT_NAME(object_id),'[') + ' DISABLE;'+char(10) + char(13)
        FROM sys.indexes
        WHERE OBJECTPROPERTY([object_id], 'IsMsShipped') = 0 AND type =2;   
    END
    IF UPPER(@action)='REBUILD'
    BEGIN
        SELECT @v_sql = @v_sql + 'ALTER INDEX '+QUOTENAME(name,'[')+' ON ' +  quotename( OBJECT_SCHEMA_NAME(object_id),'[') +'.'+ quotename( OBJECT_NAME(object_id),'[') + ' REBUILD WITH(SORT_IN_TEMPDB=ON);'+char(10) + char(13)
        FROM sys.indexes
        WHERE OBJECTPROPERTY([object_id], 'IsMsShipped') = 0 AND type =2;
    END
    IF @v_sql <> ''
    BEGIN
        select @v_sql
        --EXEC sp_executesql @v_sql;
    END
END

你说得对,我们在PRINT中获取数据时被截断了,但是实际数据执行时不会被截断,只是我们必须将长度定义为MAX .

Sqlserver 也支持 8000 个字符。唯一的东西,你看不到,但它会被sqlserver执行。

表示EXEC sp_executesql @v_sql;将执行sqlserver追加尽可能多的长字符串。并执行。

我认为您遇到了错误,因为我们需要打印实际查询。是的,如果是,那么我有一个解决方案,您可以破坏独立执行或工作的代码。

您可以使用一个结果集中的核心值,检查是否会产生问题,然后remove/add一些过滤更多数据的条件。

你终于得到了造成问题的数据。

运行只有这一部分,然后是第二部分。

DECLARE @v_sql nvarchar(max)
    SELECT @v_sql = N'';
    IF UPPER(@action)='DISABLE'
    BEGIN
        SELECT @v_sql = @v_sql + 'ALTER INDEX '+ QUOTENAME(name,'[')+' ON ' + quotename( OBJECT_SCHEMA_NAME(object_id),'[') +'.'+ quotename( OBJECT_NAME(object_id),'[') + ' DISABLE;'+char(10) + char(13)
        FROM sys.indexes
        WHERE OBJECTPROPERTY([object_id], 'IsMsShipped') = 0 AND type =2;   
    END
    IF @v_sql <> ''
       BEGIN
         select @v_sql
         --EXEC sp_executesql @v_sql;
       END

nvarchar(max) still being truncated