假设我们尝试更改 SQL 表中列的类型,例如从
varchar
更改为 float
,使用: ALTER TABLE <mytable> ALTER COLUMN <mycolumn> FLOAT
。但是,我们收到错误Error to convert datatype varchar to float
。
是否可以缩小列中导致此问题的单元格的范围?
您可以使用
ISNUMERIC
功能:
select * from table where isnumeric(mycolumn) = 0
如果您的列中允许 NULL 值,您还需要添加对 NULL 的检查,因为
ISNUMERIC(NULL)
的计算结果也为 0
select * from table where isnumeric(mycolumn) = 0 or mycolumn is not null
选择
varchar
值包含非数字字符的任何记录
SELECT col
FROM tab
WHERE col LIKE '%[^0-9.]%'
以及任何可能有多个句点的行:
SELECT col
FROM tab
WHERE col LIKE '%.%.%'
我在编写ETL过程时遇到了同样的问题。将暂存数据移动到实际的核心表中,并且我们将暂存表上的所有列都设置为 NVARCHAR。 可能有一个数值,该数值要么是科学格式(如 Excel 单元格中非常大的浮点值),要么包含这种特殊的 CHAR 之一。当该字符显示为整数值时,ISNUMERIC 函数将该字符计算为 True。 例如
SELECT ISUMERIC('$'), ISNUMERIC('.')
所以只需检查该列中的任何单元格是否具有此类值。
'$'
'-'
'+'
','
'.'
如果您发现该单元格具有上述之一,则只需在查询中排除此类数据即可。 如果您发现您有科学格式的数据,例如“1.2408E+12”,那么 ISNUMERIC 仍会将其评估为 TRUE,但直接插入将失败,因此请转换为适当的数字格式。
DECLARE @t NUMERIC(28,10)
SELECT @t=CONVERT(NUMERIC(28,10),CONVERT(FLOAT,'1.2408E+12'))
SELECT @t
肮脏,但有效。这会删除浮点数中找到的所有字符(#s 和小数 - 我以美国为中心)。您从查询中获得的结果是需要进行审查以确定应该做什么的项目(即导致您出现问题的单元格)。
SELECT
*
FROM (
SELECT
TableId
, REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
ISNULL(Col1,'')
,'0','')
,'1','')
,'2','')
,'3','')
,'4','')
,'5','')
,'6','')
,'7','')
,'8','')
,'9','')
,'.','') [FilteredCol1]
FROM Table
) a
WHERE len(a.[FilteredCol1])>0