查看列有 8000 个字符的限制?

Lum*_*mpy 2 sql-server sql-server-2008-r2 view

在 SQL Server 2008 R2 中,我们使用可更新视图来更新varchar(max)列。当我们用文本更新列然后检查字符数时,它显示的长度为 8000 个字符,即使更新包含更多的字符。

视图可以接收更新的字符数是否有某种限制?

好的,我正在与应用程序开发团队合作解决这个问题,他们认为他们找到了解决方法,因此他们放弃了用作测试用例的代码。我会尽力给出大致的想法。更新语句类似于:

UPDATE vorders
set [description] = '<br> This is some text about the order </br>' 
    + CHAR(34) + 'This is more text' + CHAR(34) + 'and on it goes'
where orderid = 12345
Run Code Online (Sandbox Code Playgroud)

然后我们将通过运行以下查询来检查放入该字段的字符的长度

SELECT LEN([description])
  FROM vorders
 WHERE orderid = 12345
Run Code Online (Sandbox Code Playgroud)

应用程序人员发现,如果他们删除 + CHAR(34) + 部分代码,则长度将达到 8700 个字符。使用 + CHAR(34) + 部分代码将文本截断为 8000 个字符。这让我怀疑这是某种隐式转换;但是,我们发现在 + CHAR(34) + 中的一两个就位时不会发生截断。最初的声明大约有 30 个。

知道是什么原因导致了这个问题,我对此一无所知。

Aar*_*and 5

我怀疑您只是没有准确检查列的长度(例如在 Management Studio 中检查PRINTSELECT输出,它被工具截断,没有准确反映数据库中的实际内容)。视图可以公开或更新的字符数没有限制,除非您引入它们,也许您正在使用INSTEAD OF触发器,或者某处正在进行隐式转换,或者您的数据在更新之前被截断。没有更多细节很难说,我希望你能提供。

与此同时,试试这个:

USE tempdb;
GO

CREATE TABLE dbo.foobar(x VARCHAR(MAX));
GO

CREATE VIEW dbo.v_foobar 
WITH SCHEMABINDING
AS
  SELECT x FROM dbo.foobar;
GO

INSERT dbo.v_foobar(x) VALUES('c');
GO

UPDATE dbo.v_foobar 
  SET x = REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 8000)
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 8000);
GO

SELECT LEN(x), DATALENGTH(x)
  FROM dbo.v_foobar;
GO
Run Code Online (Sandbox Code Playgroud)

结果:

-----    -----
16000    16000
Run Code Online (Sandbox Code Playgroud)

我也不相信这CHAR(34)是罪魁祸首。

UPDATE dbo.v_foobar 
  SET x = CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x' 
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 800)
        + CHAR(34) + 'x'
        + REPLICATE(CHAR(34), 400)
        + 'x'
        + REPLICATE(CHAR(34), 400)
        + 'x' 
        + REPLICATE(CHAR(34), 400)
        + 'x' + CHAR(34)
        + REPLICATE(CONVERT(VARCHAR(MAX), 'c'), 8000);

GO
SELECT LEN(x), DATALENGTH(x)
  FROM dbo.v_foobar;
Run Code Online (Sandbox Code Playgroud)

结果:

-----    -----
17226    17226
Run Code Online (Sandbox Code Playgroud)

我怀疑这个字符串在生成时或在命令传递给 SQL Server 之前发生了其他事情。