子查询转换为uniqueidentifier失败,没有Top()-MSSQL
以下查询通过将NVARCHAR(MAX)字段修剪为有效的uniqueidentifier值(如xxxxxxxx-xxxx-xxxx-xxxx-xxxx-XXXXXXXXXXXXXXXX),排除子查询返回的Id(uniqueidentifier类型)行 但是,上面的查询会导致一个错误: 如果我使用CONVERT,同样的问题也会出现 子查询子查询转换为uniqueidentifier失败,没有Top()-MSSQL,sql,sql-server,types,casting,Sql,Sql Server,Types,Casting,以下查询通过将NVARCHAR(MAX)字段修剪为有效的uniqueidentifier值(如xxxxxxxx-xxxx-xxxx-xxxx-xxxx-XXXXXXXXXXXXXXXX),排除子查询返回的Id(uniqueidentifier类型)行 但是,上面的查询会导致一个错误: 如果我使用CONVERT,同样的问题也会出现 子查询 select cast (right(message, 36) as uniqueidentifier) from tableB 它本身是有效的 我的第一次
select cast (right(message, 36) as uniqueidentifier) from tableB
它本身是有效的
我的第一次尝试是通过使用TOP检查是否有一些行无效。
当我在查询中添加一个TOP时,它在任何情况下都可以正常工作:
select * from tableA
where Id not in (select top(n) cast (right(message, 36) as uniqueidentifier) from tableB)
无论我对n取什么值(1、1.000甚至100.000),查询都可以正常工作
我还考虑过使用TOP with ORDER BY。但当使用TOP(100000)返回所有行时,查询将按预期工作
因此,表B中没有被修剪为无效uniqueidentifier值的空条目或无效行。表B中的行总数约为13.000
我发现了一个类似的问题,但与我的问题不太相符
为什么使用top后查询会起作用?我希望您能帮助我了解这种行为。使用
不存在和尝试转换()
因为子查询返回的任何(任意)行只返回可以转换的值。真正的问题是,为什么要将uniqueidentifier
值存储在一个不是uniqueidentifier
的列中TRY\u CONVERT
应该可以解决问题(检查TRY\u CONVERT
在哪里产生NULL
应该可以得到无效行)。一个查询起作用而另一个不起作用的原因很简单,就是优化器生成了不同的计划,其中一个查询通过CONVERT
传递无效数据,而另一个查询则不这样做;这可能会发生,无论您如何制定WHERE
,因为不管逻辑语义如何,优化器都可以自由地进行物理上的重新安排。问题不在顶部。消息
值之一不是有效的GUID<代码>顶部
在转换后应用。顺便说一句,像这样使用nvarchar(max)
是一种气味-nvarchar(max)
不是一个任意长度的字符串
,它是一个4GB长的字符串,存储在表的数据页之外
最好的修复方法是使用一个单独的uniqueidentifier
字段来存储GUID,并在创建行时填充它。接下来,将消息
字段更改为适当的字段。即使您希望消息
包含超过4K的数据,也可以更容易地将任何有用的数据提取到单独的字段中,并避免昂贵的解析和转换fact@PanagiotisKanavos:这是一个常见的误解,但是MAX
类型的值不会存储在表页之外,除非数据实际超过8000字节,或者(非默认)行外的大值类型设置为sp_table选项
。当然,这并不意味着正确的输入是不必要的。
select * from tableA
where Id not in (select top(n) cast (right(message, 36) as uniqueidentifier) from tableB)
select a.*
from tableA a
where not exists (select 1
from tableB b
where a.id = try_cast(right(message, 36) as uniqueidentifier)
);