Skip to content

Garbled text when connecting to two Oracle databases with different NLS_CHARACTERSET in the same process (v2.9.0) #692

@lwqmyself

Description

@lwqmyself

When connecting to two Oracle databases that use different NLS_CHARACTERSET values in the same process, the query result from the second connection becomes garbled.
It seems that the character set information is determined from the first connection and reused for subsequent connections, regardless of the target database’s encoding.

Environment

  • go-ora version: v2.9.0

Oracle DB NLS Settings

  • DB1 (10.0.0.1:1521): AL32UTF8
  • DB2 (10.0.0.1:1522): ZHS16GBK

Steps to Reproduce

  1. On both databases (UTF-8 and GBK), create the same test table and insert the same data:

    CREATE TABLE TEST (
        COLUMN1 VARCHAR2(50)
    );
    
    INSERT INTO TEST VALUES ('测试');
    
    COMMIT;
  2. Run the following Go code in the same process:

    package main
    
    import (
        "database/sql"
        "fmt"
        "log"
        "testing"
    
        go_ora "github.com/sijms/go-ora/v2"
        _ "github.com/sijms/go-ora/v2"
    )
    
    func getOracleDb(ip string, port int, instName, userName, DbPassword string) (*sql.DB, error) {
        dsn := go_ora.BuildUrl(ip, port, instName, userName, DbPassword, nil)
        d, err := sql.Open("oracle", dsn)
        if err != nil {
            return nil, fmt.Errorf("connect [%s] err=[%w]", dsn, err)
        }
        return d, nil
    }
    
    func TestOracle(t *testing.T) {
        // Connect to UTF-8 DB (AL32UTF8)
        oraDb, err := getOracleDb("10.0.0.1", 1521, "XE", "user1", "pass1")
        if err != nil {
            log.Println(err)
            return
        }
        defer oraDb.Close()
    
        var colVal sql.NullString
        err = oraDb.QueryRow(`select COLUMN1 from TEST`).Scan(&colVal)
        if err != nil {
            log.Println(err)
            return
        }
        log.Println("UTF8 DB result:", colVal)
    
        // Connect to GBK DB (ZHS16GBK)
        oraDbGbk, err := getOracleDb("10.0.0.1", 1522, "XE", "user2", "pass2")
        if err != nil {
            log.Println(err)
            return
        }
        defer oraDbGbk.Close()
    
        var colValGbk sql.NullString
        err = oraDbGbk.QueryRow(`select COLUMN1 from TEST`).Scan(&colValGbk)
        if err != nil {
            log.Println(err)
            return
        }
        log.Println("GBK DB result:", colValGbk)
    }

Expected behavior

Both queries should return the correct string according to the database’s NLS_CHARACTERSET.

Actual behavior

The second query's result is garbled.
If the connection order is reversed (connect to GBK first, then UTF-8), the second connection's result is still garbled.
Image

Additional context

It looks like go-ora determines and caches the NLS_CHARACTERSET from the first connection, and does not reinitialize it for subsequent connections in the same process.
This makes it impossible to query multiple databases with different encodings without restarting the application.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions