在计算 SUM 之前过滤列(错误:将数据类型 varchar 转换为 int 时出错)
Posted
技术标签:
【中文标题】在计算 SUM 之前过滤列(错误:将数据类型 varchar 转换为 int 时出错)【英文标题】:Filter columns before calculating SUM (Error: Error converting data type varchar to int) 【发布时间】:2021-03-31 07:07:05 【问题描述】:我需要计算最小值/最大值/等。我的表中列的值。所以我想过滤来自 INFORMATION_SCHEMA 的列,只得到数字。
以下查询返回错误:将数据类型 varchar 转换为 int 时出错。 我不知道如何解决。
SELECT @vQuery =
'SELECT '''+TABLE_NAME+''' AS TableName
, '''+COLUMN_NAME+''' AS ColumnName
, '''+DATA_TYPE+''' AS DataType
, MIN(TRY_CAST(TRY_CAST(['+COLUMN_NAME+'] AS VARCHAR(MAX)) AS NUMERIC(30,4))) AS MinValue
, MAX(TRY_CAST(TRY_CAST(['+COLUMN_NAME+'] AS VARCHAR(MAX)) AS NUMERIC(30,4))) AS MaxValue
, AVG(TRY_CAST(TRY_CAST(['+COLUMN_NAME+'] AS VARCHAR(MAX)) AS NUMERIC(30,4))) AS AvgValue
, STDEV(TRY_CAST(TRY_CAST(['+COLUMN_NAME+'] AS VARCHAR(MAX)) AS NUMERIC(30,4))) AS StandardDeviation
, SUM(TRY_CAST(TRY_CAST(['+COLUMN_NAME+'] AS VARCHAR(MAX)) AS NUMERIC(30,4))) AS TotalSum
FROM '+QUOTENAME(TABLE_SCHEMA)+'.'+QUOTENAME(TABLE_NAME)+';'+ CHAR(10)
FROM
(SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @Schema
AND TABLE_NAME = @Table
AND DATA_TYPE IN ('BIGINT','NUMERIC','SMALLINT','DECIMAL','SMALLMONEY','INTEGER','INT','TINYINT','MONEY','FLOAT','REAL')) t
【问题讨论】:
这个帖子可能会有所帮助:***.com/questions/18625548/… en.wikipedia.org/wiki/Divide-and-conquer_algorithm 为什么在转换为数字之前先将值转换为字符串?这与错误无关,但似乎相当尴尬。 您编写的查询应该正确构造 SQL:dbfiddle.uk/…。 小心,这仍然很容易注射。您将QUOTENAME
用于FROM
,但不要用于其余的查询。你需要。
【参考方案1】:
评论有点长:
您的查询似乎有效here。
如果您没有使用try_()
函数,那么问题可能会在您运行查询时出现,但在生成它时不会出现。问题是指数符号。例如:
select convert(varchar(255), convert(float, 1234556678990.0))
返回:
'1.23456e+012'
而且这个值不能转换成数值。
我认为在转换为数字之前转换为字符串没有优势,所以我会放弃这些转换。但是,对于 try_cast()
,这应该不是问题。
事实上,您正在为每种类型生成单独的 查询。我认为没有必要进行任何转换。如果需要,查询可以返回不同的类型。如果您使用UNION ALL
连接查询,则需要关注类型。
注意:您还应该在列名上使用QUOTENAME()
。它可以防止 SQL 注入,但是当您从 INFORMATION_SCHEMA
表中进行选择时,这似乎是一个不太可能出现的问题(有人必须创建非常奇怪的表/列名称)。但是,它也可以处理不一致的列名,例如带有空格的列名。
【讨论】:
我首先转换为 VARCHAR,因为在另一种情况下,我在直接转换为 NUMERIC 时遇到问题。如果您尝试运行查询并拥有 datetime 列,它将显示我正在谈论的错误。 这就是为什么我要过滤掉非数字类型的列。 我删除了 try_cast 但仍然得到与我将 varchar/datetime 转换为 int 相同的错误。我只需要对数字列进行计算。 如果@vQuery
、@Schema
或 @Table
声明为整数,则可能会发生这种情况,但这似乎不太可能。
他们是NVARCHAR
类型。以上是关于在计算 SUM 之前过滤列(错误:将数据类型 varchar 转换为 int 时出错)的主要内容,如果未能解决你的问题,请参考以下文章
hive对有null值的列进行avg,sum,count等操作时会不会过滤null值