Autor | Zpráva | ||
---|---|---|---|
maycza Profil |
#1 · Zasláno: 22. 5. 2015, 12:22:58
Ahojte,
rovnou uvedu příklad, mám tabulku CREATE TABLE dbo.dodavatele ( id int NOT NULL, nazev nvarchar(80) NULL, PRIMARY KEY (id) ); Tabulka má nastavenou collation na Czech_100_CI_AI. Potřebuji do tabulky vkládat kromě českých znaků i azbuku. Česky to všechno funguje, ale.. 1) pokud vložím do tabulky nový záznam přes MSSQL Server manager pomocí editování řádků napsaný azbukou, všechno v pořádku, záznam se uloží tak jak jsem ho zadal 2) pokud vložím do tabulky nový záznam v MSSQL SM pomocí dotazu INSERT INTO dbo.dodavatele (nazev)VALUES(N'Москва') - vše ok (i když nepoužiju "N" před vkládanými daty
3) když vkládám záznam pomocí php, nastává problém. V souboru vloz.php uloženém v kódování windows-1250 mám úplně stejný dotaz jako v bodu 2), je jedno jestli použiju N pro unikód nebo ne, do databáze se uloží "?????? ". Co se stane když změním kódování na utf-8 asi psát nemusím...
Když nechám uložená data vypsat na stránce vypis.php , kódování windows-1250 , vylezou z toho vždycky otazníky.
Nevíte někdo, kde dělám chybu? |
||
Alphard Profil |
#2 · Zasláno: 22. 5. 2015, 12:45:14
maycza:
„Když nechám uložená data vypsat na stránce vypis.php , kódování windows-1250 , vylezou z toho vždycky otazníky.“
To ale v každém případě, ať tam ty data vložíte jakkoliv, ne? cp1250 neobsahuje znaky azbuky, viz např. cs.wikipedia.org/wiki/Windows-1250#K.C3.B3dov.C3.A1_tabulka. Použijte jiné kódování, nebo převod na entity. |
||
maycza Profil |
#3 · Zasláno: 22. 5. 2015, 13:45:02
Ano s tím výpisem je to stejné pro všechny.
Nevíte jaké kódování se dá použít, aby to sežvýkala databáze i stránka? Myslím, že použití entit mi také nepomůže pokud budu používat na stránce cp1250.. Když použiju utf8 tak se mi to zase blbě uloží v databázi.. |
||
juriad Profil |
#4 · Zasláno: 22. 5. 2015, 13:57:42
maycza:
Máš nějaký důvod nepoužít úplně všude (tedy na stránce, ve skriptech i v databázi) UTF-8? |
||
maycza Profil |
#5 · Zasláno: 22. 5. 2015, 14:03:03
No právě jenom jeden, nějak mi uniká, která collation v MSSQL je ekvivalentem k UTF-8.. používám MSSQL server 2012
|
||
juriad Profil |
#6 · Zasláno: 22. 5. 2015, 14:11:03
maycza:
Collation říká jen jakým způsobem se porovnávají znaky *, nikoli jak jsou uložené. Stačí ti, když máš sloupce typu NVARCHAR. * například, zda jsou znaky shodné, po nějaké normalizaci (velikost písmen, diakritika, různé zápisy stejného znaku). |
||
Joker Profil |
#7 · Zasláno: 22. 5. 2015, 14:12:14
maycza:
Pokud vím, MS SQL Server nemá unicode na úrovni porovánání, ale použije se jiný datový typ. CHAR, VARCHAR a TEXT jsou ne-unicode, NCHAR, NVARCHAR a NTEXT jsou unicode. |
||
maycza Profil |
#8 · Zasláno: 22. 5. 2015, 14:29:12
Jj, to je pravda. Když se mrknete na ten úplně první příspěvek, tak vidíte, že jsem si vytvořil sloupec
název , který je typu nvarchar o délce 50 znaků, tzn. unicode. Proč se mi tedy do databáze uloží nesmyly, když mám stránku uloženou v UTF-8 a nastaveno <meta charset="utf-8" /> . Když nechám vypsat obsah tabulky, tak se mi ty nesmysly i zobrazí.
|
||
_es Profil |
#9 · Zasláno: 22. 5. 2015, 14:34:40
maycza:
„Proč se mi tedy do databáze uloží nesmyly, když mám stránku uloženou v UTF-8 a nastaveno <meta charset="utf-8" />“ Veď ale sám píšeš, že problém nastáva pri neprávom nastavení kódovania na windows-1250 cez PHP.
|
||
maycza Profil |
#10 · Zasláno: 22. 5. 2015, 14:38:20
_es:
to se omlouvám, zapomněl jsem dodat, že jsem to všechno změnil pro UTF-8.. a stejně to nepomáhá. |
||
_es Profil |
#11 · Zasláno: 22. 5. 2015, 14:44:50
maycza:
No dobre „vkladáš v PHP“ ale ako konkrétne? To popíš, aby ti mohol poradiť niekto, kto vie správne skombinovať PHP s MSSQL a UTF-8. |
||
maycza Profil |
#12 · Zasláno: 22. 5. 2015, 14:50:00 · Upravil/a: maycza
_es:
dotaz je úplně na začátku, v php to vypadá tedy takto: $dotaz="INSERT INTO dbo.dodavatele (nazev)VALUES(N'Москва')"; $proved=odbc_exec($dbcon,$dotaz); ještě ať to máte úplné: $dbcon = odbc_pconnect('Driver=TDS;Server=nazev_serveru;', 'username', 'password'); |
||
_es Profil |
#13 · Zasláno: 22. 5. 2015, 15:03:06
[#12] maycza:
Myslím, že problém je jednoducho v tom, že časť dotazu v ruštine Москва sa do databázy odosiela zle. Termín Unicode neznamená to isté ako UTF-8.
|
||
maycza Profil |
_es:
nemůže být ještě něco špatně třeba s tím ODBC driverem..? Ono to není totiž úplně dokonalé ani s tou češtinou. Když mám například sloupec "poznamky" typu nvarchar(255) , uložím do něj řetězec obsahující diakritiku, tak to do databáze uloží např. místo ě písmeno í (s obráceonu čárkou) atd.
Při výpisu na stránku se znaky zobrazují tak jak mají. |
||
_es Profil |
#15 · Zasláno: 23. 5. 2015, 07:46:34
maycza:
„tak to do databáze uloží např. místo ě písmeno í (s obráceonu čárkou) atd.“ No veď to tvrdím, že sa textové reťazce neposielajú správne. Tak skús si to naštudovať v nejakej dokumentácii k MSSQL ako to má byť. Takto „naslepo“ to skúšať nie je asi dobrý nápad. Asi tu veľa diskutujúcich nepoužíva takú kombináciu databázového servera, PHP, znakovej sady a kódovania. MS tuším pod „Unicode“ rozumie často nejaké 16bitové kódovanie Unicode. Aj ODBC ovládač má nejaké svoje vlastné nastavenia - skús pozrieť aj tam. Musí byť vzájomne zosúladené: ukladanie znakov v databáze, to aby databázový server so znakmi pracoval správne, výstup z databázy aj vstup do nej. |
||
tomix Profil |
_es:
Unicode je v rámci MS SQL spoločný názov pre formáty ako je UTF-8, UTF-16, UTF-32, UCS-2. Zial, UTF-8 má mizernú podporu a preferuje sa konveria do UTF-16 respektive co som teraz pozrel na UCS-2 Co sa týka nastavení pre ODBC, tak nejaké extra zvláštne nastavenia nepomôžu, pretože úloha ODBC je iba zabezpečiť konektivitu medzi medzi klientom a servrom (pokiaľ si to aplikácia vyžaduje). maycza: Pre radenie znakov v azbuke doporučujem pre tabulku alebo tabuľky koláciu Cyrillic_General_CI_AS , pre server nechaj Czech_100_CI_AI alebo zmen to na SQL_Czech_CP1250_CI_AS. |
||
maycza Profil |
#17 · Zasláno: 23. 5. 2015, 20:19:33
tomix:
ono o to řazení ani tak moc nejde i když je to taky potřeba.. mě jde hlavně o to zapsat data do db ve správném tvaru a pak je i ve správném tvaru vypsat. Ale to co píšete vyzkoušet můžu, nic lepšího zatím nemám |
||
Časová prodleva: 3 dny
|
|||
maycza Profil |
#18 · Zasláno: 26. 5. 2015, 08:32:51
Pokud by to někoho ještě zajímalo, tak v MSSQL jsem nastavil kódování SQL_Latin1_General_CP1_CI_AS (default), php skripty jsem uložit v utf-8 a výsledek je následující:
- přes <form> zadáno "Москва" (uloženo pomocí odbc_exec($dbcon,"INSERT INTO dbo.dodavatele (nazev)VALUES(N'Москва')") ) -> v db uloženo "МоÑква" -> při výpisu dat na stránku se zobrazí "Москва" (takže to co jsem zadal)
- přes SSMS zadáno INSERT INTO dbo.dodavatele (nazev)VALUES(N'Москва') -> v db uloženo "Москва" -> při výpisu na stránku zobrazeno "??????"
Možná bude nakonec nejjednodušší ukládat ruské názvy do zvláštní tabulky s nastavením collation na Cyrillic_General_CI_AS a svázat to přes id_dodavatele... |
||
Joker Profil |
#19 · Zasláno: 26. 5. 2015, 09:19:41
maycza:
„v db uloženo "Москва" -> při výpisu na stránku zobrazeno "??????"“ To už bude problém kódování na výstupu, řekl bych. |
||
_es Profil |
maycza:
Jednoducho si stále neprišiel na to, ako správe skombinovať PHP a databázový server aby správne pracovali so znakovou sadou Unicode. Z ďalších možností: môžeš spraviť stránku aj v iných kódovaniach podporujúcich Unicode než UTF-8, napríklad spomínané UTF-16 či UCS-2. |
||
maycza Profil |
#21 · Zasláno: 27. 5. 2015, 08:45:51
Ještě se zkusím zeptat jinak. Používal nebo používá někdo z Vás tuto kombinaci? PHP na Linuxu + MSSQL na windows? Nemůže být právě toto kámen úrazu? Nestačilo by rozjet php na IIS?
|
||
Alphard Profil |
#22 · Zasláno: 27. 5. 2015, 10:31:45
Vrátím se ještě k [#18] maycza. Ten první případ bohužel vůbec neznamená, že už to funguje. Vy jste databázi poslal nějakou sekvenci bajtů a ona vám ji beze změny vrací. Když je daná sekvence bajtů interpretována na té stránce, kde byla zadána, zobrazí se vše v pořádku, ale nějaký admin pracující s jiným kódováním to pochopitelně zobrazí špatně.
Druhý případ to jen dokazuje. Na stránce stackoverflow.com/a/9259763 doporučují ini_set('mssql.charset', 'UTF-8') |
||
maycza Profil |
#23 · Zasláno: 27. 5. 2015, 12:11:10
Alphard:
k tomu příspěvku [18] - já jsem netvrdil, že to funguje, jen jsem chtěl ukázat, že se alespoň vložený text zobrazí tak jak má. Samozřejmě je to k ničemu... Jinak ini_set('mssql.charset', 'UTF-8') jsem už také zkoušel, ale nic se nezměnilo, jen si nejsem jistý jaké kódování při tom používat v html kódu tak jsem pro jistotu zkusil jak windows-1250 tak utf-8 (i když to by mělo být podle mě nastaveno na windows-1250). Zkoušel jsem i tohle:
$dbcon = odbc_pconnect('Driver=TDS;Server=nazev_serveru;Client_CSet=UTF-8', 'username', 'password'); |
||
Alphard Profil |
#24 · Zasláno: 27. 5. 2015, 12:39:36
maycza:
„i když to by mělo být podle mě nastaveno na windows-1250“ Co vás k tomu vede k myšlence deklarovat cp1250, když na serveru používáte utf8? Určitě ne, jak jsem uváděl v [#2] Alphard, cp1250 neobsahuje znaky azbuky (tyto rodiny znakových sad (u nás iso-8859-2 a cp1250) jsou kódovány 8bitově s velmi omezeným rozsahem znaků, proto je pro každý region určena jiná sada). V souladu s [#20] _es lze použít utf-8, utf-16, UCS-2 (což je myslím interní kódování v MSSQL),... „Myslím, že použití entit mi také nepomůže pokud budu používat na stránce cp1250.. Když použiju utf8 tak se mi to zase blbě uloží v databázi..“ To si opět myslíte špatně. Entity pomohou, díky nim lze třeba na tuto diskuse psát Москва, i když je stránka kódována v iso-8859-2 (které znaky azbuky taktéž neobsahuje). Myslím, že by to mělo jít nastavit a že třeba někde děláte jen drobnou chybu, ale přes diskusi nedokáži poradit víc. |
||
maycza Profil |
#25 · Zasláno: 27. 5. 2015, 13:41:26
Alphard:
no, říkal jsem si když mám všude nastaveno utf-8, proč používat převod na utf-8... ale protože jsem si tím právě nebyl jistý tak jsem zkusil obě varianty. S těmi entitami jsem to psal proto, protože mi příkaz htmlentities() ani htmlspecialchars() nepřevede azbuku na číselné entity a převodní tabulka ve windows1250 je pitomost právě z důvodu, který uvádíte v příspěvku [#2].
Všude teď používám kódování utf-8, v db používám Latin1_General_CP1_CI_AS, azbuku převádím na číselné entity a ukládám do databáze. Jen jsem musel rozšířit rozsah sloupce "nazev". |
||
_es Profil |
#26 · Zasláno: 27. 5. 2015, 14:24:28
maycza:
Používať UTF-8 a súčasne entity značne stráca zmysel, keďže v UTF-8 sa tie znaky dajú zapísať „priamo“. Zdá sa mi, že nemáš dostatočný prehľad o tom, čo je znaková sada a čo kódovanie znakovej sady. Preto len naslepo skúšaš rôzne kombinácie, či to náhodou nezačne správne fungovať. Ako písal Alphard, nejako by to asi nastaviť malo ísť. Ak sa to nepodarí rozbehnúť v UTF-8, môžeš použiť aj UCS-2, v čom by to malo ísť, ak to je vraj interné kódovanie databázy. |
||
Časová prodleva: 7 dní
|
|||
maycza Profil |
Tak problém vyřešen.
Rozjel jsem php na IIS7, nainstaloval ovladač ODBC Driver 11 for SQL Server, do php extensions jsem přidal sqlsrv (v php.ini přidal řádek extension=php_sqlsrv_56_nts.dll ).
Připojení: $connectionInfo = array('UID'=>'username', 'PWD'=>'pwd', 'Database'=>'jmeno_databaze', 'CharacterSet' => 'UTF-8'); $conn = sqlsrv_connect('server', $connectionInfo); if ($conn === false) die( print_r( sqlsrv_errors() ) ); <meta charset="utf-8" /> .
V db používám collation Latin1_General_CI_AI. Vše se ukládá a zobrazuje tak jak má. |
||
Časová prodleva: 10 let
|
0