Tôi đã tạo một giải pháp bằng cách sử dụng
- Cơ sở dữ liệu Oracle 12c với Bộ ký tự cơ sở dữ liệu AL32UTF8 (bắt buộc để lưu trữ Unicode !!)
- Lược đồ SCOTT
- Máy khách Oracle Instant 12.2 với gói ODBC (có thể tải xuống miễn phí từ Oracle)
- Oracle SQL Developer (Công cụ có thể nhập các ký tự Unicode và kết nối bằng Java / JDBC)
- Python 3.8
Mã Python dưới đây theo sự hiểu biết của tôi, tôi tự giải thích - chỉ IP, PORT và SERVICE trong chuỗi kết nối cần được thay đổi. Để xem các ký tự Unicode trên shell / cmd, bạn cần đặt biến môi trường
PYTHONIOENCODING=UTF-8
Rất tiếc, điều này không hoạt động trên Eclipse IDE với PyDEV, vì vậy tôi đã sử dụng thử ngoại trừ để lấy mã đang chạy. Đã cho tôi vài giờ đau đầu ...
#
# Safe python file as UTF-8 - otherwise you get no UTF-8 output !!!!
#
# Unix:
# export PYTHONIOENCODING=UTF-8
#
# Windows:
# set PYTHONIOENCODING=UTF-8
#
# Eclipse/PyDev:
# create for run/debug environment variable
# PYTHONIOENCODING=UTF-8
#
# ODBC:
# Oracle Instantclient 12.2 + ODBC package
#
# DB:
# Oracle RDBMS 12.2 with Database Characterset AL32UTF8 to allow Unicode
#
# SQL Tool to Execute SQL (JDBC)
# Oracle SQL Developer
#
# SQL
# connect scott/tiger
# create table polish(col1 varchar2(50));
# insert into polish(col1) values('SQLD ł ń');
# commit;
#
#
import pyodbc
bl = " "
UTF8 = "UTF-8"
strict = "Strict"
s1 = "Test "+UTF8
print(s1)
s1 = chr(322) + bl + chr(324)
m = bytes(s1,UTF8)
print(m)
try:
print(m.decode(UTF8,strict))
except:
pass
print()
print("Test ODBC and " + UTF8)
print("Test ODBC and " + UTF8)
cs = "DRIVER={DRIVERNAME};UID={USERID};PWD={PASSWD};DBQ={IP_OR_HOSTNAME}:{PORT}/{SERVICE_OR_SID};"
csfill = cs.format(DRIVERNAME="Oracle in instantclient_12_2",
IP_OR_HOSTNAME="111.222.33.44",
PORT=12102,
SERVICE_OR_SID="DB1212UTF",
USERID="SCOTT",
PASSWD="tiger")
print(csfill)
cn = pyodbc.connect(csfill)
cursor = cn.cursor()
# Do the insert - can be done using normal parameters and Unicode strings...
cursor.execute("insert into Polish(COL1) values ( ? )", u"Python ł ń")
# perform commit if want to inspect in SQL Developer
# cursor.commit()
cursor = cn.cursor()
# We need to cast COL1 so that unicode is shipped as ' \xxxx'
# unfortunatly Unicode deos not work directly
# so we use ASCIISTR() to do that...
cursor.execute('SELECT ASCIISTR(COL1)"COL1" from Polish')
rows = cursor.fetchall()
for row in rows:
s =""
x = row.COL1
y = 0
j = len(x)-1
# Parse incoming column for Oracle-Style Unicode like ' \0142'
while y <= j:
if y + 5 <= j:
# detect if oracle unicode begins with blank and slash -> ' \'
sc = x[y]+x[y+1]
if sc == " \\":
# create unicode character
c = x[y+2]+x[y+3]+x[y+4]+x[y+5]
s += bl + chr(int(c,16))
# step forward to next character
y += 5
else:
# no unicode 4 characters before end !!
s += chr(ord(x[y]))
else:
# no unicode - regular ASCII
s += chr(ord(x[y]))
y += 1
m = bytes(s,UTF8)
print(m)
try:
print(m.decode(UTF8,strict))
except:
pass
cursor.close()
cn.close()
Ứng dụng đang chạy mang lại
Test UTF-8
b'\xc5\x82 \xc5\x84'
ł ń
Test ODBC and UTF-8
DRIVER=Oracle in instantclient_12_2;UID=SCOTT;PWD=tiger;DBQ=111.222.33.44:12102/DB1212UTF;
b'SQLD \xc5\x82 \xc5\x84'
SQLD ł ń
b'Python \xc5\x82 \xc5\x84'
Python ł ń