Sql 转换数据类型varchar时出错
我目前有一个列为Sql 转换数据类型varchar时出错,sql,sql-server,tsql,Sql,Sql Server,Tsql,我目前有一个列为varchar的表。此列可以容纳数字或文本。在某些查询过程中,我将其视为bigint列(我将其与另一个表中的bigint列进行联接) 只要该字段中只有数字,就没有问题,但在该字段中即使有一行有文本而没有数字的那一分钟,我得到了一个“将数据类型varchar转换为bigint”的错误,即使在WHERE部分,我确保没有出现任何文本字段 为了解决这个问题,我创建了一个视图,如下所示: SELECT TOP (100) PERCENT ID, CAST(MyCol AS bigi
varchar
的表。此列可以容纳数字或文本。在某些查询过程中,我将其视为bigint
列(我将其与另一个表中的bigint
列进行联接)
只要该字段中只有数字,就没有问题,但在该字段中即使有一行有文本而没有数字的那一分钟,我得到了一个“将数据类型varchar
转换为bigint
”的错误,即使在WHERE部分,我确保没有出现任何文本字段
为了解决这个问题,我创建了一个视图,如下所示:
SELECT TOP (100) PERCENT ID, CAST(MyCol AS bigint) AS MyCol
FROM MyTable
WHERE (isnumeric(MyCol) = 1)
但是,即使视图仅显示具有数值的行,并将mycl强制转换为bigint,但在运行以下查询时,将数据类型varchar转换为bigint仍然会出错:
SELECT * FROM MyView where mycol=1
当对视图执行查询时,它不应该知道其背后发生了什么!它应该只看到两个bigint字段!(,甚至mssql management studio也将视图字段显示为bigint)是否尝试将其他表的bigint字段转换为varchar?对我来说,执行更健壮的转换是有意义的。。。如果对varchar字段进行索引,则不会对性能造成太大影响。考虑创建一个冗余的bigint字段来保存af MyCol的整数值
然后,您可以为新字段编制索引以加快加入速度。尝试分两个阶段进行选择 首先创建一个视图,选择我的列为nummeric的所有列 然后在该视图中进行选择,在该视图中强制转换varchar字段 另一件事,你可以看看你的表设计,以消除对演员的需要 编辑
- 有些数字比bigint大吗
- 数字中是否有空格、前导空格、尾随空格或空格
- 有格式字符吗?小数点
CREATE FUNCTION [dbo].[fnBigIntRecordsOnly]()
RETURNS @Results TABLE (BigIntCol BIGINT)
AS
BEGIN
INSERT @Results
SELECT CAST(MyCol AS BIGINT)
FROM MyTable
WHERE MyCol NOT LIKE '%[^0-9]%'
RETURN
END
SELECT * FROM [dbo].[fnBigIntRecordsOnly]() WHERE BigIntCol = 1
我并不认为这是一个从性能角度考虑的好主意,但它是一个解决方案尝试使用以下方法:
SELECT
ID,
CAST(MyCol AS bigint) as MyCol
FROM
(
SELECT TOP (100) PERCENT
ID,
MyCol
FROM
MyTable
WHERE
(isnumeric(MyCol) = 1)
) as tmp
这应该是可行的,因为内部选择只返回数值,而外部选择可以将第一次选择的所有值转换为数值。在您自己的代码中,SQL似乎在执行isnumeric函数之前尝试强制转换(可能与优化有关)。回答您关于错误消息的问题:当您在另一个查询中引用视图名称时(假设它是传统视图而不是实体化视图),SQL Server有效地将视图定义的宏替换到消费查询中,然后执行该宏 这样做的好处是,如果查询优化程序能够看到整个查询,而不是将视图作为“黑匣子”单独优化,那么它可以做得更好 结果是,如果发生错误,错误描述可能看起来很混乱,因为执行引擎正在访问数据的基础表,而不是视图 我不确定具体化视图是如何处理的,但我可以想象它们被视为表,因为视图数据缓存在数据库中
话虽如此,我同意前面的回答-您应该重新考虑您的表设计,并将文本和整数数据值分隔为单独的列。尝试将您的视图更改为:
SELECT TOP 100 PERCENT ID,
Cast(Case When IsNumeric(MyCol) = 1 Then MyCol Else null End AS bigint) AS MyCol
FROM MyTable
WHERE (IsNumeric(MyCol) = 1)
嗯。我最终创建了一个有效的视图:
SELECT TOP (100) PERCENT id, CAST(CASE WHEN IsNumeric(MyCol) = 1 THEN MyCol ELSE NULL END AS bigint) AS MyCol
FROM dbo.MyTable
WHERE (MyCol NOT LIKE '%[^0-9]%')
多亏了AdaTheDev和CodeByMoonlight。我用了你的两个答案。(当然也要感谢其他回复者)
现在,当我与其他bigint col进行连接或执行类似于“SELECT*FROM MyView where mycl=1”的操作时,它将返回正确的结果,而不会出现错误。我的猜测是,查询中的强制转换本身会导致查询优化器不查看原始表,正如Christian Hayter所说,其他视图可能会出现这种情况,这可能是一种解决方案,但真正让我感兴趣的是,即使只有bigint fieldsTried,视图也会出现错误。即使在查询第二个视图时,我仍然会遇到相同的错误。这意味着每次都要更改项目的大部分以选择正确的字段……您的查询实际上只返回带数字的行。但是,当将其转换为视图并查询视图时,我得到了相同的“将数据类型varchar转换为bigint时出错”(仅当执行“where mycl=1”时,我得到了错误),我个人认为您解决了错误的问题。如果您将一列用于两个不同的目的,则架构/数据库设计有问题。是的,我知道,但整个系统太长,无法进行重大更改。下面的链接提供了一些详细信息:抱歉,此查询返回了相同的“将数据类型varchar转换为bigint时出错”错误您使用的SQL Server版本是什么?我在SQL2000和更高版本中尝试过这个,没有任何问题。很高兴你找到了解决办法:)如果你仍然认为这个答案是最正确的,那么你应该接受它作为答案。这将从尚未解决的问题列表中删除您的问题。
SELECT TOP (100) PERCENT id, CAST(CASE WHEN IsNumeric(MyCol) = 1 THEN MyCol ELSE NULL END AS bigint) AS MyCol
FROM dbo.MyTable
WHERE (MyCol NOT LIKE '%[^0-9]%')