我有一个查询,我正在尝试检查scode
列中的代码范围。问题是该scode
列包含一些 nvarchar 字符,并且在找到它们时会出错。
如何运行以下查询而不返回错误。
SELECT dtExpires, dtFirst
FROM Customers
WHERE (scode BETWEEN 10 AND 100) OR
(scode BETWEEN 500 AND 600)
我收到的错误:
将 nvarchar 值转换为数据类型 int 时转换失败
我有一个查询,我正在尝试检查scode
列中的代码范围。问题是该scode
列包含一些 nvarchar 字符,并且在找到它们时会出错。
如何运行以下查询而不返回错误。
SELECT dtExpires, dtFirst
FROM Customers
WHERE (scode BETWEEN 10 AND 100) OR
(scode BETWEEN 500 AND 600)
我收到的错误:
将 nvarchar 值转换为数据类型 int 时转换失败
如果你不能修复你真正应该做的数据类型......
唯一可靠的短路方法是将过滤后的结果填充到#temp 表中。否则,您无法控制评估顺序。即使您使用子查询或 CTE 来筛选ISNUMERIC() = 1
“first”的行,SQL Server 也可能首先评估BETWEEN
条件,但仍然会失败并出现相同的错误。这可能并不总是发生,但这是保证您避免它的唯一方法:
SELECT dtExpires, dtFirst, scode
INTO #t
FROM dbo.Customers
WHERE scode NOT LIKE '%[^0-9]%'; -- this assumes no decimals allowed
SELECT dtExpires, dtFirst
FROM #t
WHERE (scode BETWEEN 10 AND 100)
OR (scode BETWEEN 500 AND 600);
DROP TABLE #t;
您的最终问题是您将这些数值存储为nvarchar
. 这是有问题的,首先是速度。那里有大量出色的文档和答案表明本网站上的许多情况就是如此。
整数值比字符串小,每页可以容纳比您可以容纳的更多的字符串,nvarchar
并且在整数上更容易完成数学运算。尝试一个小实验,转到SQLFiddle并输入您的表并给它一些值并运行您的查询。然后尝试将该列更改为整数值并运行相同的查询,它不仅会运行得更快,而且您当前的SELECT
语句将正常运行。如果您需要加入此信息和整数,我也会更快。
我不完全确定天气是否有能力这样做,但它肯定会解决你的问题并提高你的数据库性能。
也许使用类似的东西
SELECT dtExpires, dtFirst
FROM Customers
WHERE ( cast(fnRemoveNonNumericCharacters(scode) as int) BETWEEN 10 AND 100) OR
(cast(fnRemoveNonNumericCharacters(scode) as int)BETWEEN 500 AND 600)
函数在哪里:
CREATE Function [fnRemoveNonNumericCharacters](@strText VARCHAR(1000))
RETURNS VARCHAR(1000)
AS
BEGIN
WHILE PATINDEX('%[^0-9]%', @strText) > 0
BEGIN
SET @strText = STUFF(@strText, PATINDEX('%[^0-9]%', @strText), 1, '')
END
RETURN @strText
END
或者,如果您想排除那些 scode 不是数字的条目,还可以创建一个 bool 返回函数,它会告诉您它是否具有非数字字符并将其放在 where 子句中。
解决这个问题的另一种方法可能是:(受到 Aron 的启发
SELECT dtExpires, dtFirst
FROM Customers
WHERE (( case when scode LIKE '%[^0-9]%' then 0 else scode end BETWEEN 10 AND 100) OR
(case when scode LIKE '%[^0-9]%' then 0 else scode end BETWEEN 500 AND 600))
and scode not like '%[^0-9]%'