Exemple #1
0
func (stmt *statement) NumInput() int {
	var num C.int
	if r := C.OCIAttrGet(stmt.handle, C.OCI_HTYPE_STMT, unsafe.Pointer(&num), nil, C.OCI_ATTR_BIND_COUNT, (*C.OCIError)(stmt.conn.err)); r != C.OCI_SUCCESS {
		log.Println(ociGetError(stmt.conn.err))
	}
	return int(num)
}
Exemple #2
0
func (r *result) RowsAffected() (int64, error) {
	var t C.ub4
	if C.OCIAttrGet(r.stmt.handle, C.OCI_HTYPE_STMT, unsafe.Pointer(&t), nil, C.OCI_ATTR_ROW_COUNT, (*C.OCIError)(r.stmt.conn.err)) != C.OCI_SUCCESS {
		return 0, ociGetError(r.stmt.conn.err)
	}
	return int64(t), nil
}
Exemple #3
0
// Set the rowcount variable.
func (cur *Cursor) setRowCount() error {
	var rowCount, x C.ub4

	if cur.statementType == C.OCI_STMT_SELECT {
		cur.rowCount = 0
		cur.actualRows = -1
		cur.rowNum = 0
	} else if cur.statementType == C.OCI_STMT_INSERT ||
		cur.statementType == C.OCI_STMT_UPDATE ||
		cur.statementType == C.OCI_STMT_DELETE {
		if CTrace {
			ctrace("OCIAttrGet", cur.handle, "HTYPE_STMT", &rowCount, &x,
				"ATTR_ROW_COUNT", cur.environment.errorHandle)
		}
		if err := cur.environment.CheckStatus(
			C.OCIAttrGet(unsafe.Pointer(cur.handle),
				C.OCI_HTYPE_STMT, unsafe.Pointer(&rowCount), &x,
				C.OCI_ATTR_ROW_COUNT, cur.environment.errorHandle),
			"SetRowCount"); err != nil {
			return err
		}
		cur.rowCount = int(rowCount)
	} else {
		cur.rowCount = -1
	}

	return nil
}
Exemple #4
0
// getStatementType determines if the cursor is executing a select statement.
func (cur *Cursor) getStatementType() error {
	var statementType C.ub2
	var vsize C.ub4
	if CTrace {
		ctrace("getStatementType.OCIAttrGet",
			cur.handle, "HTYPE_STMT", &statementType, &vsize,
			"ATTR_STMT_TYPE", cur.environment.errorHandle)
	}
	if err := cur.environment.CheckStatus(
		C.OCIAttrGet(unsafe.Pointer(cur.handle), C.OCI_HTYPE_STMT,
			unsafe.Pointer(&statementType), &vsize, C.OCI_ATTR_STMT_TYPE,
			cur.environment.errorHandle),
		"getStatementType"); err != nil {
		return err
	}
	cur.statementType = int(statementType)
	if CTrace {
		ctrace("statement type is ", cur.statementType)
	}
	if cur.fetchVariables != nil {
		cur.fetchVariables = nil
	}

	return nil
}
Exemple #5
0
// GetCharacterSetName retrieves the IANA character set name for the attribute.
func (env *Environment) GetCharacterSetName(attribute uint32) (string, error) {
	//, overrideValue string
	var (
		charsetID, vsize C.ub4
		status           C.sword
		err              error
	)

	/*
	   // if override value specified, use it
	   if (overrideValue) {
	       *result = PyMem_Malloc(strlen(overrideValue) + 1);
	       if (!*result)
	           return -1;
	       strcpy(*result, overrideValue);
	       return 0;
	   }
	*/

	// get character set id
	status = C.OCIAttrGet(unsafe.Pointer(env.handle), //void *trgthndlp
		C.OCI_HTYPE_ENV,            //ub4 trghndltyp
		unsafe.Pointer(&charsetID), //void *attributep
		&vsize,           //ub4 *sizep
		C.ub4(attribute), //ub4 attrtype
		env.errorHandle)  //OCIError *errhp
	if err = env.CheckStatus(status, "GetCharacterSetName[get charset id]"); err != nil {
		return "", errgo.Mask(err)
	}

	charsetName := make([]byte, C.OCI_NLS_MAXBUFSZ)
	ianaCharsetName := make([]byte, C.OCI_NLS_MAXBUFSZ)

	// get character set name
	if err = env.CheckStatus(C.OCINlsCharSetIdToName(unsafe.Pointer(env.handle),
		(*C.oratext)(&charsetName[0]),
		C.OCI_NLS_MAXBUFSZ, C.ub2(charsetID)),
		"GetCharacterSetName[get Oracle charset name]"); err != nil {
		return "", errgo.Mask(

			// get IANA character set name
			err)
	}

	status = C.OCINlsNameMap(unsafe.Pointer(env.handle),
		(*C.oratext)(&ianaCharsetName[0]),
		C.OCI_NLS_MAXBUFSZ, (*C.oratext)(&charsetName[0]),
		C.OCI_NLS_CS_ORA_TO_IANA)
	if err = env.CheckStatus(status, "GetCharacterSetName[translate NLS charset]"); err != nil {
		return "", errgo.Mask(

			// store results
			// oratext = unsigned char
			err)
	}

	return string(ianaCharsetName), nil
}
Exemple #6
0
func (conn *OCI8Conn) Begin() (driver.Tx, error) {
	if conn.inTx {
		return nil, errors.New("transaction already in progress")
	}

	var txHandle unsafe.Pointer
	// determine if a transaction handle was previously allocated
	rv := C.OCIAttrGet(
		conn.svc,
		C.OCI_HTYPE_SVCCTX,
		unsafe.Pointer(&txHandle),
		nil,
		C.OCI_ATTR_TRANS,
		(*C.OCIError)(conn.err),
	)
	if err := conn.check(rv, "OCI8Conn.Begin() find existing transaction handle"); err != nil {
		return nil, err
	}
	if txHandle == nil {
		rv := C.OCIHandleAlloc(
			conn.env,
			&txHandle,
			C.OCI_HTYPE_TRANS,
			0,
			nil,
		)
		if err := conn.check(rv, "OCI8Conn.Begin() allocate transaction handle"); err != nil {
			return nil, err
		}
	}
	rv = C.OCIAttrSet(
		conn.svc,
		C.OCI_HTYPE_SVCCTX,
		txHandle,
		0,
		C.OCI_ATTR_TRANS,
		(*C.OCIError)(conn.err),
	)
	if err := conn.check(rv, "OCI8Conn.Begin(): associate transaction"); err != nil {
		return nil, err
	}

	rv = C.OCITransStart(
		(*C.OCISvcCtx)(conn.svc),
		(*C.OCIError)(conn.err),
		60,
		C.OCI_TRANS_NEW,
	)
	if err := conn.check(rv, "OCI8Conn.Begin(): start transaction"); err != nil {
		return nil, err
	}

	conn.inTx = true

	return conn, nil
}
Exemple #7
0
// Get the error offset on the error object, if applicable.
func (cur *Cursor) getErrorOffset() int {
	var offset, x C.ub4
	if CTrace {
		ctrace("OCIAttrGet", cur.handle, "HTYPE_STMT", &offset, &x,
			"ATTR_PARSE_ERROR_OFFSET", cur.environment.errorHandle)
	}
	C.OCIAttrGet(unsafe.Pointer(cur.handle), C.OCI_HTYPE_STMT,
		unsafe.Pointer(&offset), &x,
		C.OCI_ATTR_PARSE_ERROR_OFFSET, cur.environment.errorHandle)
	return int(offset)
}
Exemple #8
0
func (s *OCI8Stmt) NumInput() int {
	var num C.int
	C.OCIAttrGet(
		s.s,
		C.OCI_HTYPE_STMT,
		unsafe.Pointer(&num),
		nil,
		C.OCI_ATTR_BIND_COUNT,
		(*C.OCIError)(s.c.err))
	return int(num)
}
Exemple #9
0
// attr gets an attribute from the statement handle. No locking occurs.
func (stmt *Stmt) attr(attrup unsafe.Pointer, attrSize C.ub4, attrType C.ub4) error {
	r := C.OCIAttrGet(
		unsafe.Pointer(stmt.ocistmt), //const void     *trgthndlp,
		C.OCI_HTYPE_STMT,             //ub4         cfgtrghndltyp,
		attrup,                       //void           *attributep,
		&attrSize,                    //ub4            *sizep,
		attrType,                     //ub4            attrtype,
		stmt.ses.srv.env.ocierr)      //OCIError       *errhp );
	if r == C.OCI_ERROR {
		return stmt.ses.srv.env.ociError()
	}
	return nil
}
Exemple #10
0
// paramAttr gets an attribute from the parameter handle.
func (rset *Rset) paramAttr(ocipar *C.OCIParam, attrup unsafe.Pointer, attrSize C.ub4, attrType C.ub4) error {
	r := C.OCIAttrGet(
		unsafe.Pointer(ocipar),       //const void     *trgthndlp,
		C.OCI_DTYPE_PARAM,            //ub4            trghndltyp,
		attrup,                       //void           *attributep,
		&attrSize,                    //ub4            *sizep,
		attrType,                     //ub4            attrtype,
		rset.stmt.ses.srv.env.ocierr) //OCIError       *errhp );
	if r == C.OCI_ERROR {
		return rset.stmt.ses.srv.env.ociError()
	}
	return nil
}
Exemple #11
0
func (env *Environment) AttrGet(parent unsafe.Pointer, parentType, key int,
	dst unsafe.Pointer, errText string) (int, error) {
	var osize C.ub4
	if CTrace {
		ctrace("OCIAttrGet", parent, C.ub4(parentType), dst, &osize, C.ub4(key), env.errorHandle)
	}
	if err := env.CheckStatus(
		C.OCIAttrGet(parent, C.ub4(parentType), dst, &osize, C.ub4(key),
			env.errorHandle), errText); err != nil {
		// log.Printf("error gettint attr: %s", err)
		return -1, err
	}
	return int(osize), nil
}
Exemple #12
0
func (r *OCI8Result) RowsAffected() (int64, error) {
	var t C.ub4
	rv := C.OCIAttrGet(
		r.s.s,
		C.OCI_HTYPE_STMT,
		unsafe.Pointer(&t),
		nil,
		C.OCI_ATTR_ROW_COUNT,
		(*C.OCIError)(r.s.c.err))
	if rv == C.OCI_ERROR {
		return 0, ociGetError(r.s.c.err)
	}
	return int64(t), nil
}
Exemple #13
0
func (r *OCI8Result) LastInsertId() (int64, error) {
	var t C.ub4
	rv := C.OCIAttrGet(
		r.s.s,
		C.OCI_HTYPE_STMT,
		unsafe.Pointer(&t),
		nil,
		C.OCI_ATTR_ROWID,
		(*C.OCIError)(r.s.c.err))
	if rv == C.OCI_ERROR {
		return 0, ociGetError(r.s.c.err, "OCI8Result.LastInsertId")
	}
	return int64(t), nil
}
Exemple #14
0
//AttrGet gets the parent's attribute identified by key, and stores it in dst
func (env *Environment) AttrGet(parent unsafe.Pointer, parentType, key int,
	dst unsafe.Pointer, errText string) (int, error) {
	var osize C.ub4
	if CTrace {
		ctrace("OCIAttrGet(parent=%p, parentType=%d, dst=%p, osize=%p, key=%d, env=%p)",
			parent, C.ub4(parentType), dst, &osize, C.ub4(key), env.errorHandle)
	}
	if err := env.CheckStatus(
		C.OCIAttrGet(parent, C.ub4(parentType), dst, &osize, C.ub4(key),
			env.errorHandle), errText); err != nil {
		Log.Error("AttrGet", "attr", key, "error", err)
		return -1, err
	}
	return int(osize), nil
}
Exemple #15
0
// Perform the defines for the cursor. At this point it is assumed that the
// statement being executed is in fact a query.
func (cur *Cursor) performDefine() error {
	var numParams uint
	var x C.ub4 = 0

	// determine number of items in select-list
	if CTrace {
		ctrace("OCIAttrGet", cur.handle, "HTYPE_STMT", &numParams, &x,
			"PARAM_COUNT", cur.environment.errorHandle)
	}
	if err := cur.environment.CheckStatus(
		C.OCIAttrGet(unsafe.Pointer(cur.handle),
			C.OCI_HTYPE_STMT,
			unsafe.Pointer(&numParams), &x,
			C.OCI_ATTR_PARAM_COUNT, cur.environment.errorHandle),
		"PerformDefine"); err != nil {
		return err
	}
	// debug("performDefine param count = %d", numParams)

	// create a list corresponding to the number of items
	cur.fetchVariables = make([]*Variable, numParams)

	// define a variable for each select-item
	var v *Variable
	var e error
	cur.fetchArraySize = cur.arraySize
	for pos := uint(1); pos <= numParams; pos++ {
		v, e = cur.varDefine(cur.fetchArraySize, pos)
		// debug("varDefine[%d]: %s nil?%s", pos, e, e == nil)
		if e != nil {
			return fmt.Errorf("error defining variable %d: %s", pos, e)
		}
		if v == nil {
			return fmt.Errorf("empty variable on pos %d!", pos)
		}
		// debug("var %d=%v", pos, v)
		cur.fetchVariables[pos-1] = v
	}
	// debug("len(cur.fetchVariables)=%d", len(cur.fetchVariables))
	return nil
}
Exemple #16
0
func (s *OCI8Stmt) Query(args []driver.Value) (driver.Rows, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}

	var t C.int
	C.OCIAttrGet(
		s.s,
		C.OCI_HTYPE_STMT,
		unsafe.Pointer(&t),
		nil,
		C.OCI_ATTR_STMT_TYPE,
		(*C.OCIError)(s.c.err))
	iter := C.ub4(1)
	if t == C.OCI_STMT_SELECT {
		iter = 0
	}

	rv := C.OCIStmtExecute(
		(*C.OCIServer)(s.c.svc),
		(*C.OCIStmt)(s.s),
		(*C.OCIError)(s.c.err),
		iter,
		0,
		nil,
		nil,
		OCI_MODE)
	if rv == C.OCI_ERROR {
		return nil, ociGetError(s.c.err)
	}

	var rc C.ub2
	C.OCIAttrGet(
		s.s,
		C.OCI_HTYPE_STMT,
		unsafe.Pointer(&rc),
		nil,
		C.OCI_ATTR_PARAM_COUNT,
		(*C.OCIError)(s.c.err))

	oci8cols := make([]oci8col, int(rc))
	for i := 0; i < int(rc); i++ {
		var p unsafe.Pointer
		var np *C.char
		var ns C.ub4
		var tp C.ub2
		var lp C.ub2
		C.OCIParamGet(
			s.s,
			C.OCI_HTYPE_STMT,
			(*C.OCIError)(s.c.err),
			(*unsafe.Pointer)(unsafe.Pointer(&p)),
			C.ub4(i+1))
		C.OCIAttrGet(
			p,
			C.OCI_DTYPE_PARAM,
			unsafe.Pointer(&tp),
			nil,
			C.OCI_ATTR_DATA_TYPE,
			(*C.OCIError)(s.c.err))
		C.OCIAttrGet(
			p,
			C.OCI_DTYPE_PARAM,
			unsafe.Pointer(&np),
			&ns,
			C.OCI_ATTR_NAME,
			(*C.OCIError)(s.c.err))
		C.OCIAttrGet(
			p,
			C.OCI_DTYPE_PARAM,
			unsafe.Pointer(&lp),
			nil,
			C.OCI_ATTR_DATA_SIZE,
			(*C.OCIError)(s.c.err))
		oci8cols[i].name = string((*[1 << 30]byte)(unsafe.Pointer(np))[0:int(ns)])
		oci8cols[i].kind = int(tp)
		oci8cols[i].size = int(lp)
		oci8cols[i].pbuf = make([]byte, int(lp)+1)

		var defp *C.OCIDefine
		rv = C.OCIDefineByPos(
			(*C.OCIStmt)(s.s),
			&defp,
			(*C.OCIError)(s.c.err),
			C.ub4(i+1),
			unsafe.Pointer(&oci8cols[i].pbuf[0]),
			C.sb4(lp+1),
			C.SQLT_CHR,
			nil,
			nil,
			nil,
			OCI_MODE)
		if rv == C.OCI_ERROR {
			return nil, ociGetError(s.c.err)
		}
	}
	return &OCI8Rows{s, oci8cols, false}, nil
}
Exemple #17
0
func (s *OCI8Stmt) Query(args []driver.Value) (rows driver.Rows, err error) {
	var (
		freeBoundParameters func()
	)

	if freeBoundParameters, err = s.bind(args); err != nil {
		return nil, err
	}

	defer freeBoundParameters()

	var t C.int
	C.OCIAttrGet(
		s.s,
		C.OCI_HTYPE_STMT,
		unsafe.Pointer(&t),
		nil,
		C.OCI_ATTR_STMT_TYPE,
		(*C.OCIError)(s.c.err))
	iter := C.ub4(1)
	if t == C.OCI_STMT_SELECT {
		iter = 0
	}

	// set the row prefetch.  Only one extra row per fetch will be returned unless this is set.
	prefetch_size := C.ub4(s.c.attrs.Get("prefetch_rows").(int))
	C.OCIAttrSet(s.s, C.OCI_HTYPE_STMT, unsafe.Pointer(&prefetch_size), 0, C.OCI_ATTR_PREFETCH_ROWS, (*C.OCIError)(s.c.err))

	// if non-zero, oci will fetch rows until the memory limit or row prefetch limit is hit.
	// useful for memory constrained systems
	prefetch_memory := C.ub4(s.c.attrs.Get("prefetch_memory").(int64))
	C.OCIAttrSet(s.s, C.OCI_HTYPE_STMT, unsafe.Pointer(&prefetch_memory), 0, C.OCI_ATTR_PREFETCH_MEMORY, (*C.OCIError)(s.c.err))

	rv := C.OCIStmtExecute(
		(*C.OCISvcCtx)(s.c.svc),
		(*C.OCIStmt)(s.s),
		(*C.OCIError)(s.c.err),
		iter,
		0,
		nil,
		nil,
		C.OCI_DEFAULT)
	if rv == C.OCI_ERROR {
		return nil, ociGetError(s.c.err)
	}

	var rc C.ub2
	C.OCIAttrGet(
		s.s,
		C.OCI_HTYPE_STMT,
		unsafe.Pointer(&rc),
		nil,
		C.OCI_ATTR_PARAM_COUNT,
		(*C.OCIError)(s.c.err))

	oci8cols := make([]oci8col, int(rc))
	for i := 0; i < int(rc); i++ {
		var p unsafe.Pointer
		var np *C.char
		var ns C.ub4
		var tp C.ub2
		var lp C.ub2
		C.OCIParamGet(
			s.s,
			C.OCI_HTYPE_STMT,
			(*C.OCIError)(s.c.err),
			(*unsafe.Pointer)(unsafe.Pointer(&p)),
			C.ub4(i+1))
		C.OCIAttrGet(
			p,
			C.OCI_DTYPE_PARAM,
			unsafe.Pointer(&tp),
			nil,
			C.OCI_ATTR_DATA_TYPE,
			(*C.OCIError)(s.c.err))
		C.OCIAttrGet(
			p,
			C.OCI_DTYPE_PARAM,
			unsafe.Pointer(&np),
			&ns,
			C.OCI_ATTR_NAME,
			(*C.OCIError)(s.c.err))
		C.OCIAttrGet(
			p,
			C.OCI_DTYPE_PARAM,
			unsafe.Pointer(&lp),
			nil,
			C.OCI_ATTR_DATA_SIZE,
			(*C.OCIError)(s.c.err))

		switch tp {
		case C.SQLT_NUM:
			oci8cols[i].kind = C.SQLT_CHR
		default:
			oci8cols[i].kind = tp
		}
		oci8cols[i].name = string((*[1 << 30]byte)(unsafe.Pointer(np))[0:int(ns)])
		oci8cols[i].size = int(lp)

		var defp *C.OCIDefine
		if tp == C.SQLT_CLOB || tp == C.SQLT_BLOB {
			rv = C.OCIDescriptorAlloc(
				s.c.env,
				&oci8cols[i].pbuf,
				C.OCI_DTYPE_LOB,
				0,
				nil)
			if rv == C.OCI_ERROR {
				return nil, ociGetError(s.c.err)
			}
			rv = C.OCIDefineByPos(
				(*C.OCIStmt)(s.s),
				&defp,
				(*C.OCIError)(s.c.err),
				C.ub4(i+1),
				unsafe.Pointer(&oci8cols[i].pbuf),
				-1,
				oci8cols[i].kind,
				unsafe.Pointer(&oci8cols[i].ind),
				&oci8cols[i].rlen,
				nil,
				C.OCI_DEFAULT)
		} else {
			oci8cols[i].pbuf = C.malloc(C.size_t(lp) + 1)
			rv = C.OCIDefineByPos(
				(*C.OCIStmt)(s.s),
				&defp,
				(*C.OCIError)(s.c.err),
				C.ub4(i+1),
				oci8cols[i].pbuf,
				C.sb4(lp+1),
				oci8cols[i].kind,
				unsafe.Pointer(&oci8cols[i].ind),
				&oci8cols[i].rlen,
				nil,
				C.OCI_DEFAULT)
		}

		if rv == C.OCI_ERROR {
			return nil, ociGetError(s.c.err)
		}
	}
	return &OCI8Rows{s, oci8cols, false}, nil
}
Exemple #18
0
// Exec executes a query that may return rows, such as SELECT.
func (stmt *statement) Query(v []driver.Value) (driver.Rows, error) {
	if err := stmt.bind(v); err != nil {
		return nil, err
	}

	// determine the type of statement.  For select statements iter is set to zero, for other statements, only execute once.
	// * NOTE * Should an error be returned if the statement is a non-select type?
	var stmt_type C.int
	if C.OCIAttrGet(stmt.handle, C.OCI_HTYPE_STMT, unsafe.Pointer(&stmt_type), nil, C.OCI_ATTR_STMT_TYPE, (*C.OCIError)(stmt.conn.err)) != C.OCI_SUCCESS {
		log.Println(ociGetError(stmt.conn.err))
	}
	iter := C.ub4(1)
	if stmt_type == C.OCI_STMT_SELECT {
		iter = 0
	}
	// set the row prefetch.  Only one extra row per fetch will be returned unless this is set.
	prefetchSize := C.ub4(100)
	if C.OCIAttrSet(stmt.handle, C.OCI_HTYPE_STMT, unsafe.Pointer(&prefetchSize), 0, C.OCI_ATTR_PREFETCH_ROWS, (*C.OCIError)(stmt.conn.err)) != C.OCI_SUCCESS {
		log.Println(ociGetError(stmt.conn.err))
	}

	// execute the statement
	if C.OCIStmtExecute((*C.OCIServer)(stmt.conn.svr), (*C.OCIStmt)(stmt.handle), (*C.OCIError)(stmt.conn.err), iter, 0, nil, nil, C.OCI_DEFAULT) != C.OCI_SUCCESS {
		err := ociGetError(stmt.conn.err)
		log.Println(err)
		return nil, err
	}

	// find out how many output columns there are
	var cols C.ub2
	if C.OCIAttrGet(stmt.handle, C.OCI_HTYPE_STMT, unsafe.Pointer(&cols), nil, C.OCI_ATTR_PARAM_COUNT, (*C.OCIError)(stmt.conn.err)) != C.OCI_SUCCESS {
		err := ociGetError(stmt.conn.err)
		log.Println(err)
		return nil, err
	}

	// build column meta-data
	columns := make([]column, int(cols))
	for pos := 0; pos < int(cols); pos++ {
		col := &columns[pos]
		var param unsafe.Pointer
		var colType C.ub2
		var colSize C.ub4
		var colName *C.char
		var nameSize C.ub4

		if C.OCIParamGet(stmt.handle, C.OCI_HTYPE_STMT, (*C.OCIError)(stmt.conn.err), (*unsafe.Pointer)(unsafe.Pointer(&param)), C.ub4(pos+1)) != C.OCI_SUCCESS {
			err := ociGetError(stmt.conn.err)
			log.Println(err)
			return nil, err
		}

		C.OCIAttrGet(param, C.OCI_DTYPE_PARAM, unsafe.Pointer(&colType), nil, C.OCI_ATTR_DATA_TYPE, (*C.OCIError)(stmt.conn.err))
		C.OCIAttrGet(param, C.OCI_DTYPE_PARAM, unsafe.Pointer(&colName), &nameSize, C.OCI_ATTR_NAME, (*C.OCIError)(stmt.conn.err))
		C.OCIAttrGet(param, C.OCI_DTYPE_PARAM, unsafe.Pointer(&colSize), nil, C.OCI_ATTR_DATA_SIZE, (*C.OCIError)(stmt.conn.err))

		col.kind = int(colType)
		col.size = int(colSize)
		col.name = C.GoStringN(colName, (C.int)(nameSize))
		col.raw = make([]byte, int(colSize+1))

		var def *C.OCIDefine
		result := C.OCIDefineByPos((*C.OCIStmt)(stmt.handle), &def, (*C.OCIError)(stmt.conn.err),
			C.ub4(pos+1), unsafe.Pointer(&col.raw[0]), C.sb4(colSize+1), C.SQLT_CHR, nil, nil, nil, C.OCI_DEFAULT)
		if result != C.OCI_SUCCESS {
			return nil, ociGetError(stmt.conn.err)
		}
	}

	return &rows{stmt, columns}, nil
}
func (s *StatementOracle) Next() (err int) {

	if !s.fetchDone {
		s.hDefine = new(C.OCIDefine)
		res := C.OCIStmtExecute(s.con.driver.hService, s.hStatement, s.con.driver.hError, 0, 0, nil, nil, C.OCI_DEFAULT)
		if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res {
			fmt.Printf("Resultado OCIStmtExecute=%v\n", res)
			C.AuxOCIErrorGet(s.con.driver.hError)
			return -1
		}
		s.fetchDone = true
		/*
		    var idValue int
		    res = C.OCIDefineByPos( s.hStatement, &s.hDefine, s.con.driver.hError, 1 /*pos* /, unsafe.Pointer(&idValue), C.sb4(unsafe.Sizeof(idValue)), C.SQLT_INT, nil, nil, nil, C.OCI_DEFAULT);
		    if (C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res* /) {
		 		fmt.Printf( "Resultado OCIDefineByPos=%v\n", res)
		     	C.AuxOCIErrorGet( s.con.driver.hError);
		     	return -2
		    }
		    var surnameValue [40]C.char
		    res = C.OCIDefineByPos( s.hStatement, &s.hDefine, s.con.driver.hError, 2 /*pos* /, unsafe.Pointer(&surnameValue[0]), C.sb4(unsafe.Sizeof(surnameValue)), C.SQLT_STR, nil, nil, nil, C.OCI_DEFAULT);
		    if (C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res* /) {
		 		fmt.Printf( "Resultado OCIDefineByPos=%v\n", res)
		     	C.AuxOCIErrorGet( s.con.driver.hError);
		     	return -3
		    }
		*/
		res = C.OCIAttrGet(unsafe.Pointer(s.hStatement), C.OCI_HTYPE_STMT, unsafe.Pointer(&s.numColumns), nil, C.OCI_ATTR_PARAM_COUNT, s.con.driver.hError)
		if C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res*/ {
			fmt.Printf("Resultado OCIAttrGet=%v\n", res)
			C.AuxOCIErrorGet(s.con.driver.hError)
			return -3
		}
		fmt.Printf("numColumns=%v\n", s.numColumns)

		s.columns = make([]*ColumnOracle, 0, 50)
		var hColumn C.ub4
		pColumn := unsafe.Pointer(&hColumn)
		for i := 1; i <= s.numColumns; i++ {
			/* get parameter for column i */
			res = C.OCIParamGet(unsafe.Pointer(s.hStatement), C.OCI_HTYPE_STMT, s.con.driver.hError, &pColumn, C.ub4(i))
			if C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res*/ {
				fmt.Printf("Resultado OCIParamGet=%v\n", res)
				C.AuxOCIErrorGet(s.con.driver.hError)
				return -4
			}

			/* get data-type of column i */
			var columnType C.ub2
			pType := unsafe.Pointer(&columnType)
			res = C.OCIAttrGet(pColumn, C.OCI_DTYPE_PARAM, pType, nil, C.OCI_ATTR_DATA_TYPE, s.con.driver.hError)
			if C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res*/ {
				fmt.Printf("Resultado OCIParamGet=%v\n", res)
				C.AuxOCIErrorGet(s.con.driver.hError)
				return -4
			}

			size := C.ub4(100)
			var column_name_tmp *C.char
			res = C.OCIAttrGet(pColumn, C.OCI_DTYPE_PARAM, unsafe.Pointer(&column_name_tmp), nil, C.OCI_ATTR_NAME, s.con.driver.hError)
			fmt.Printf("coumnName (size=%v) = %v\n", size, column_name_tmp)
			//column_name_tmp[size] = 0
			columnName := C.GoString(column_name_tmp)
			var columnSize int
			res = C.OCIAttrGet(pColumn, C.OCI_DTYPE_PARAM, unsafe.Pointer(&columnSize), nil, C.OCI_ATTR_DATA_SIZE, s.con.driver.hError)

			fmt.Printf("Column:%v Name:%v Size:%v Type:%v\n", i, columnName, columnSize, columnType)

			switch columnType {
			case C.SQLT_CHR:
				var columnValue = make([]C.char, columnSize+1)

				res = C.OCIDefineByPos(s.hStatement, &s.hDefine, s.con.driver.hError, C.ub4(i), /*pos*/
					unsafe.Pointer(&columnValue[0]), C.sb4(columnSize), columnType, nil, nil, nil, C.OCI_DEFAULT)
				if C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res*/ {
					fmt.Printf("Resultado OCIDefineByPos=%v\n", res)
					C.AuxOCIErrorGet(s.con.driver.hError)
					return -2
				}
				s.columns = append(s.columns, NewColumnChrOracle(s, columnName, int(columnSize), columnValue))

			case C.SQLT_NUM:
				var columnValue int

				res = C.OCIDefineByPos(s.hStatement, &s.hDefine, s.con.driver.hError, C.ub4(i), /*pos*/
					unsafe.Pointer(&columnValue), C.sb4(4 /*sizeof(columnValue)*/), columnType, nil, nil, nil, C.OCI_DEFAULT)
				if C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res*/ {
					fmt.Printf("Resultado OCIDefineByPos=%v\n", res)
					C.AuxOCIErrorGet(s.con.driver.hError)
					return -2
				}
				s.columns = append(s.columns, NewColumnNumberOracle(s, columnName, int(columnSize), columnValue))

			//case C.SQLT_LNG:
			//case C.SQLT_RID:
			//case C.SQLT_DAT:
			//case C.SQLT_BIN:
			//case C.SQLT_LBI:
			//case C.SQLT_AFC:
			//case C.SQLT_REF:
			//case C.SQLT_CLOB:
			//case C.SQLT_BLOB:
			//case C.SQLT_BFILEE:
			//case C.SQLT_TIMESTAMP:
			//case C.SQLT_TIME_TZ:
			//case C.SQLT_INTERVAL_YM:
			//case C.SQLT_INTERVAL_DS:
			//case C.SQLT_TIMESTAMP_LTZ:
			//case C.SQLT_RDD:
			default:
				s.columns = append(s.columns, NewColumnUnknownOracle(s, columnName, int(columnSize), int(columnType)))
			}
			fmt.Printf("Next len(stmt.columns)=%v\n", len(s.columns))
		}
		//return 0
	}

	res := C.OCIStmtFetch2(s.hStatement, s.con.driver.hError, 1 /*nrows*/, C.OCI_FETCH_NEXT, 0, C.OCI_DEFAULT)
	if C.OCI_SUCCESS != res && C.OCI_NO_DATA != res {
		fmt.Printf("Resultado OCIStmtFetch2=%v\n", res)
		C.AuxOCIErrorGet(s.con.driver.hError)
		return -4
	} else if C.OCI_NO_DATA == res {
		//fmt.Printf( "The result is:%v-%v\n", idValue, C.GoString(&surnameValue[0]))
		return 0
	}
	return 1
}