doulidai6316 2016-08-22 09:37
浏览 224
已采纳

使用Golang中的go-hdb驱动程序将十进制转换为从SAP HANA数据库检索的字符串

I am new to Golang (but not on HANA), and I am trying to test out the go-hdb to pull out data from TCURR table (from HANA DB SPS6). From what I understand is in that table, UKURS, FFACT, and TFACT are all Decimals in HANA DB. However when retrieving from Go, which I tried fetch using row.Scan to Float64 like this:

var mandt, kurst, fcurr, tcurr, gdatu, datum string
var ukurs float64
var ffact, tfact float64

if err := rows.Scan(&mandt, &kurst, &fcurr, &tcurr, &gdatu, &ukurs, &ffact, &tfact, &datum); err != nil {
   log.Fatal(err)
}

But alas, getting error like this

2016/08/18 10:18:31 sql: Scan error on column index 5: converting driver.Value type []uint8 ("@\xe2\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0060") to a float64: invalid syntax

I try to read and understand the error it looks like needs uint8 data type (or byte), however, I am stuck with how to convert those uint8/byte into string.

Is there anyone have this problem before and how to getting decimal data and displayed it properly (ie print them into console)?

  • 写回答

1条回答 默认 最新

  • duanpiangeng8958 2016-09-09 09:31
    关注

    After to look and understand the driver package a while, I found out there is a function that actually answered my question. The function is reside within decimal.go with function name decodeDecimal(). Due to it is used by internal only, I copy the source code and paste to my code.

    The code is something like this:

    var mandt, kurst, fcurr, tcurr, gdatu, datum string
    var ukurs, ffact, tfact []byte
    if err := rows.Scan(&mandt, &kurst, &fcurr, &tcurr, &gdatu, &ukurs, &ffact, &tfact, &datum); err != nil {
       WriteMsg("SCAN")
       log.Fatal(err)
    }
    
    var bi big.Int
    var z float64
    var neg bool
    var i int
    
    var record []string
    
    record = append(record, mandt)
    record = append(record, kurst)
    record = append(record, fcurr)
    record = append(record, tcurr)
    record = append(record, gdatu)
    
    // ukurs
    neg, i = decodeDecimal(ukurs, &bi)
    z = BigIntToFloat(neg, &bi, i)
    record = append(record, fmt.Sprintf("%.4f", z))
    
    // ffact
    neg, i = decodeDecimal(ffact, &bi)
    z = BigIntToFloat(neg, &bi, i)
    record = append(record, fmt.Sprintf("%.4f", z))
    
    // tfact
    neg, i = decodeDecimal(tfact, &bi)
    z = BigIntToFloat(neg, &bi, i)
    record = append(record, fmt.Sprintf("%.4f", z))
    
    record = append(record, datum)
    

    Function of decodeDecimal()

    func decodeDecimal(b []byte, m *big.Int) (bool, int) {
    
        //bigint word size (*--> src/pkg/math/big/arith.go)
            const (
            dec128Bias = 6176
            // Compute the size _S of a Word in bytes.
            _m    = ^big.Word(0)
            _logS = _m>>8&1 + _m>>16&1 + _m>>32&1
            _S    = 1 << _logS
        )
    
        neg := (b[15] & 0x80) != 0
        exp := int((((uint16(b[15])<<8)|uint16(b[14]))<<1)>>2) - dec128Bias
    
        b14 := b[14]  // save b[14]
        b[14] &= 0x01 // keep the mantissa bit (rest: sign and exp)
    
        //most significand byte
        msb := 14
        for msb > 0 {
            if b[msb] != 0 {
                break
            }
            msb--
        }
    
        //calc number of words
        numWords := (msb / _S) + 1
        w := make([]big.Word, numWords)
    
        k := numWords - 1
        d := big.Word(0)
        for i := msb; i >= 0; i-- {
            d |= big.Word(b[i])
            if k*_S == i {
                w[k] = d
                k--
                d = 0
            }
            d <<= 8
        }
        b[14] = b14 // restore b[14]
        m.SetBits(w)
        return neg, exp
    }
    

    Function BigIntToFloat()

    func BigIntToFloat(sign bool, m *big.Int, exp int) float64 {
        var neg int64
        if sign {
            neg = -1
        } else {
            neg = 1
        }
    
        return float64(neg*m.Int64()) * math.Pow10(exp)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 服务端可运行语言,解析unity文件
  • ¥15 英飞凌TC387使用MCAL唤醒TJA1145问题
  • ¥15 android tv图标显示异常
  • ¥20 (标签-AR|关键词-预测分析)
  • ¥15 QT IFW 自定义界面添加lineedit小键盘输入数字无效果
  • ¥15 python thinter动态建立Entry并读取数据
  • ¥150 电路仿真,演示反激变压器升压
  • ¥100 libcurl使用无法连接服务器问题
  • ¥30 链表栈表达式求值求解
  • ¥15 关于龙芯1b,JTAG停止调试服务