2016-08-22 11 views
1

私はGolangを新しくしましたが(HANAではなく)、go-hdbをテストしてTCURRテーブル(HANA DB SPS6から)。 UKURS,FFACTTFACTは、すべてこのテーブルに記載されているとおり、HANA DBの10進数です。 しかし、私はこのようなのfloat64するrow.Scanを使用してフェッチしようとした移動から取り出す:golangのgo-hdbドライバを使用してSAP HANA dbから10進数を文字列に変換します

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) 
} 

しかし、悲しいかな、私はエラーにそれを読んで理解しようとするこの

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 

のようなエラーを取得need uint8のデータ型(またはバイト)のように見えますが、私はこれらのuint8/byteを文字列に変換する方法に悩まされています。

10進数のデータを取得する前にこの問題が発生していて、正しく表示されていますか?

+0

それはあなたが行 'に間違った順序で引数を渡しているになります。

コードは次のようなものです.Scan() '、おそらくインデックス '5'(ゼロベース)は' datum'で、 'ukurs'ではありませんか? – icza

+0

申し訳ありませんが、インデックス0は、mandt、kurst、fcurr、tcurr、gdatuです。その後ukursはインデックス5(ゼロベース) –

答えて

0

ドライバパッケージをしばらく見てから、実際に私の質問に答えた機能があることがわかりました。この関数は、関数名がdecodeDecimal()decimal.goにあります。内部のみで使用されているため、ソースコードをコピーして自分のコードに貼り付けます。

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) 

機能

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 
} 

decodeDecimal()の機能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) 
} 
関連する問題