Oracle i cyrylica

LE
  • Rejestracja: dni
  • Ostatnio: dni
0

Witam

Posiadam bazę Oracle z następującymi ustawieniami

Kopiuj
NLS_CHARACTERSET                      EE8MSWIN1250 
NLS_NCHAR_CHARACTERSET                AL16UTF16
NLS_LANGUAGE                          AMERICAN

Stworzyłem w tej bazie na próbę tabelę z jedną kolumną typu NVARCHAR2 w której to zamierzam przechowywać cyrylicę.

Z bazą łączę się za pomocą SQL Developera.
Cały problem polega na tym, że kiedy łańcuch wrzucam do bazy za pomocą komórki w sekcji Data tej tabeli dane umieszczane są w tabeli prawidłowo. kiedy natomiast dane wrzucam za pomocą zapytania INSERT w bazie lądują znaki zapytania, bez względu na to czy owy łańcuch poprzedzę N'łańcuch' czy też nie.

Warto przy tym dodać, że zapytanie moje jak i to wygenerowane przez SQL Developera podczas modyfikacji komórki jest identyczne, co więcej, NVARCHAR2 korzysta z kodowania AL16UTF16 więc nie powinien mieć problemu z zapisem cyrylicy.

Na sam koniec podam jako ciekawostkę, że kiedy zmieniłem kodowanie NLS_CHARACTERSET na UTF8 dane wrzucane za pomocą zapytanie INSERT poprawnie lądowały w bazie, jednak na bazie produkcyjnej nie mam możliwości takiej zmiany :(, tym bardziej, że skoro SQL Developer potrafi umieścić cyrylicę poprawnie dla pierwszego przypadku, to zakładam, że istnieje możliwość poprawnego wrzucenia danych poprzez zapytanie.

Pozdrawiam

Misiekd
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7923
0
Melanholik napisał(a)

Za ciężkie pytanie jak na to forum leshqo. Tu potrafią odpowiadać tylko na pytania studentów.

a ty oczywiście wiesz ale nie powiesz bo jesteś super hiper pojebany...

sqldeveloper nie jest stworzony do takich rzeczy ale można go do tego zmusić (ale musisz mieć klienta i serwer min 10.2, czasami nie chce działać z instant klientem)

  1. w pliku <SQLDEV_HOME>\sqldeveloper\bin\sqldeveloper.conf dodaj linijkę
    AddVMOption -Doracle.jdbc.convertNcharLiterals=true
  2. przy zapytaniu używasz konstrukcji z N
Kopiuj
insert into aaa(a) values (N'пвпвапва');

Natomiast aby aplikacje używały przekodowania znaków musisz ustawić zmienną środowiskową (wymagania co do klienta i serwera jw.)
ORA_NCHAR_LITERAL_REPLACE=TRUE

przykład

Kopiuj
drop table dupa;
create table dupa (a nvarchar2(100));
insert into dupa(a) values (N'пвпвапва');
select * from dupa;

wynik

Kopiuj
table dupa dropped.

table dupa created.

1 rows inserted.

A                                  
                                                                  
---------------------------------------------------------------------------------------------------- 

пвпвапва                                                                                             
LE
  • Rejestracja: dni
  • Ostatnio: dni
0

Dzięki Misiekd.

Aktualnie miałem tylko chwilę i sprawdziłem pierwszą część tego co napisałeś i SQL Dev prawidłowo już wrzuca dane. Chwilę później lub jutro sprawdzę jeszcze jak radzi sobie apka na .NET po dodaniu zmiennej środowiskowej i dam znać.

LE
  • Rejestracja: dni
  • Ostatnio: dni
0

Sprawa wygląda następująco.

Ustawiłem zmienną środowiskową w systemie

ORA_NCHAR_LITERAL_REPLACE=TRUE

jednak w dalszym ciągu, kiedy korzystam z aplikacji zewnętrznej w bazie lądują znaki zapytania, podczas gdy z NATIONAL_CHAR UTF8 jest OK.

Czy jest jeszcze jakieś miejsce, gdzie trzeba coś zmienić ?

Dodam że korzystam z aplikacji w .NET łączącej się z bazą za pomocą sterownika MS.

Misiekd
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7923
0

odpowiedzieć mogę jedynie u mnie działa

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

    const string conString = "Data Source=linux100;Persist Security Info=True;User ID=***;Password=***;Unicode=True";
    System.Data.OracleClient.OracleConnection con = new System.Data.OracleClient.OracleConnection(conString);
        
    private void button1_Click(object sender, EventArgs e)
    {
        con.Open();
        textBox1.Text += "\r\nOPEN --------------";
    }

    private void button2_Click(object sender, EventArgs e)
    {
        string sql = "select * from dupa";
        System.Data.OracleClient.OracleCommand comm = new System.Data.OracleClient.OracleCommand(sql, con);

        System.Data.OracleClient.OracleDataReader dr = comm.ExecuteReader();
        textBox1.Text += "\r\nSELECT --------------";
        while (dr.Read())
        {
            textBox1.Text += "\r\n" + dr.GetString(0);
        }

    }

    private void button3_Click(object sender, EventArgs e)
    {
        string sql = "insert into dupa(a) values (N'пвпвапва')";
        System.Data.OracleClient.OracleCommand comm = new System.Data.OracleClient.OracleCommand(sql, con);
        comm.ExecuteNonQuery();
        textBox1.Text += "\r\nINSERT --------------";
    }
}
Kopiuj

to co leci do textboxa

OPEN --------------

SELECT --------------

пвпвапва

INSERT --------------

SELECT --------------

пвпвапва

пвпвапва

INSERT --------------

INSERT --------------

INSERT --------------

SELECT --------------

пвпвапва

пвпвапва

пвпвапва

пвпвапва

пвпвапва

Kopiuj
LE
  • Rejestracja: dni
  • Ostatnio: dni
0

Problem rozwiązany :)

Pierwsza rzecz o której wspomnę, a którą pominąłem wcześniej to fakt że aplikacja, z której korzystam ze sterowników do .NET dostarczonych przez ORACLE, o czym wcześniej po prostu nie wiedziałem. Warto przy tej okazji wspomnieć, że parametr Unicode=True w connection string poprawny jest tylko dla sterowników MS.

A co do sedna sprawy to w trakcie debbugowania potężnej ilości kodu okazało się, że w moim przypadku wpis w configu SQL Developera niezbędny jest do poprawnej jego pracy, ale co się tyczy zapytań produkowanych w mojej aplikacji to problemem był źle ustawiona właściwość dla kolejnych parametrów OracleParametrer.OracleDbType, której wartość zawsze wynosiła Varchar2 dla dowolnego stringa. Tak więc dla stringów z niestandardowymi znakami należy ustawić NVarchar2.

Dzięki za pomoc, Pozdrawiam

  • Rejestracja: dni
  • Ostatnio: dni
0

Witam!
U mnie jesli używam klas z przestrzeni System.Data.OracleClient do cyrylica da się zapisać i również da sie odczytać ale jak używam do odczytu obiekty z przestrzeni System.Data.OleDb to juz nie moge odczytać cyrylicy tylko znaki zapytania np.

Kopiuj
 public DataTable GetTableQuery(string cmdString)
        {
            OleDbConnection con = new OleDbConnection(connectionString);
            OleDbCommand cmd = new OleDbCommand(cmdString, con);
            OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);

            DataTable dataTable = new DataTable();
            adapter.Fill(dataTable);

            return dataTable;
        }
 

connectionstring wyglada tak:

Kopiuj
<connectionStrings>
    <add name="xxx" connectionString="Provider=MSDAORA;Data Source=baza;Password=haslo;User ID=system; Unicode=true" providerName="System.Data.OleDb"/>
  </connectionStrings>
 

Czy "System.Data.OleDb" może doczytać cyrylice??

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.