Hibás magyar ékezet konvertálása JavaScriptben

Hibás magyar ékezet konvertálása JavaScriptben
2021-08-20T22:44:37+02:00
2021-08-26T19:25:45+02:00
2022-12-06T21:20:38+01:00
juzzie
Sziasztok!

Adott egy külföldi termék, mely MS SQL szerverhez csatlakozik és egy Java-ban megírt kliens programmal lehet elérni. A kliens programot nem lehet átírni, de bármennyi JS makró szkriptet lehet futtatni induláskor, ami eseményvezérelt. Az ügyfél ügyesen Latin1-es collation-os szerverre telepítette a programot (a programban nem lehet állítani telepítéskor). Igazából működik a rendszer, de ha egy táblában egy karakterlánc mező típusa varchar, akkor az ott bevitt hosszú ő és ű hibásan jelenik meg a kliensben. Ha nvarchar a mező, akkor minden rendben, a hosszú magyar ékezetes betűk helyesen jelennek meg Latin1 collation mellett is.
Régebben amikor felvetettem itt a problémát, akkor azt tanácsolták többen, hogy állítsam át a collation-t. Ezt megírtam SQL-ben (index-ek primary key-ek SQL create script mentése, majd eldobása, collation átállítás és index, primary create SQL scriptek futtatása) és futtattam is. Igaz, hogy a Latin1-es tábla csak azon mezőinél, ahol a bibi van. Lehet, hogy az egész táblánál javítani kell és a tábla collation-t is átállítani? Mert sajna ez nem vezetett eredményre. Na de a lényeg. Mivel bármilyen JS keretrendszer elérhető és használható vagy akár Java osztályok is, tudnám az értéket kiolvasáskor konvertálni is? Van erre valamilyen megoldás?

Köszönöm előre is a segítséget!
Mutasd a teljes hozzászólást!
Szia,

1) Szuper!
2) Ez érdekes, lásd lentebb.
3) Szerintem mindent jól csináltál, csak egy valami kimaradt.

Kicsit utánaolvastam, és a következő lehet a probléma: habár az oszlopaid collation beállítása
már jó, de mivel az adatabázis még Latin1-es ezért az összes kiadott SQL parancs az adatbázon belül az adatbázis collation-jével fut. (Ezért kaptál eltérő eredményt a tesztekre a 2-es pontban). Tehát hiába adsz ki jó SQL parancsokat, azok Latin1-re konvertálódnak a futtatás pillanatában.

Szóval az adatbázis collation-t is át kell állítani:

use master; go alter database eloam COLLATE Hungarian_CI_AS; go use eloam;
Ezután próbáld meg a felhasználót létrehozni.

Ha vannak tárolt eljárások és függvények, akkor külön meg kellene nézni, hogy az új adatbázis collation-t átvették-e rendesen (remélhatőleg igen), vagy esetleg újra kell őket kreálni.
Mutasd a teljes hozzászólást!

  • A 'collation' az a rendezés sorrendje, neked a 'character set' a barátod. (Megjegyzés: ezeket tipikusan MySql-felhasználók szokták összekeverni; biztos hogy nem arra gondoltál?)
    Mutasd a teljes hozzászólást!
  • Szia,

    ha utólag módosítod a collation-t az oszlopon, az már nem érinti az előtte betöltött adatokat, csak a későbbieket:

    create table tst1 ( c1 varchar(30) collate Latin1_General_CI_AI ) insert into tst1 values ('Alávaló gyűrütt gőzölő') ALTER TABLE tst1 ALTER COLUMN c1 VARCHAR(30) COLLATE Hungarian_CI_AS insert into tst1 values ('Második alávaló gyűrütt gőzölő') -- select * from tst1 Alávaló gyurütt gozölo Második alávaló gyűrütt gőzölő
    Tehát újra kell töltened az adatokat.
    Ha még így sem jó, akkor ki kellene derítened (Profiler), hogy a Java kliens SQL parancsaiba nincs-e bevarrva collation:

    insert into tst1 values ('3. alávaló gyűrütt gőzölő' collate Latin1_General_CI_AI) select * from tst1 --- Alávaló gyurütt gozölo Második alávaló gyűrütt gőzölő 3. alávaló gyurütt gozölo <<< megint rossz --- select c1 collate Latin1_General_CI_AI from tst1 Alávaló gyurütt gozölo Második alávaló gyurütt gozölo <<< a jól bevitt is hibás 3. alávaló gyurütt gozölo
    Mutasd a teljes hozzászólást!
  • SQL Server esetén a collation beállítás befolyásolja a codepage-et is:
    Understand Unicode and code pages in SQL Server collations

    [...] client tools use the collation of non-Unicode data as hint to choose the code page of the data.
    Mutasd a teljes hozzászólást!
  • Mivel még sosem volt dolgom ilyen "MS SQL"-lel, most google-ztam egy kicsit, és azt vélem látni, hogy nem használja a 'character set' fogalmát, pontosabban mondva implicit állapítja meg a 'collation'-ból.

    Mindenesetre a konkrét probléma megoldásához többet kellene tudni annál, hogy 'hibásan jelenik meg' illetve 'nem javult meg'. Az internet szerint mezőben lévő tényleges tartalmat így lehetne hexásan megmutatni:

    select convert(varbinary, Mezoneve) from TablaNeve
    Mutasd a teljes hozzászólást!
  • Szia!

    Köszönöm a választ. Igen, ezt így csinálom, de sajnos továbbra sem lett jó az ékezet.
    Lehet, hogy a táblában az összes szöveges mező (legyen az akár nvarchar) collation-jét és magának a táblának a collation-jét is módosítanom kell?

    Üdv.
    Mutasd a teljes hozzászólást!
  • Szia!

    Igen, ez így van, itt nincs character set, mint például az Oracle-ben vagy MySQL-ben.
    A gond az, hogy mivel ez egy termék, ezért az adatbázis szerkezetét nem lehet módosítani, csak a tulajdonságokkal és az adatokkal tudok játszani. Szerencsére van saját rendszerem is, amit annyiszor berhelhetek szét, ahányszor akarom! :)

    De köszönöm, megnézem a hexa tartalmat is, már csak azért, mert az első adatbevitelnél a hosszú ő és ű még jól látszik. Aztán ez megváltozik (pl. ha újraindítom az egész rendszer).

    Adott egy felhasználókat tároló tábla, aminek az első mezője (username) nvarchar típusú és ott nincs gond a hosszú ő és ű betűkkel, hiába Latin1-es a collation, mert az nvarchar az unicode mező igazából.
    Azonban van vagy 5 leíró mező, amit vagy használunk vagy sem. Általában egy ilyen porperty mezőt felhasználunk, ahova a felhasználó szervezeti egységét írjuk be. Ez nagyon nem változik, csak ha áthelyezik máshová. Itt szerepelhet az a szó például, hogy Jogi főosztály. A Java alapú kliensben amikor egy űrlapon kiválasztják a felhasználót egy kulcsszólistából (pl. Gipsz Jakab is a Jogi főosztálynál dolgozik), akkor egy általunk készített JS szkript lefut (egy API alapján) az eseményre és beírja a felhasználónév mező mellett található szervezeti egység mezőbe automatikusan a szervezet nevét. Ide már minden esetben hibásan érkezik a megnevezés: Jogi foosztály. Ez meg tovább szül más hibákat. Azt meg sem szeretném említeni, hogy akkor a szkriptben javítsunk minden ilyen megnevezést... Azért nem vagyunk favágók! :) De azt azért nem vetném el, ha JS-ben lehetne konvertálni valahogy. De a legjobb megoldás, ha tényleg javítani tudnám az SQL db annyira, hogy eltárolja helyesen a hosszú ő és ű karaktereket.

    Az egész azzal a hibával kezdődött, hogy a rendszert telepítő kolléga nem nézte meg, hogy az ügyfél milyen adatbázis szervert hozott létre a részünkre...

    Üdv.
    Mutasd a teljes hozzászólást!
  • Szia!

    Ha már egy oszlopra átállítottad a collation-t, akkor az új inserteknek a megfelelő kódolással kellene hogy lerakják az adatokat. A régi adat marad, ahogy volt, hibásan, ezért kell mindent rossz kódolású értéket újra betölteni az adatbázisba.

    Ha biztosra akarsz menni, akkor mindent alterálsz az adatbázistól kezdve lefelé a táblákig és oszlopokig.

    Viszont hiába állítod bármire az oszlop collation-t, ha az alkalmazás felülbírálja, pl. a kiadott parancsokba beírva a szerinte megfelelőt. Ezért kellene kinyomozni, pontosan milyen SQL utasítások jönnek Java oldalról.

    A Javascript makrókat nem teljesen értem, hol futnak: a JVM-ben, böngészőben?
    Mutasd a teljes hozzászólást!
  • Szia!

    Annyi hibát találtam, hogy a módosítás előtt single user-re kell kapcsolni az elérést és utána vissza multira. Na ilyet én nem csináltam és talán még az index drop-ot is hülyén csináltam, bár hibaüzenetet nem kaptam.

    Az alkalmazás biztosan nem bírálja felül, de sajna ahhoz vissza kellene fejteni a gyári Java kódot, hogy látni lehessen az sql utasításokat. A Java alapú kliens programnak saját futtató környezete van.
    A kliens közvetlenül nem nyúl az adatbázishoz, azt egy Apache Tomcat-en futó servlet csinálja. A Java kliens-ben tudok kliens és szerveroldali JS-t is futtatni.

    Üdv.
    Mutasd a teljes hozzászólást!
  • Szia,

    módosítás előtt single user-re kell kapcsolni az elérést és utána vissza multira.

    Ez nem feltétlenül probléma, ettől még működnie kellene a fentieknek.

    Nézzünk pár konkrétumot.

    1) Milyen SQL klienst használsz az adminisztratív műveletek futtatásakor? SQL Management Studio lenne az ideális. Minden más csak újabb hibalehetőség.

    2) Szeretném, ha lefuttatnád a fenti példáimat (create table tst1... és a többi) a problémás adatbázison, hogy nálad is ugyanúgy reagál-e a szerver.

    3) Szeretném, ha pontosan (konkrét SQL parancsokkal) leírnád, hogyan próbáltad rendberakni a fent említett felhasználók tábla szervezeti egység property oszlopát, és mi volt az output egyes parancsoknál.
    Mutasd a teljes hozzászólást!
  • Közben ne feledkezzünk meg az adatbázistartalom hexás lekérdezéséről; referenciaképpen itten van a magyar betűk kódja néhány kódolásban.
    Mutasd a teljes hozzászólást!
  • Szia!

    Az adatbázis neve: eloam
    Amit tudni kell még, hogy itthon az SQL szerver egy 2019-es Linux-on (Debian 10.10) futó db!

    1. MS SQL Management Studio-t.
    2. Nem úgy reagál: https://imgur.com/WFNaBNH.png
    3. Sorrend:
    - Mentem a DB-t
    - Megnézem az adott tábla azon mezőit, ahol a javítást eszközölni kell:

    SELECT COLUMN_NAME, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'userdata' and column_name in ('prop3', 'prop5', 'prop6', 'prop7', 'prop8')
    Eredmény:

        - prop3 SQL_Latin1_General_CP1_CI_AS varchar(320)
        - prop5 SQL_Latin1_General_CP1_CI_AS varchar(320)
        - prop6 SQL_Latin1_General_CP1_CI_AS varchar(320)
        - prop7 SQL_Latin1_General_CP1_CI_AS varchar(320)
        - prop8 SQL_Latin1_General_CP1_CI_AS varchar(320)

    - Megnézem az index-eket és az elsődleges kulcsokat, hogy vannak-e:

    EXECUTE sp_helpindex userdata
            - index_name  index_descrtiption                      index_keys
            - ---------------------------------------------------------------------------------------
            - ixuser      nonclustered, unique located on PRIMARY userid
            - ixuserguid  nonclustered, unique located on PRIMARY userguid
            - ixusername  nonclustered, unique located on PRIMARY username

    - Elsődleges kulcs nincs az adott táblához
    - Lementem az Index-ek CREATE SQL szkriptjeit
    - Index mező vagy Elsődleges kulcs törlése (eldobása)

    USE [eloam] GO DROP INDEX [ixuser] ON [dbo].[userdata] GO USE [eloam] GO DROP INDEX [ixuserguid] ON [dbo].[userdata] GO USE [eloam] GO DROP INDEX [ixusername] ON [dbo].[userdata] GO
    - Collation módosítás

    ALTER TABLE userdata ALTER COLUMN prop3 varchar(320) COLLATE Hungarian_CI_AS; GO ALTER TABLE userdata ALTER COLUMN prop5 varchar(320) COLLATE Hungarian_CI_AS; GO ALTER TABLE userdata ALTER COLUMN prop6 varchar(320) COLLATE Hungarian_CI_AS; GO ALTER TABLE userdata ALTER COLUMN prop7 varchar(320) COLLATE Hungarian_CI_AS; GO ALTER TABLE userdata ALTER COLUMN prop8 varchar(320) COLLATE Hungarian_CI_AS; GO
    - Lefuttatom a lementett Index létrehozó CREATE SQL szkripteket
    - Újraindítom a DB-t
    - Létrehozók egy új felhasználót és a prop5 mezőbe beírok egy szervezetet: Jogi főosztály

    Köszönöm a további segítséget előre is.
    Üdv
    Mutasd a teljes hozzászólást!
  • Szia,

    1) Szuper!
    2) Ez érdekes, lásd lentebb.
    3) Szerintem mindent jól csináltál, csak egy valami kimaradt.

    Kicsit utánaolvastam, és a következő lehet a probléma: habár az oszlopaid collation beállítása
    már jó, de mivel az adatabázis még Latin1-es ezért az összes kiadott SQL parancs az adatbázon belül az adatbázis collation-jével fut. (Ezért kaptál eltérő eredményt a tesztekre a 2-es pontban). Tehát hiába adsz ki jó SQL parancsokat, azok Latin1-re konvertálódnak a futtatás pillanatában.

    Szóval az adatbázis collation-t is át kell állítani:

    use master; go alter database eloam COLLATE Hungarian_CI_AS; go use eloam;
    Ezután próbáld meg a felhasználót létrehozni.

    Ha vannak tárolt eljárások és függvények, akkor külön meg kellene nézni, hogy az új adatbázis collation-t átvették-e rendesen (remélhatőleg igen), vagy esetleg újra kell őket kreálni.
    Mutasd a teljes hozzászólást!
  • Szia!

    Köszönöm szépen az utánajárást. Gondoltam én is erre, de van legalább 15 tábla még az adatbázisban. Ez a DB kizárólag a felhasználók adataira van létrehozva.

    Megcsinálom akkor mindre és visszajelzek!

    Üdv.
    Mutasd a teljes hozzászólást!
  • Szia!

    Köszönöm szépen a sok-sok segítséget. Már sikerült az adatbázis collation-t beállítani és működik is, de csak úgy, hogy a 14 táblából 12-ben van index és ebből 2 táblánál van összesen 3 elsődleges kulcs beállítva.

    https://imgur.com/eqQ492m.png

    Az index-eket mindenképpen el kell dobnom ahhoz, hogy a collation-t módosítani tudjam. Az index-ek eldobása után eldobtam az elsődleges kulcsokat is. Azonban amikor újra akarom építeni őket, az hibára fut. Most úgy jó csak, ha az elsődleges kulcsokat nem dobom el és a hozzátartozó mezők collation-jét nem bántom. Pont olyan három mezőről van szó, ahol soha nem lesz ékezetes magyar betű, csak hash azonosítókat tárolnak bennük. Ez azt jelenti, hogy a mostani megoldással a db és az összes karakter típusú mező collation-jét módosítom (kivéve a fent említett három mező). Remélem ez nem okoz gondot a rendszernél, jó sok tesztelést fogok kiosztani az ügyfélnek! :)

    Még egyszer köszönöm szépen a segítséget!
    Üdv.
    Mutasd a teljes hozzászólást!
  • Szia!

    Szívesen, örülök, hogy sikerült működésre bírni.

    Azonban amikor újra akarom építeni őket, az hibára fut.

    Nem írtad milyen hiba, gondolom a jelenlegi tartalommal függ össze, csak tippelni tudok: a Hungarian_CI_AS speciálisan kezel bizonyos karakter sorozatokat. Pl.: az "szsz" és az "ssz" ilyenkor ekvivalens, nem kerülhet be ez a két string ugyanabba az oszlopba egy uniq key esetén.

    Viszont hash kódok tárolására pont ezért nem is használnék nyelvfüggő collation-t, hanem valami alap latin1-et, vagy sima binárist. Szóval szerintem jó leszel.
    Mutasd a teljes hozzászólást!
  • Szia!

    Ez a két hibaüzenet, ami azt jelenit, hogy null korlátozás van az adott mezőn.

    https://imgur.com/oD9nIOU.png
    https://imgur.com/GpNzSjW.png

    Miként lehetne ezt megoldani?

    Üdv.
    Mutasd a teljes hozzászólást!
  • Szia,

    a problémát jól jelzi a hibaüzenet:

    Cannot define PRIMARY KEY on nullable column in table...

    Tehát az oszlop megengedi a NULL értéket, ezért nem lehet rá elsődleges kulcsot létrehozni.

    Ez azért lehet, mert
    - ami index eredetileg rajta volt, az nem primary key volt, hanem pl egy filtered index
    - VAGY az oszlopra futtatott ALTER COLUMN parancsból kimaradt a NOT NULL constraint

    Ha az utóbbi, akkor annyi a dolgod, hogy újra kiadod az oszlopokra az alter column parancsot, de mostmár a "not null"-t is megadod a típus és a collation mellé.
    Mutasd a teljes hozzászólást!
  • Szia!

    Nagyon szépen köszönöm még egyszer, ez is bejött. Így most a teljes ELOAM db magyar lett.

    Üdv. és szép estét!
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd