Postgres 无法检测到使用 ResultSetMetaData 检查的正确类型的整数字段

问题描述 投票:0回答:2

我根据 PostgresQL 数据库返回的结果集构建了一个 Excel 文档。 我需要能够区分结果集返回的十进制(双精度)和非十进制(整数)数字。

我的 SQL 如下所示:

...
 (select product, reportflag,
                        (select measure_name from report_measures rm where rm.measure_key = typeflag and rm.object_id=(select object_id from reportdet)) as salesLoss,
                        (case when skunumber = 'MULTIPLE' then '-1' else skunumber end)::varchar(12) as skunumber, skuname, null::varchar(12) as substitutesku,
                        null as substituteskuname,
                        null::decimal as substituteTransferSales,
                        case when measure_symbol[3] = '%' then ((measures ->> measure_key[3])::decimal)/100 else (measures ->> measure_key[3])::decimal end as totalSpend, 
                        case when measure_symbol[4] = '%' then ((measures ->> measure_key[4])::decimal)/100 else (measures ->> measure_key[4])::bigint end as totalUnits,  <-- this neeeds to be an integer
                        case when measure_symbol[5] = '%' then ((measures ->> measure_key[5])::decimal)/100 else (measures ->> measure_key[5])::decimal end as totalVisits,
...

我需要

totalUnits
字段是某种整数。但是,它返回为
decimal

我使用以下内容来检测字段的类型:

public void processRow(ResultSet rs) throws SQLException {
    var rsmd = rs.getMetaData();
    ...
}

然后,当我检查

rcmd
时,我可以看到以下类型:

rsmd = {PgResultSetMetaData@21873} 
 connection = {PgConnection@21880} 
 fields = {Field[55]@21881} 
  0 = {Field@21882} "Field(product,TEXT,65535,T)"
  1 = {Field@21883} "Field(reportflag,TEXT,65535,T)"
  2 = {Field@21884} "Field(salesloss,VARCHAR,65535,T)"
  3 = {Field@21885} "Field(skunumber,VARCHAR,65535,T)"
  4 = {Field@21886} "Field(skuname,TEXT,65535,T)"
  5 = {Field@21887} "Field(substitutesku,VARCHAR,65535,T)"
  6 = {Field@21888} "Field(substituteskuname,TEXT,65535,T)"
  7 = {Field@21889} "Field(substitutetransfersales,NUMERIC,65535,T)"
  8 = {Field@21890} "Field(totalspend,NUMERIC,65535,T)"
  9 = {Field@21891} "Field(totalunits,NUMERIC,65535,T)" <-- this should be an integer
  10 = {Field@21892} "Field(totalvisits,NUMERIC,65535,T)"
  ...

正如我们所见,

totalunits
返回为
NUMERIC
,这是一种十进制类型,尽管我将其转换为
bigint

我尝试在 SQL 中将该字段显式转换为

bigint
,如下所示:

    case when measure_symbol[4] = '%' then ((measures ->> measure_key[4])::decimal)/100
 else CAST(measures ->> measure_key[4] AS bigint) end as totalUnits,

,与上面的结果完全相同。

同时,上面提交的

skunumber
被正确转换为varchar。

我做错了什么?

java postgresql jdbc
2个回答
1
投票

我想这个问题在

CASE
声明中。 该语句可能返回不同的数据类型(
decimal & bigint
,并且
decimal
是两者的公共类型),因此不存在类型一致性。

根据您的查询:

case when measure_symbol[4] = '%' 
     then ((measures ->> measure_key[4])::decimal)/100 <-- it returns DECIMAL
     else (measures ->> measure_key[4])::bigint end as totalUnits,  <-- this neeeds to be an INTEGER

作为解决方案,您可以投射整个

CASE
-语句:

CAST(
    case 
        when measure_symbol[4] = '%' then ((measures ->> measure_key[4])::decimal)/100
        else measures ->> measure_key[4]::bigint 
    end
AS bigint) as totalUnits,

0
投票

正如 @Albina 正确指出的那样,

case
语句的两边都应该返回相同的类型。

在挖掘时,我遇到了这个错误:“CASE 类型字符变化和数字无法匹配”,这导致我得到以下答案: 错误:CASE类型字符变化和数字无法匹配

此外,我必须四舍五入为 0,因为结果带有尾随

.0
。所以我最终得到的答案是:

ROUND(case when measure_symbol[4] = '%' then ((measures ->> measure_key[4])::decimal)/100 else (measures ->> measure_key[4])::decimal end, 0)::bigint as totalUnits,
© www.soinside.com 2019 - 2024. All rights reserved.