varchar(max) 切割限制

Varchar(max) cutting limit

我需要一个脚本来为我的数据库中的每个标识列重新设定种子

我已经这样做了:

DECLARE @sqlreseed nvarchar(max)

SELECT 
    @sqlreseed = COALESCE(@sqlreseed + ' ', '') + 'set @id = (select isnull(max(' + cast(c.name as nvarchar(max)) +'), 0) + 1  from ' + CAST(t.name as nvarchar(max)) + ') DBCC CHECKIDENT (''' + cast(t.name as nvarchar(max)) +''', RESEED, @id); '
FROM 
    sys.schemas AS s
INNER JOIN 
    sys.tables AS t ON s.[schema_id] = t.[schema_id]
INNER JOIN 
    sys.identity_columns AS c on c.[object_id] = t.[object_id]

SET @sqlreseed = cast(cast('declare @id int ' as nvarchar(max)) + @sqlreseed as nvarchar(max))

EXEC(@sqlreseed)

但是我在某列上遇到语法错误。

生成的脚本似乎没问题

declare @id int set @id = (select isnull(max(SpecPositionID), 0) + 1  from SpecPosition_TS) DBCC CHECKIDENT ('SpecPosition_TS', RESEED, @id);  set @id = (select isnull(max(AuditId), 0) + 1  from TS_User_Audit) DBCC CHECKIDENT ('TS_User_Audit', RESEED, @id);  

依此类推 table。每个 checkident 工作正常,但如果我 运行 它与我发布的第一个查询我得到

Incorrect syntax near 'BoxId'.

如果我执行 len(@sqlreseed) 我得到 70905.

我有很多table,但显然剧本被删减了。我在某处读到问题是如果我连接字符串我必须将它们全部转换为 nvarchar(max) 因为如果不是它会被削减到 8000 但这就是我所读的。

我做错了什么?

这样试试:

SELECT SqlCommand + CHAR(10)--this concatenation without a column name is the magic to get "xml free" xml :-) Try this without the "+CHAR(10)"
FROM
(
    SELECT 0 AS inx, 'declare @id int;' AS SqlCommand
    UNION 
    SELECT
         ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) --Dummy Order
        ,'set @id = (select isnull(max(' + cast(c.name as nvarchar(max)) +'), 0) + 1  from ' + CAST(t.name as nvarchar(max)) + '); DBCC CHECKIDENT (''' + cast(t.name as nvarchar(max)) +''', RESEED, @id); '
    FROM 
        sys.schemas AS s
    INNER JOIN 
        sys.tables AS t ON s.[schema_id] = t.[schema_id]
    INNER JOIN 
        sys.identity_columns AS c on c.[object_id] = t.[object_id]
) AS tbl
ORDER BY tbl.inx 
FOR XML PATH('')

在 XML 查看器中,您(几乎)是不受限制的。右键单击您的查询并选择选项,勾选网格并将 XML(最后一点)设置为 "unlimited"。

顺便说一句:SELECT @var=@var+... 的字符串连接非常慢。上面显示的方式应该表现得更好......

正如@Blorgbeard 在评论中发布的那样,解决方案是在生成的字符串的列名称中使用 []

可能有一个带有特殊名称或字符的列名。

我还在所有连接中使用强制转换为 nvarchar(max) 以确保限制不限于 8000,正如我所读

V 2.0(完全工作)就是这个。

declare @sqlreseed nvarchar(max)
SELECT @sqlreseed = COALESCE(cast(@sqlreseed as nvarchar(max)) + ' ', '') + 'set @id = (select isnull(max([' + cast(c.name as nvarchar(max)) +']), 0) + 1  from [' + CAST(s.name as nvarchar(max)) + '].[' + CAST(t.name as nvarchar(max)) + ']) DBCC CHECKIDENT (''' + cast(t.name as nvarchar(max)) +''', RESEED, @id); '
FROM sys.schemas AS s
INNER JOIN sys.tables AS t ON s.[schema_id] = t.[schema_id]
INNER JOIN sys.identity_columns AS c on c.[object_id] = t.[object_id]
SET @sqlreseed = cast(cast('declare @id int ' as nvarchar(max)) + @sqlreseed as nvarchar(max))
exec(@sqlreseed)