SQL Server LEN / DATALENGTH始终为文本列返回8000

时间:2014-12-30 19:01:59

标签: sql-server sql-server-2008

我目前在2008R2工作,但我相信,我有一个在SQL Server 2000中创建的审计表tAudit。其中,tAudit有一个名为Change的文本列。 tAudit中有超过20万行。

我需要找到Change列中包含的文本的最大长度,但LEN和DATALENGTH都会为每行报告8000个字符。视觉检查样本表明最大长度更可能在200到300个字符范围内。

我尝试过的事情:

- 所有236645行都是8000.这里发生了什么?

SELECT max(DATALENGTH(CAST(change AS VARCHAR(MAX)))), COUNT(*) AS MaxLenCount FROM dbo.tAudit
SELECT max(DATALENGTH(change)), COUNT(*) AS MaxLenCount FROM dbo.tAudit
SELECT max(LEN(LTRIM(RTRIM(CAST(change AS VARCHAR(MAX)))))), COUNT(*) AS MaxLenCount 
FROM dbo.tAudit

CREATE TABLE #tAuditTemp 
(
     TaskID INT
   , AuditDate DATETIME
   , CHANGE varchar(8000) 
)
INSERT INTO #tAuditTemp
   SELECT 
        JobID
      , AuditDate
      , Change
   FROM dbo.tAudit 
   ORDER BY 
        AuditDate
      , JobID
      , cast(Change AS VARCHAR(max))

SELECT max(LEN(change)) AS MaxLen FROM #tAuditTemp  -- All are 8000 again; so much for the VAR part of VARCHAR in this case.

为临时表中的更改指定小于8000的任何内容会导致运行时发生截断错误。

我也尝试使用CHARINDEX来定位字符串的结尾,但是更改值在CHARINDEX给我带来的字符串的最后几个字符中没有足够的通用性。

该表是使用ANSI_PADDING ON创建的。从SSMS行编辑器捕获一些更改数据表明尚未存储尾随空白。

问题:
1.知道为什么每行报告8000的长度?
2.知道如何提取变更数据的实际长度吗?

3 个答案:

答案 0 :(得分:1)

char类型总是用空格填充它的长度(在你的情况下为8000),你需要使用varchar来防止填充,你也可以尝试TRIM来获取实际文本

此处来自http://msdn.microsoft.com/en-us/library/ms176089.aspx

  

char [(n)]

Fixed-length, non-Unicode string data. n defines the string length and must be a value from 1 through 8,000

或者你可以关闭填充

  

如果CREATE TABLE或ALTER TABLE为SET,则ANSI ANSI_ADDING为OFF   执行后,定义为NULL的char列将作为varchar处理。

<强>更新

我想你至少有一行实际长度为8000,这就是为什么max返回它,如果你想计算不同长度的行数,你可以使用:

SELECT LEN(change) as ChangeLength, COUNT(*) as LengthCount
FROM dbo.tAudit
GROUP BY LEN(change)
ORDER BY 1

答案 1 :(得分:0)

问题:
1.知道为什么每行报告8000的长度?
2.知道如何提取变更数据的实际长度吗?
答案:
因为我对处理TEXT领域的困难非常困惑,所以我没有注意到这个事实 MAX在本页顶部的三个原始查询中从复制/粘贴中遗留下来。 Lashane的 "SELECT LEN(change) as ChangeLength, COUNT( * ) as LengthCount..."
我指出了我(明显的)问题。

2.调整上面引用的查询以使用临时表而不是tAudit允许我获得所需的 结果。但是,如果没有虚假的MAX,我也可以直接从tAudit获得所需的结果

SELECT LEN(CAST(change AS VARCHAR(MAX))) as ChangeLength, COUNT(*) as LengthCount FROM dbo.tAudit GROUP BY LEN(CAST(change AS VARCHAR(MAX))) ORDER BY 1 desc

感谢所有贡献的人!

答案 2 :(得分:-1)

这里没有涉及CHAR列。问题是TEXT列总是显示8000的长度,与字符串的实际长度无关,并且没有存储填充空格。 ANSI_PADDING ON 允许存储尾随空格,但同样,这里并非如此,因为我检查过的行中没有一行甚至有一个尾随空格。