Попытка вставить такую строку в таблицу Oracle: ABčDE
Таблица Oracle определяется следующим образом:
SQL> create table DUMMY_TEST (Field1 number, Name_Test varchar2(20));
Ниже приводится Java / JDB C код используется. Это делает 2 вставки. Одна вставка жестко запрограммирована в коде, а вторая извлечена из файла.
import java.sql.*;
import java.util.*;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Locale;
class JdbcTest
{
static StringBuffer sbuff = new StringBuffer();
public static void main (String a[])
{
//Creating the connection
String url = "jdbc:oracle:thin:@//server:port/ServiceName";
String user = "xa21appdb";
String pass = "neptune";
//Inserting data using SQL query
String sql = "INSERT INTO DUMMY_TEST VALUES(1, 'ABèDE')";
loadDataFromFile();
Connection con=null;
try
{
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
//Reference to connection interface
con = DriverManager.getConnection(url,user,pass);
Statement st = con.createStatement();
System.out.println("Executing 1st INSERT");
int m = st.executeUpdate(sql);
if (m == 1)
System.out.println("1st inserted successfully ");
else
System.out.println("1st insertion failed");
System.out.println("Executing 2nd INSERT");
m = st.executeUpdate(sbuff.toString());
if (m == 1)
System.out.println("2nd inserted successfully ");
else
System.out.println("2nd insertion failed");
con.close();
}
catch(Exception ex)
{
System.err.println(ex);
}
}
static void loadDataFromFile()
{
try
{
InputStream inputStream = new FileInputStream("/tmp/input.txt");
Reader inputStreamReader = new InputStreamReader( inputStream, "UTF-8");
int ch = inputStreamReader.read();
while(ch != -1)
{
sbuff.append((char) ch);
ch = inputStreamReader.read();
}
inputStreamReader.close();
}
catch(Exception e){}
}
}
Здесь находится содержимое файла, которое содержит то же SQL, что и жестко закодированное значение.
> cat /tmp/input.txt
INSERT INTO DUMMY_TEST VALUES(2, 'ABèDE')
Чтобы жестко закодировать SQL и SQL из файла, команда xxd использовалась для отображения шестнадцатеричных значений.
Показывает только оператор INSERT и строку ABčDE для вставки.
> xxd -b JdbcTest.java
:
:
000019e: 01101100 00100000 00111101 00100000 00100010 01001001 l = "I
00001a4: 01001110 01010011 01000101 01010010 01010100 00100000 NSERT
00001aa: 01001001 01001110 01010100 01001111 00100000 01000100 INTO D
00001b0: 01010101 01001101 01001101 01011001 01011111 01010100 UMMY_T
00001b6: 01000101 01010011 01010100 00100000 01010110 01000001 EST VA
00001bc: 01001100 01010101 01000101 01010011 00101000 00110001 LUES(1
00001c2: 00101100 00100000 00100111 01000001 01000010 11101000 , 'AB.
00001c8: 01000100 01000101 00100111 00101001 00100010 00111011 DE')";
Показывает весь код файла, который читается со вставляемой строкой ABčDE.
> xxd -b /tmp/input.txt
0000000: 01001001 01001110 01010011 01000101 01010010 01010100 INSERT
0000006: 00100000 01001001 01001110 01010100 01001111 00100000 INTO
000000c: 01000100 01010101 01001101 01001101 01011001 01011111 DUMMY_
0000012: 01010100 01000101 01010011 01010100 00100000 01010110 TEST V
0000018: 01000001 01001100 01010101 01000101 01010011 00101000 ALUES(
000001e: 00110010 00101100 00100000 00100111 01000001 01000010 2, 'AB
0000024: 11101000 01000100 01000101 00100111 00101001 00001010 .DE').
При сравнении файла 2 он подтверждает, что строка идентична жесткому коду и файлу.
00100111 01000001 01000010 11101000 01000100 01000101 00100111
' A B . D E '
Когда код запускается, следующие 2 строки вставляются в Oracle.
SQL> select * from dummy_test;
FIELD1 NAME_TEST
---------- --------------------
1 ABèDE
2 AB?DE
Использование команды DUMP для получения сведений для каждого.
SQL> select field1, dump(name_test, 1016) from dummy_test;
FIELD1 DUMP(NAME_TEST,1016)
---------- -------------------------------------------------------------
1 Typ=1 Len=6 CharacterSet=AL32UTF8: 41,42,c4,8d,44,45
2 Typ=1 Len=7 CharacterSet=AL32UTF8: 41,42,ef,bf,bd,44,45
Если код изменен с этого:
Reader inputStreamReader = new InputStreamReader( inputStream, "UTF-8");
на это:
Reader inputStreamReader = new InputStreamReader( inputStream);
Это работает, так как обе строки покажут следующее:
SQL> select field1, dump(name_test, 1016) from dummy_test;
FIELD1 DUMP(NAME_TEST,1016)
---------- -------------------------------------------------------------
1 Typ=1 Len=6 CharacterSet=AL32UTF8: 41,42,c4,8d,44,45
2 Typ=1 Len=6 CharacterSet=AL32UTF8: 41,42,c4,8d,44,45
Теперь на 3 вопроса.
1 - В сценарии, когда он работает и «специальный» символ вставлен правильно, это можно подтвердить, поскольку набор символов Oracle AL32UTF8 показывает, что c4 8d представляет č, но мой вопрос заключается в том, почему Oracle распечатка è.
2 - Когда UTF-8 используется с READER, вставляются 3 байта (ef, bf, bd). Если я правильно выполнил вычисления в UTF-8, то получилось что-то вроде следующего:
11101111 10111111 10111101
1111111111111101
FF FD
И это очень необычный персонаж.
Хотя я понимаю, что произошел конфликт с преобразованием, но не могли бы вы объяснить, что именно произошло?
Отредактировано, чтобы добавить третий вопрос.
3 - Сессия My Putty содержит набор символов: ISO-8859-1: 1998 (Latin-1, Западная Европа) Почему в командной строке отображается ABèDE вместо ABčDE?