Oracle
 sql >> база данни >  >> RDS >> Oracle

Как да се свържа с база данни с помощта на QOCI или QODBC с правилно кодиране?

Създадох решение с помощта на

  • Oracle Database 12c с Database Characterset AL32UTF8 (задължително за съхраняване на Unicode!!)
  • Схема на SCOTT
  • Oracle Instant client 12.2 с ODBC пакет (може да бъде изтеглен безплатно от Oracle)
  • Oracle SQL Developer (Инструмент, който може да въвежда Unicode символи и да се свързва чрез Java/JDBC)
  • Python 3.8

Кодът на Python по-долу според моето разбиране се обяснява сам - трябва да се променят само IP, PORT и SERVICE в низа за свързване. За да гледате Unicode знаците в shell/cmd, трябва да зададете променливата на средата

PYTHONIOENCODING=UTF-8

За съжаление това не работи на Eclipse IDE с PyDEV, така че използвах try-except, за да получа работещ код. Създадох ми няколко часа главоболие...

#  
# 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()   

Работещото приложение дава

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. Продължителност на данните в глобална временна таблица?

  2. Как да използвам CREATE OR REPLACE?

  3. Условен уникален индекс на h2 база данни

  4. ORA-12519 TNS:не е намерен подходящ манипулатор на услугата

  5. Защо OCI8/Oracle oci_bind_array_by_name на PHP не работи за мен?