【发布时间】:2012-05-04 23:07:20
【问题描述】:
- 列表中似乎出现了一些 NULL 值。
- 某些 NULL 值正在被查询过滤掉。我已经检查过了。
- 如果我添加
AND AdditionalFields = '',仍然返回这两个结果 - AdditionalFields 是一个 varchar(max)
- 数据库是 SQL Server 10,兼容级别 = Sql Server 2005 (90)
- 我正在使用 Management Studio 2008
我似乎有长度为 NULL 的空字符串,或等于空字符串的 NULL 值。这是一种新的数据类型吗?!
编辑: 新数据类型 - 在此称为“Numpty”
编辑 2 将数据插入临时表会将 Numpties 变为 NULLS。 (这条sql的结果是10)
CREATE TABLE #temp(ID uniqueidentifier , Value varchar(max))
INSERT INTO #temp
SELECT top 10 g.ID, g.AdditionalFields
FROM grants g
WHERE g.AdditionalFields IS NOT NULL AND LEN(g.AdditionalFields) IS NULL
SELECT COUNT(*) FROM #temp WHERE Value is null
DROP TABLE #temp
编辑 3 我可以通过运行更新来修复数据:
UPDATE Grants SET AdditionalFields = NULL
WHERE AdditionalFields IS NOT NULL AND LEN(AdditionalFields) IS NULL
所以这让我认为字段必须包含一些东西,而不是架构定义的一些问题。但它是什么?以及如何阻止它再次出现?
编辑 4 我的数据库中还有 2 个其他字段,两个 varchar(max) 在字段不为空且 LEN(field) 为空时返回行。所有这些字段都曾经是 TEXT 并更改为 VARCHAR(MAX)。数据库也从 Sql Server 2005 移动到 2008。看起来我们默认关闭了 ANSI_PADDING 等。
另一个例子:
转换为 varbinary
执行计划: 编辑 5: 删除了表定义 - 最终证明是不相关的
编辑 6 生成脚本以将 TEXT 更改为 VARCHAR(MAX) 然后更新值以防止错误并提高性能
--Generate scripts to alter TEXT to VARCHAR(MAX)
SELECT 'ALTER TABLE [' + tab.table_schema + '].[' + tab.table_name + '] ALTER COLUMN [' + col.column_name + '] VARCHAR(MAX)' + CASE WHEN col.IS_NULLABLE = 'YES' THEN ' NULL' ELSE ' NOT NULL' END + ' GO'
FROM INFORMATION_SCHEMA.tables tab
INNER JOIN INFORMATION_SCHEMA.COLUMNS col ON col.table_name = tab.table_name
AND tab.table_schema = col.table_schema
AND tab.table_catalog = col.table_catalog
WHERE tab.table_type <> 'VIEW' and col.DATA_TYPE = 'text'
--Generate scripts to set value to value in VARCHAR(MAX) fields
SELECT 'UPDATE [' + tab.table_schema + '].[' + tab.table_name + '] SET [' + col.column_name + '] = [' + col.column_name + ']'
FROM INFORMATION_SCHEMA.tables tab
INNER JOIN INFORMATION_SCHEMA.COLUMNS col ON col.table_name = tab.table_name
AND tab.table_schema = col.table_schema
AND tab.table_catalog = col.table_catalog
WHERE tab.table_type <> 'VIEW' AND col.DATA_TYPE = 'varchar' and col.CHARACTER_MAXIMUM_LENGTH = -1
【问题讨论】:
-
您的查询是逐字发布的吗?您是否有可能在
WHERE子句中拼错了AdditionalFields,但在SELECT列表中却没有(这会导致在另一个字段上进行过滤)?像WHERE 'g.AdditionalFields' IS NOT NULL这样的东西会产生类似的行为(因为你过滤的不是字段而是字符串常量)。 -
第一个结果并不令人惊讶。空字符串和
NULL是两个独立的概念(除非你很奇怪,比如 Oracle) -
作为调试提示:只需输出 PK,以便您看到生成结果的行。
-
当我们这样做时,您可以发布整个 ssms 窗口的屏幕截图,以便我们更轻松地验证您的声明。
-
I've created a connect item for this。我还没有测试过这个问题是否发生在 SQL Server 2012 中。
标签: sql-server sql-server-2005