Bob*_*ant 14 sql-server sql-server-2008
上下文:SQL Server 2008
我有一个表,mytable
其中包含两NVARCHAR
列id
,title
.
id
列中的所有数据实际上都是数字的,除了包含值'test'的一行.
我希望得到10到15之间的所有ID,所以我需要SQL Server将id列值转换为INTEGER
.
我首先使用ISNUMERIC(id) = 1
消除非数字值,但SQL Server对此查询非常奇怪.
SELECT
in.*
FROM
(SELECT
id, title
FROM
mytable
WHERE
ISNUMERIC(id) = 1) in
WHERE
in.id BETWEEN 10 AND 15
Run Code Online (Sandbox Code Playgroud)
此查询导致以下错误:
将nvarchar值'test'转换为数据类型int时转换失败.
内部查询使用'test'id值删除行,因此'in'不应包含它.为什么SQL Server仍在尝试转换它?
我错过了什么吗?我怎么能绕过这个?
PS我试过WHERE CAST(in.id AS INTEGER) BETWEEN 10 AND 15
但也没用.
cyb*_*c87 13
使用TRY_CONVERT函数,它非常方便.
SELECT id,
title
FROM mytable
where TRY_CONVERT(int, id) is not NULL
and TRY_CONVERT(int, id) BETWEEN 10 and 15
Run Code Online (Sandbox Code Playgroud)
如果转换失败,TRY_CONVERT将返回null.
对于您的错误,我认为查询优化器在这里混淆了一些东西.看看执行计划,也许它首先在10到15之间过滤值.我的解决方案永远有效.
正如另一位评论者所说,BETWEEN函数在ISNUMERIC之前完成.这是一个简单的例子:
select * into #temp2
from (
select 'test' a
union
select cast(1 as varchar) a
union
select cast(2 as varchar) a
union
select cast(3 as varchar) a
)z
SELECT a FROM (
SELECT a FROM #temp2 WHERE ISNUMERIC(a) = 1
) b
WHERE b.a BETWEEN 10 AND 15
Run Code Online (Sandbox Code Playgroud)
这个简单的查询是另一种选择:
SELECT a
FROM #temp2
WHERE ISNUMERIC(a) = 1
and a BETWEEN 10 AND 15
Run Code Online (Sandbox Code Playgroud)
我应该再添加一种XML样式:
SELECT *
FROM mytable
WHERE CAST(id as xml).value('. cast as xs:decimal?','int') BETWEEN 10 AND 15
Run Code Online (Sandbox Code Playgroud)
转换id
为XML,转换值xs:decimal
然后转换为integer
.如果没有数值,它将被转换为NULL
.
在这里,您可以阅读有关XML类型转换规则(链接)的信息.
归档时间: |
|
查看次数: |
59289 次 |
最近记录: |