Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
子查询转换为uniqueidentifier失败,没有Top()-MSSQL_Sql_Sql Server_Types_Casting - Fatal编程技术网

子查询转换为uniqueidentifier失败,没有Top()-MSSQL

子查询转换为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 它本身是有效的 我的第一次

以下查询通过将NVARCHAR(MAX)字段修剪为有效的uniqueidentifier值(如xxxxxxxx-xxxx-xxxx-xxxx-xxxx-XXXXXXXXXXXXXXXX),排除子查询返回的Id(uniqueidentifier类型)行

但是,上面的查询会导致一个错误:

如果我使用CONVERT,同样的问题也会出现

子查询

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)
                 );