func runExecScalarTests(t *testing.T, fname string) { username, password, sid := oracle.SplitDSN(*dsn) conn, err := NewConnection(username, password, sid, false, fname, "") if err != nil { t.Fatalf("Connect error: \"%s\"", err.Error()) } defer func() { err = conn.Close() //Важно. Следующие строки должны быть обязательно строго после закрытия соединения с БД <-time.After(time.Second) holder.closeAll() //Важно. Предидущие строки должны быть обязательно строго после закрытия соединения с БД if err != nil { t.Fatalf("Disconnect error: \"%s\"", err.Error()) } }() cur := conn.NewCursor() defer cur.Close() var ( in *oracle.Variable out *oracle.Variable val interface{} outStr string ok bool qry string ) for i, tt := range execScalarTests { if out, err = cur.NewVar(""); err != nil { t.Errorf("cannot create out variable: %s", err) t.FailNow() } qry = `DECLARE TYPE tabTyp IS TABLE OF ` + tt.tabTyp + ` INDEX BY PLS_INTEGER; tab tabTyp := :in; v_idx PLS_INTEGER; v_out VARCHAR2(1000) := '!'; BEGIN v_out := v_out||tab.COUNT||'!'; v_idx := tab.FIRST; IF FALSE and v_idx IS NULL THEN v_out := v_out||'EMPTY'; END IF; WHILE v_idx IS NOT NULL LOOP SELECT v_out||v_idx||'. '||DUMP(tab(v_idx))||CHR(10) INTO v_out FROM DUAL; v_idx := tab.NEXT(v_idx); END LOOP; :out := v_out; END;` in, err = cur.NewVar(tt.in) if err != nil { t.Errorf("%d. error with NewVar: %v", i, err) continue } if err = cur.Execute(qry, nil, map[string]interface{}{"in": in, "out": out}); err != nil { t.Errorf("error executing `%s`: %s", qry, err) continue } if val, err = out.GetValue(0); err != nil { t.Errorf("%d. error getting value: %s", i, err) continue } if outStr, ok = val.(string); !ok { t.Logf("output is not string!?!, but %T (%v)", val, val) } //t.Logf("%d. in:%s => out:%v", i, out, outStr) if outStr != tt.out { t.Errorf("%d. exec(%q) => %q, want %q", i, tt.in, outStr, tt.out) } } }
func TestFloat(t *testing.T) { //os.Setenv("NLS_LANG", "RUSSIAN_RUSSIA.CL8MSWIN1251") username, password, sid := oracle.SplitDSN(*dsn) conn, err := oracle.NewConnection(username, password, sid, false) if err != nil { t.Fatalf("Connect error: \"%s\"", err.Error()) } defer func() { err := conn.Close() if err != nil { t.Errorf("Close error: \"%s\"", err.Error()) } }() cur := conn.NewCursor() defer cur.Close() // { // if oci, client, db, err := conn.NlsSettings(cur); err != nil { // t.Logf("NlsSettings: %s", err) // } else { // t.Logf("NLS oci=%s client=%s database=%s", oci, client, db) // } // } var v *oracle.Variable v, err = cur.NewVariable(0, oracle.FloatVarType, 0) if err != nil { t.Fatalf("Error with NewVariable: %v", err) } var fI float64 fI = float64(-1) / 25 err = v.SetValue(0, fI) if err != nil { t.Fatalf("Error with SetValue: %v", err) } var fR float64 err = v.GetValueInto(&fR, 0) if err != nil { t.Fatalf("Error with GetValueInto: %v", err) } if fR != fI { t.Errorf("Value should be \n\"%v\",\n was \n\"%v\"", fI, fR) } fIntf, err1 := v.GetValue(0) if err1 != nil { t.Fatalf("Error with GetValueInto: %v", err1) } switch x := fIntf.(type) { case float32: fR = fIntf.(float64) case float64: fR = fIntf.(float64) case string: fR, err = strconv.ParseFloat(fIntf.(string), 64) if err != nil { panic(err) } default: panic(x) } if fR != fI { t.Errorf("Value should be \n\"%v\",\n was \n\"%v\"", fI, fR) } }
func (cur *Cursor) Execute(statement string, listArgs []interface{}, keywordArgs map[string]interface{}) error { bg := time.Now() stm := statement params := keywordArgs var ( err error serverBgVar *oracle.Variable serverFnVar *oracle.Variable serverFnScnVar *oracle.Variable serverBg = time.Time{} serverFn = time.Time{} serverFnScn string ) if cur.holder != "" { stm = fmt.Sprintf(stmWithStats, statement) serverBgVar, err = cur.NewVariable(0, oracle.StringVarType, 100) if err != nil { return errgo.Newf("error creating variable for %s: %s", "serverBg", err) } serverFnVar, err = cur.NewVariable(0, oracle.StringVarType, 100) if err != nil { return errgo.Newf("error creating variable for %s: %s", "serverFn", err) } serverFnScnVar, err = cur.NewVariable(0, oracle.StringVarType, 200) if err != nil { return errgo.Newf("error creating variable for %s: %s", "serverFnScn", err) } params["яbg"] = serverBgVar params["яfn"] = serverFnVar params["яfn_scn"] = serverFnScnVar } err = cur.Cursor.Execute(stm, nil, params) if cur.holder != "" { paramVal, err1 := serverBgVar.GetValue(0) if err1 == nil { serverBg, _ = time.Parse("2006-01-02 15:04:05.999999999 -07:00", paramVal.(string)) } paramVal, err1 = serverFnVar.GetValue(0) if err1 == nil { serverFn, _ = time.Parse("2006-01-02 15:04:05.999999999 -07:00", paramVal.(string)) } paramVal, err1 = serverFnScnVar.GetValue(0) if err1 == nil { serverFnScn, _ = paramVal.(string) } delete(params, "яbg") delete(params, "яfn") delete(params, "яfn_scn") } if err != nil { if cur.holder != "" { execCmd(cur.holder, cur.streamID, statement, params, bg, time.Now(), serverBg, serverFn, serverFnScn, false, err.Error()) } return err } if cur.holder != "" { execCmd(cur.holder, cur.streamID, statement, params, bg, time.Now(), serverBg, serverFn, serverFnScn, true, "") } return nil }