sijms / go-ora

Pure go oracle client
MIT License
767 stars 168 forks source link

unregister custom type: ANYDATA. call RegisterType first #542

Closed freeman983 closed 2 months ago

freeman983 commented 2 months ago
package main

import (
    "context"
    "database/sql"
    "errors"
    "fmt"
    go_ora "github.com/sijms/go-ora/v2"
    "time"
)

func main() {
    db, err := connectORACLE("192.168.1.155", "ORCLCDB", "SYSTEM", "oracle", 11521)
    if err != nil {
        panic(err)
    }

    defer db.Close()

    ctx := context.Background()

    /**
    begin
      sys.dbms_scheduler.create_program(program_name        => 'SYSTEM.PROGRAM1',
                                        program_type        => 'EXECUTABLE',
                                        program_action      => 'select 1 from dual',
                                        number_of_arguments => 2,
                                        enabled             => false,
                                        comments            => '');
      sys.dbms_scheduler.define_program_argument(program_name        => 'SYSTEM.PROGRAM1',
                                                 argument_position   => 1,
                                                 argument_name       => 'ID',
                                                 argument_type       => 'NUMBER',
                                                 default_value       => '');
      sys.dbms_scheduler.define_program_argument(program_name        => 'SYSTEM.PROGRAM1',
                                                 argument_position   => 2,
                                                 argument_name       => 'NAME',
                                                 argument_type       => 'VARCHAR2',
                                                 default_value       => '');
      sys.dbms_scheduler.enable(name => 'SYSTEM.PROGRAM1');
    end;
    /

    */
    sql := `select * from all_scheduler_program_args WHERE owner='SYSTEM'  and  program_name='PROGRAM1' ORDER BY argument_position`

    rows, err := db.QueryContext(ctx, sql)
    if err != nil {
        fmt.Println("err2:", err.Error())
        return
    }
    defer rows.Close()

    for rows.Next() {
        var text string
        err = rows.Scan(&text)
        if err != nil {
            panic(err.Error())
        }
        fmt.Printf("text: %s\n", text)
    }

}

func connectORACLE(host, serviceName, user, password string, port int) (*sql.DB, error) {

    url := `(DESCRIPTION=(connect_timeout=15)(ADDRESS=(PROTOCOL=TCP)(HOST=%s)(PORT=%d))(CONNECT_DATA=(SERVICE_NAME=%s)))`

    //if dbI.ServiceType == "sid" {
    //  url = `(DESCRIPTION=(connect_timeout=15)(ADDRESS=(PROTOCOL=TCP)(HOST=%s)(PORT=%d))(CONNECT_DATA=(SID=%s)))`
    //}

    urlOptions := map[string]string{}

    dsn := fmt.Sprintf(url, host, port, serviceName)

    fmt.Println("dsn:", dsn)

    connStr := go_ora.BuildJDBC(user, password, dsn, urlOptions)

    fmt.Println("connStr:", connStr)
    db, err := sql.Open("oracle", connStr)

    if err != nil {
        fmt.Println("err:", err)
        return nil, err
    }

    ctx, cancel := context.WithTimeout(context.TODO(), 61*time.Second)
    defer cancel()
    if db == nil {
        err := errors.New("初始化连接池失败")
        return nil, err
    }

    err = db.PingContext(ctx)

    return db, nil
}

get error:

err2: unregister custom type: ANYDATA. call RegisterType first

sijms commented 2 months ago

this is correct because driver deal with basic database types. driver don't know how to store value returned as ANYDATA

nangcr commented 2 months ago

@sijms Based on the behavior of client tools such as Oracle SQL Developer, Navicat, DataGrip, etc., please consider whether it is possible to replace the error with displaying a nil value.

sijms commented 2 months ago

you should convert anydata to its representative type in the sql. otherwise don't mention it in query string