在计算 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值

R:平均列的语法问题

如何在 hive 中将列的空白值替换为 [null] 以计算 SUM

对字符串类型的数据表列求和

Sum 十进制数据类型 SwiftUI CoreData