Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Làm thế nào để kết nối với cơ sở dữ liệu bằng QOCI hoặc QODBC với mã hóa chính xác?

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 ł ń


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chiến lược phân trang của Oracle

  2. Trong Oracle 11g làm thế nào để bạn tính thời gian cho dữ liệu trung bình hàng giờ giữa hai ngày?

  3. Có danh sách cột tự động bỏ chia sẻ (oracle 11g)

  4. Tác dụng của việc đặt cam kết sau DML trong thủ tục là gì?

  5. chuyển đổi oracle blob sang loại xml