sijms / go-ora

Pure go oracle client
MIT License
796 stars 177 forks source link

Add an option to specify client charset different than server charset #323

Closed travelliu closed 1 year ago

travelliu commented 1 year ago

When the Oracle client character set NLS_LANG is consistent with the server, the data will not be transcoded.

insert into ora_mtk.TAB_US7ASCCI (name) values ('中国人')
SELECT dump(col2,1016) FROM ora_mtk.TAB_US7ASCCI tua ;
Typ=1 Len=9 CharacterSet=US7ASCII: e4,b8,ad,e5,9b,bd,e4,ba,ba;

The character encoding in the program is UTF8. Set NLS_LANG=AMERICAN_AMERICA.US7ASCII. The inserted encoding is UTF8

How to set go-ora not to transcode query and insert

sijms commented 1 year ago

hi @travelliu this code from command.go line #89

if parse {
    session.PutUint(len(stmt.connection.strConv.Encode(stmt.text)), 4, true, true)
    session.PutBytes(1)
}

as you see the text is encoded with character conversion method of the connection which use server charset not UTF8 this step is important and done by all clients otherwise server will raise error so sequence as follow your text => convert to UTF8 by go => convert from UTF8 to bytes using server charset ==> bytes send to server as network message the first part of the sequence you should do and the remaining is done automatically by the client

travelliu commented 1 year ago

I know this. If you use OCI, you can set NLS_LANG=AMERICAN_AMERICA. US7ASCII. This allows the client and server to have the same character set. Neither the server nor the client is transcoded. Client-generated characters are encoded and stored on the server side. Queries too. This allows the application to handle the characters itself. How to drive the error transcoding, resulting in garbled data queried.

For example, the data is inserted into the US7ASCII database through OCI and the GBK code is inserted. Now this treatment becomes to think that the encoding is US7ASCII but it is actually GBK, and it is wrong in transcoding

Transcoding is possible by default, and it is best to provide parameters that are not transcoded. For example, the database returns the encoding user sets US7ASCII so that it is transcoded, and the data encoding is processed by the application

sijms commented 1 year ago

still i can't get your point sorry but i will go step by step 1- the program code is written in utf8 2- client will encode query string from utf8 to bytes using server charset 3- bytes send to server

so Chinese text in sql text will be encoded with server charset = US7ASCII will lead to wrong encoding

you can change connection character conversion after connection is opened by calling go_ora.SetStringConverter(...)

// SetStringConverter this function is used to set a custom string converter interface
// that will used to encode and decode strings and bytearrays
func (conn *Connection) SetStringConverter(converter converters.IStringConverter) {
    conn.strConv = converter
    conn.session.StrConv = converter
}
travelliu commented 1 year ago

Oracle dump chinese US7ASCII: e4,b8,ad,e5,9b,bd,e4,ba,ba;

SELECT dump(col2,1016) FROM ora_mtk.TAB_US7ASCCI tua ;
Typ=1 Len=9 CharacterSet=US7ASCII: e4,b8,ad,e5,9b,bd,e4,ba,ba;

now query result 3f3f3f3f3f3f3f3f3f

i will test SetStringConverter

travelliu commented 1 year ago
type asciiConverter struct {
    LangID    int
}

func (conv *asciiConverter) GetLangID() int {
    return conv.LangID
}

func (conv *asciiConverter) SetLangID(langID int) int {
    oldValue := conv.LangID
    conv.LangID = langID
    return oldValue
}

func (conv *asciiConverter) Encode(data string) []byte {
    return utils.StringToBytes(&data)
}

func (conv *asciiConverter) Decode(buf []byte ) string {
    return utils.BytesToString(buf)
}

conn.SetStringConverter(&asciiConverter{})

query result 中国人 e4b8ade59bbde4baba

But this no SQL/Databases interface

sijms commented 1 year ago

the solution is to add url option to set custom charset of the client but this is not test all over connection lifetime

robstradling commented 1 year ago

I have a very similar issue with a legacy US7ASCII database, which is far too large to contemplate attempting to convert to UTF-8.

With other Oracle clients I've been able to get UTF-8 data in and out of this database by claiming that the client's character set is also US7ASCII, and I now need to be able to do the same thing with go-ora.

In my Go application I'd already configured a SetStringConverter as described by @travelliu a few comments ago, and with this my application can successfully SELECT UTF-8 data that is already present in my US7ASCII database. However, I'm still having trouble getting UTF-8 data into this database in the first place...

When my Go application executes a PL/SQL function using go-ora and passes in any string that contains any multi-byte UTF-8 characters, I always get the following error: ORA-01460: unimplemented or unreasonable conversion requested

On my database, V$SESSION_CONNECT_INFO.CLIENT_CHARSET is "US7ASCII" for the connections from go-ora, so I don't understand what "conversion" is being "requested".

@sijms Do you have any suggestions?

sijms commented 1 year ago

I will add option client charset and use this charset in 1- encode sqlText 2- encode and decode parameters/columns 3- encode and decode CLOBs

sijms commented 1 year ago

fixed in v2.6.12

robstradling commented 1 year ago

Sadly v2.6.12 doesn't seem to help my use case. When my application sets "client charset=US7ASCII", a string such as "中国人" becomes fdfdfd before go-ora sends it to the database server. I'm looking for a way to get unmodified 8-bit data in and out of a US7ASCII database, which I've been able to do with other Oracle clients.

sijms commented 1 year ago

not used like that database charset is US7ASCII you are using text 中国人 that is not compatible with this charset so you will define a client charset that is compatible with the text as follow client charset=ZHS16GBK now test and it will work

sijms commented 1 year ago

note that using this option is left for a legacy US7ASCII database as you request before and better to avoid use it in general cases because if you insert a text with a client charset and try to read it with server charset or any other charset may give panic or unreadable text

robstradling commented 1 year ago

not used like that database charset is US7ASCII you are using text 中国人 that is not compatible with this charset so you will define a client charset that is compatible with the text as follow client charset=ZHS16GBK now test and it will work

Ah, I see. Yes, with client charset=ZHS16GBK or client charset=UTF8 I can call a PL/SQL function on my legacy US7ASCII database and successfully pass a Go string containing the text 中国人 into a VARCHAR2 parameter. (If I build my application against v2.6.11 instead, it gives the error ORA-01460: unimplemented or unreasonable conversion requested; so v2.6.12 has indeed made a difference :-) ).

However, I'm still getting ORA-01460: unimplemented or unreasonable conversion requested when attempting to pass a []string slice containing non-ASCII values into a TABLE OF VARCHAR2 parameter. I see you did update encodeArrayString in v2.6.12, so presumably this is meant to work?

note that using this option is left for a legacy US7ASCII database as you request before and better to avoid use it in general cases

+1. I completely agree!

sijms commented 1 year ago

I go to example arrays/main.go make change at line #65 as follow

nameText[index] = "中国人中国人中国人"
//nameText[index] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

now run the code with option charset=ZHS16GBK this is the output

Finish create table GOORA_TEMP_VISIT : 50.849263ms
100 rows inserted: 133.751766ms
Finish create package:  125.383457ms
ID:  1  Name:  中国人中国人中国人       val:  1.1       Date:  {2023-04-05 23:26:45 +0300 +03 true}
ID:  3  Name:  中国人中国人中国人       val:  3.3       Date:  {2023-06-05 23:26:45 +0300 +03 true}
ID:  5  Name:  中国人中国人中国人       val:  5.5       Date:  {2023-08-05 23:26:45 +0300 +03 true}
Finish query RefCursor:  742.102µs
Finish Query1:  100.475554ms
[中国人中国人中国人 中国人中国人中国人 中国人中国人中国人]
[1 3 5]
[{2023-04-05 23:26:45 +0300 +03 true} {2023-06-05 23:26:45 +0300 +03 true} {2023-08-05 23:26:45 +0300 +03 true}]
Finish Query2:  1.827653ms
Drop package:  139.774406ms
Finish drop table:  392.01054ms
travelliu commented 1 year ago

@sijms

The client character set has been added, but the query is still garbled

time="2023-04-06 14:48:02.696857" level=info msg="the connect database using: oracle://system:%2A%2A%2A%2A%2A%2A@127.0.0.1:1523/mtk?CONNECTION+TIMEOUT=30&PREFETCH_ROWS=1000&**client+charset=US7ASCII**&connStr=%28DESCRIPTION%3D%28CONNECT_TIMEOUT+%3D+30%29%28ADDRESS_LIST%3D%28ADDRESS%3D%28PROTOCOL%3DTCP%29%28HOST%3D127.0.0.1%29%28PORT%3D1523%29%29%29%28CONNECT_DATA%3D%28SERVER%3DDEDICATED%29%28SERVICE_NAME%3Dmtk%29%29%29" function=getConnectDsn line=44 file="/Users/travel/Documents/Code/Enmotech/cloudAssistant/mtk/pkg/databases/oracle/dsn.go"
time="2023-04-06 14:48:02.808869" level=info msg="the database charset US7ASCII" function=GetCharSet line=97 file="/Users/travel/Documents/Code/Enmotech/cloudAssistant/mtk/pkg/databases/oracle/version.go"
time="2023-04-06 14:48:02.808951" level=info msg="auto set ENV NLS_LANG=AMERICAN_AMERICA.US7ASCII " function=CheckEnvNlsLangExisted line=230 file="/Users/travel/Documents/Code/Enmotech/cloudAssistant/mtk/pkg/databases/oracle/oracle.go"
&sql.ColumnType{name:"ID", hasNullable:true, hasLength:false, hasPrecisionScale:true, nullable:true, length:0, databaseType:"NUMBER", precision:38, scale:255, scanType:(*reflect.rtype)(0x1007ea380)}
&sql.ColumnType{name:"CHARSET", hasNullable:true, hasLength:true, hasPrecisionScale:false, nullable:true, length:40, databaseType:"NCHAR", precision:0, scale:0, scanType:(*reflect.rtype)(0x1007ea380)}
&sql.ColumnType{name:"COL2", hasNullable:true, hasLength:true, hasPrecisionScale:false, nullable:true, length:40, databaseType:"NCHAR", precision:0, scale:0, scanType:(*reflect.rtype)(0x1007ea380)}

    --- PASS: Test_Oracle_From_Database/test_utf8_gbk (0.18s)

query result

9 GO_ASCII ????????? 3f3f3f3f3f3f3f3f3f

Additional configurations need to be added

sijms commented 1 year ago

Hi @travelliu don't use client charset=US7ASCII becuase US7ASCII is the server charset client charset should be different from server charset for example: client charset=ZHS16GBK if you need to insert or read '中国人' into US7ASCII database

robstradling commented 1 year ago

I go to example arrays/main.go make change at line #65 as follow ... now run the code with option charset=ZHS16GBK this is the output

That example works for me too, but it's a bulk-insert rather than a stored procedure call.

I've created https://gist.github.com/robstradling/3bf7c340bc4479f3b3a71c58a9842657 to precisely demonstrate the issue I'm facing. Any ideas?

sijms commented 1 year ago

if you face different issue please write example so i can produce the error

sijms commented 1 year ago

ok @robstradling i will test you code and give you feedback

travelliu commented 1 year ago

Hi @travelliu don't use client charset=US7ASCII becuase US7ASCII is the server charset

client charset should be different from server charset

for example: client charset=ZHS16GBK if you need to insert or read '中国人' into US7ASCII database

Can't you not transcode? The same character set, direct return. Program control, drivers do not decode and encode

sijms commented 1 year ago

@robstradling this is the result

Finish create string array type:  548.207721ms
Finish create stored procedure:  172.754638ms

Call stored procedure with {"a", "b", "c"}:
Can't call store procedure ORA-06550: line 1, column 7:
PLS-00905: object LAB.GOORA_TEMP_PROC is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

Call stored procedure with {"a", "b", "中国人中国人中国人"}:
Can't call store procedure ORA-06550: line 1, column 7:
PLS-00905: object LAB.GOORA_TEMP_PROC is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

Finish drop stored procedure:  122.821322ms
Finish drop string array type:  747.709701ms
sijms commented 1 year ago

@travelliu i don't understand the issue can you give me more explaination

travelliu commented 1 year ago
time="2023-04-06 21:17:12.878369" level=info msg="auto set ENV NLS_LANG=AMERICAN_AMERICA.US7ASCII " function=CheckEnvNlsLangExisted line=230 file="/Users/travel/Documents/Code/Enmotech/cloudAssistant/mtk/pkg/databases/oracle/oracle.go"
    --- FAIL: Test_Oracle_From_Database/test_utf8_gbk (0.11s)
panic: runtime error: index out of range [1] with length 1 [recovered]
    panic: runtime error: index out of range [1] with length 1

goroutine 50 [running]:
testing.tRunner.func1.2({0x10086d360, 0xc0003b23d8})
    /usr/local/opt/go/libexec/src/testing/testing.go:1396 +0x24e
testing.tRunner.func1()
    /usr/local/opt/go/libexec/src/testing/testing.go:1399 +0x39f
panic({0x10086d360, 0xc0003b23d8})
    /usr/local/opt/go/libexec/src/runtime/panic.go:884 +0x212
encoding/binary.bigEndian.Uint16(...)
    /usr/local/opt/go/libexec/src/encoding/binary/binary.go:139
github.com/sijms/go-ora/v2/converters.(*StringConverter).Decode(0xc0000ba060, {0xc000167e00, 0x9, 0x40})
    /Users/travel/Documents/Code/go/pkg/mod/github.com/sijms/go-ora/v2@v2.6.12/converters/string_conversion.go:210 +0x8f2
github.com/sijms/go-ora/v2.(*ParameterInfo).decodeValue(0xc0001744e0, 0xc0004746c0)
    /Users/travel/Documents/Code/go/pkg/mod/github.com/sijms/go-ora/v2@v2.6.12/parameter.go:923 +0x456
github.com/sijms/go-ora/v2.(*ParameterInfo).decodeColumnValue(0xc0001744e0, 0xc00059311b?)

gbk panic @sijms

robstradling commented 1 year ago

@sijms Ah, sorry, there was a stray type reference. Please try https://gist.github.com/robstradling/3bf7c340bc4479f3b3a71c58a9842657 again now.

travelliu commented 1 year ago

When client charset is the same as server charset, Decode/encode is not required. Encoding visibility The app controls itself

like this

        case NCHAR, CHAR, LONG:
            if connection.connOption.CharsetID == par.CharsetID {
                tempVal = converters.BytesToString(par.BValue)
                break
            }

func (conv *StringConverter) Encode(input string) []byte {
    if len(input) == 0 {
        return nil
    }
    temp := utf16.Encode([]rune(input))
    switch conv.LangID {
    case 1:
        return utils.StringToBytes(&input)
type asciiConverter struct {
    LangID    int
}

func (conv *asciiConverter) GetLangID() int {
    return conv.LangID
}

func (conv *asciiConverter) SetLangID(langID int) int {
    oldValue := conv.LangID
    conv.LangID = langID
    return oldValue
}

func (conv *asciiConverter) Encode(data string) []byte {
    return utils.StringToBytes(&data)
}

func (conv *asciiConverter) Decode(buf []byte ) string {
    return utils.BytesToString(buf)
}

conn.SetStringConverter(&asciiConverter{})
sijms commented 1 year ago

@travelliu you talk specifically about Ascii which is LangID = 1 right?

sijms commented 1 year ago

you want to cancel encoding and decoding for this LangID =1 and put code in StringToBytes?

sijms commented 1 year ago

@robstradling i get the error now and i will investigate and feedback

sijms commented 1 year ago

@travelliu also please update to v2.6.12 because this code

case NCHAR, CHAR, LONG:
    if connection.connOption.CharsetID == par.CharsetID {
        tempVal = converters.BytesToString(par.BValue)
        break
       }

is changed in last version

travelliu commented 1 year ago

@travelliu you talk specifically about Ascii which is LangID = 1 right?

i not sure this right. Need to check if the client charset and server charset are consistent.

Like client charset zhs16gbk and server charset zhs16gbk not need encoding and decoding

sijms commented 1 year ago

if you talk in general if server charset is same as client charset no need for encoding and decoding this will not work because bytes returned from server is encoded with server charset so to represent as go string which is UTF8 you need to convert this byte array into UTF8

sijms commented 1 year ago

@travelliu you talk specifically about Ascii which is LangID = 1 right?

i not sure this right. Need to check if the client charset and server charset are consistent.

Like client charset zhs16gbk and server charset zhs16gbk not need encoding and decoding

it will work only if zhs16gbk is same as utf8?

travelliu commented 1 year ago

if you talk in general if server charset is same as client charset no need for encoding and decoding this will not work because bytes returned from server is encoded with server charset so to represent as go string which is UTF8 you need to convert this byte array into UTF8

so to represent as go string which is UTF8 you need to convert this byte array into UTF8

No need to care

OCI The OCI driver did not convert to utf8

travelliu commented 1 year ago

I am querying data to insert into another database. The query needs to be consistent with the internal storage of the database, as there are rare and self-made characters. Encoding and decoding can result in incorrect data.

sijms commented 1 year ago

i will give you example to clear the issue

dBuffer: []int{
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
    96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
    8364, 1662, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 1657, 8249, 338, 1670, 1688, 1672,
    1711, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 1705, 8482, 1681, 8250, 339, 8204, 8205, 1722,
    160, 1548, 162, 163, 164, 165, 166, 167, 168, 169, 1726, 171, 172, 173, 174, 175,
    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 1563, 187, 188, 189, 190, 1567,
    1729, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583,
    1584, 1585, 1586, 1587, 1588, 1589, 1590, 215, 1591, 1592, 1593, 1594, 1600, 1601, 1602, 1603,
    224, 1604, 226, 1605, 1606, 1607, 1608, 231, 232, 233, 234, 235, 1609, 1610, 238, 239,
    1611, 1612, 1613, 1614, 244, 1615, 1616, 247, 1617, 249, 1618, 251, 252, 8206, 8207, 1746,
},

so if the server send for example 143 it should be converted to 1672 to be correctly displayed

sijms commented 1 year ago

I am querying data to insert into another database. The query needs to be consistent with the internal storage of the database, as there are rare and self-made characters. Encoding and decoding can result in incorrect data.

query then insert. you talk about special situation can't be generalized

travelliu commented 1 year ago
WeChatWorkScreenshot_cc1a7b17-8d4a-440f-bbb5-b8b394810653

database D6D0CEC4 not need decode to E4B8ADE69687. i need return D6D0CEC4

2023-04-06 at 22 03

sijms commented 1 year ago

if i generalize you idea i will make driver useless if you query data and need to put it into web page or display it to a customer

sijms commented 1 year ago

your situation is a special situation when you need to transfer data from server to server you can use bulk copy which use oracle direct path it will not make and encode/decode operation

travelliu commented 1 year ago

godror has option 2023-04-06 at 22 11

set Charset=US7ASCII query result like this

9 GO_ASCII 中国人 e4b8ade59bbde4baba
10 GO_ASCII ??? 3f3f3f
11 GO_ASCII 中国人 e4b8ade59bbde4baba
1 JAVA 中国人 e4b8ade59bbde4baba
2 GO_ASCII ??? 3f3f3f
13 GO_ASCII ��� d6d0b9fac8cb
13 GO_ASCII ��� fdfdfd
13 GO_ASCII ��� fdfdfd
3 GO_UTF8 ??? 3f3f3f
4 GO_ASCII ??? 3f3f3f
5 GO_ASCII ??? 3f3f3f
6 GO_ASCII ??? 3f3f3f
7 GO_ASCII ??? 3f3f3f
8 GO_ASCII 中国人 e4b8ade59bbde4baba
13 java_bytes 中国人 e4b8ade59bbde4baba
20 GO_ASCII ��� fdfdfd
20 GO_ASCII 中国人 e4b8ade59bbde4baba
21 GO_ASCII 中国人 e4b8ade59bbde4baba
21 GO_ASCII 中国人 e4b8ade59bbde4baba
travelliu commented 1 year ago

your situation is a special situation when you need to transfer data from server to server you can use bulk copy which use oracle direct path it will not make and encode/decode operation

other database not oracle

sijms commented 1 year ago

godror has option 2023-04-06 at 22 11

set Charset=US7ASCII query result like this

9 GO_ASCII 中国人 e4b8ade59bbde4baba
10 GO_ASCII ??? 3f3f3f
11 GO_ASCII 中国人 e4b8ade59bbde4baba
1 JAVA 中国人 e4b8ade59bbde4baba
2 GO_ASCII ??? 3f3f3f
13 GO_ASCII ��� d6d0b9fac8cb
13 GO_ASCII ��� fdfdfd
13 GO_ASCII ��� fdfdfd
3 GO_UTF8 ??? 3f3f3f
4 GO_ASCII ??? 3f3f3f
5 GO_ASCII ??? 3f3f3f
6 GO_ASCII ??? 3f3f3f
7 GO_ASCII ??? 3f3f3f
8 GO_ASCII 中国人 e4b8ade59bbde4baba
13 java_bytes 中国人 e4b8ade59bbde4baba
20 GO_ASCII ��� fdfdfd
20 GO_ASCII 中国人 e4b8ade59bbde4baba
21 GO_ASCII 中国人 e4b8ade59bbde4baba
21 GO_ASCII 中国人 e4b8ade59bbde4baba

i explain to you that i add this option in v2.6.12 and explain how to use it

sijms commented 1 year ago

did you try it and get error?

travelliu commented 1 year ago
time="2023-04-06 22:18:12.60593" level=info msg="the connect database using: oracle://system:%2A%2A%2A%2A%2A%2A@127.0.0.1:1523/mtk?CLIENT+CHARSET=US7ASCII&CONNECTION+TIMEOUT=30&PREFETCH_ROWS=1000&connStr=%28DESCRIPTION%3D%28CONNECT_TIMEOUT+%3D+30%29%28ADDRESS_LIST%3D%28ADDRESS%3D%28PROTOCOL%3DTCP%29%28HOST%3D127.0.0.1%29%28PORT%3D1523%29%29%29%28CONNECT_DATA%3D%28SERVER%3DDEDICATED%29%28SERVICE_NAME%3Dmtk%29%29%29" file="/Users/travel/Documents/Code/Enmotech/cloudAssistant/mtk/pkg/databases/oracle/dsn.go" function=getConnectDsn line=44
time="2023-04-06 22:18:12.679323" level=info msg="the database charset US7ASCII" function=GetCharSet line=97 file="/Users/travel/Documents/Code/Enmotech/cloudAssistant/mtk/pkg/databases/oracle/version.go"
time="2023-04-06 22:18:12.679368" level=info msg="auto set ENV NLS_LANG=AMERICAN_AMERICA.US7ASCII " function=CheckEnvNlsLangExisted line=230 file="/Users/travel/Documents/Code/Enmotech/cloudAssistant/mtk/pkg/databases/oracle/oracle.go"
<nil>
&sql.ColumnType{name:"ID", hasNullable:true, hasLength:false, hasPrecisionScale:true, nullable:true, length:0, databaseType:"NUMBER", precision:38, scale:255, scanType:(*reflect.rtype)(0x1007ea240)}
&sql.ColumnType{name:"CHARSET", hasNullable:true, hasLength:true, hasPrecisionScale:false, nullable:true, length:40, databaseType:"NCHAR", precision:0, scale:0, scanType:(*reflect.rtype)(0x1007ea240)}
&sql.ColumnType{name:"COL2", hasNullable:true, hasLength:true, hasPrecisionScale:false, nullable:true, length:40, databaseType:"NCHAR", precision:0, scale:0, scanType:(*reflect.rtype)(0x1007ea240)}
9 GO_ASCII ????????? 3f3f3f3f3f3f3f3f3f
10 GO_ASCII ??? 3f3f3f
11 GO_ASCII ????????? 3f3f3f3f3f3f3f3f3f
1 JAVA ????????? 3f3f3f3f3f3f3f3f3f
2 GO_ASCII ??? 3f3f3f
13 GO_ASCII ?????? 3f3f3f3f3f3f
13 GO_ASCII ??? 3f3f3f
13 GO_ASCII ??? 3f3f3f
3 GO_UTF8 ??? 3f3f3f
4 GO_ASCII ??? 3f3f3f
5 GO_ASCII ??? 3f3f3f
6 GO_ASCII ??? 3f3f3f
7 GO_ASCII ??? 3f3f3f
8 GO_ASCII ????????? 3f3f3f3f3f3f3f3f3f
13 java_bytes ????????? 3f3f3f3f3f3f3f3f3f
20 GO_ASCII ??? 3f3f3f
20 GO_ASCII ????????? 3f3f3f3f3f3f3f3f3f
21 GO_ASCII ????????? 3f3f3f3f3f3f3f3f3f
21 GO_ASCII ????????? 3f3f3f3f3f3f3f3f3f
21 GO_ASCII ??? 3f3f3f

result is not same godror

travelliu commented 1 year ago

My database contains characters that encode private areas, characters that the business makes itself. Encoding/Coding will cause errors. So you can only query it out as it is and then insert it

sijms commented 1 year ago

Hi @travelliu don't use client charset=US7ASCII becuase US7ASCII is the server charset

client charset should be different from server charset

for example: client charset=ZHS16GBK if you need to insert or read '中国人' into US7ASCII database

You are still using client charter = US7ASCII

travelliu commented 1 year ago

https://en.wikipedia.org/wiki/Private_Use_Areas

travelliu commented 1 year ago

Hi @travelliu don't use client charset=US7ASCII becuase US7ASCII is the server charset client charset should be different from server charset for example: client charset=ZHS16GBK if you need to insert or read '中国人' into US7ASCII database

You are still using client charter = US7ASCII

https://github.com/sijms/go-ora/issues/323#issuecomment-1499051313

panic: runtime error: index out of range [1] with length 1 [recovered] panic: runtime error: index out of range [1] with length 1

sijms commented 1 year ago

You can use utf8

travelliu commented 1 year ago

You can use utf8

OK. I test. I'm not sure it's correct for private use area characters