«« ( Date ) »» // «« ( Thread ) »» // nastava - 2004

Re: java + sql server + yu latinica

by Andrija Kovacevic
utorak, 07. septembar 2004 - 22:17.


M> Nikako ne mogu da upisem slova srpske latinice iz JSP stranica u SQL Server 2000.
M>  
M> Medjutim, problem nije u SQL Serveru, vec u JSP-u. To znam zato
M> sto kada upisujem stringove u bazu iz Query Analyzer-a sve
M> funkcionise. Kada upisujem iz JSP-a, u bazi se pojavljuju ili
M> znakovi pitanja ili neki nepoznati karakteri.
M>  
M> Pokusavao sam sa svim mogucim podesavanjima kodnih strana,
M> podesavanjima u Regional Settings, ali nista. Probao sam, naravno,
M> i da upisujem stringove izmedju N' i ' jer se tako upisuju Unicode
M> znakovi u SQL Server.
M>  
M> Ne pomaze mi nista da u bazi cuvam nerazumljive kodove
M> karaktera, pa a ih citam iz JSP aplikacije. Neophodno je da podaci
M> u bazi budu citljivi.
M>  
M> Jel imao neko slican problem? Svaka pomoc je dobrodosla.

Rešenje ti je da web aplikacija i baza komuniciraju korišćenjem kodova
karaktera, a da se u samoj bazi čuvaju podaci koji su čitljivi.

Za upis u bazu procedura je sledeća:

Na nivou web aplikacije u klasi za pristup bazi napraviš metod
koji pretvara tekst u string sastavljen od unikod kodova karaktera,
gde su pojedinačni karakteri razdvojeni nekim specijalnim znakom
(recimo #)

U bazi napraviš korisničku funkciju koja od takvog stringa restaurira
originalni tekst.

Naravno, da bi ovo radilo potrebno je da izoluješ sve pristupe bazi
preko ugrađenih procedura koje se pozivaju iz web aplikacije (znači
nema direktog pisanja SQL query-je u web aplikaciji).

Za čitanje iz baze je slično samo što sada imaš korisničku funkciju
koja od teksta iz baze generiše string sa unikod kodovima u obliku
koji mogu da se direktno prikažu u html-u (&#kod;). U ovom slučaju ti
na nivou web aplikacije ne treba ništa.

I naravno, sva polja u bazi sa kojima operišeš na ovakav način moraju
da budu nvarchar.

Evo ti i kod za ovo:
-- Čitanje iz baze
CREATE FUNCTION [dbo].[fnGetUnicode] (@NString as nvarchar(50))
RETURNS varchar(500)
AS
BEGIN

DECLARE @position int
DECLARE @Final varchar(500)

SELECT @Final = ''
SELECT @position = 1

WHILE @position <= DATALENGTH(@NString)
BEGIN
IF (CONVERT(varchar,UNICODE(SUBSTRING(@NString, @position, 1))) <> '')
SELECT @Final = @Final + '&#' + CONVERT(varchar,UNICODE(SUBSTRING(@NString, @position, 1))) +';'
SELECT @position = @position + 1
END

RETURN @Final

END

-- Upis u bazu
CREATE FUNCTION [dbo].[fnSetUnicode] (@NString as varchar(500))
RETURNS nvarchar(50)
AS
BEGIN

DECLARE @position int
DECLARE @Temp varchar(5)
DECLARE @TempInt int
DECLARE @Final nvarchar(50)

SELECT @Final = ''
SELECT @position = 1

WHILE @position <= DATALENGTH(@NString)
BEGIN
SELECT @Temp = ''
WHILE (SUBSTRING(@NString, @position, 1) <> '#')
BEGIN
SELECT @Temp = @Temp + SUBSTRING(@NString, @position, 1)
SELECT @position = @position + 1
END
SELECT @position = @position + 1
SELECT @TempInt = CONVERT(int, @Temp)
SELECT @Final = @Final + CONVERT(nvarchar,NCHAR(@TempInt))
END

RETURN @Final

END

U mom slučaju je web aplikacije rađena u php-u, ali pretpostavljam da
ti neće biti problem da kod prevedeš na jsp

function utf8_to_entities($str){
$unicode = array();
$values = array();
$lookingFor = 1;

for ($i = 0; $i < strlen($str); $i++) {
$thisValue = ord($str[$i]);
if ($thisValue < 128)
$unicode[] = $thisValue;
else {
if (count($values) == 0)
$lookingFor = ($thisValue < 224) ? 2 : 3;
$values[] = $thisValue;
if (count($values) == $lookingFor) {
$number = ($lookingFor == 3) ?
(($values[0]%16)*4096)+(($values[1]%64)*64)+($values[2]%64):
(($values[0]%32)*64)+($values[1]%64);

$unicode[] = $number;
$values = array();
$lookingFor = 1;
}
}
}

$entities = '';
foreach( $unicode as $value ) $entities .= $value. '#';
return $entities;
}

Ovo rešenje radi nezavisno od jezičkog podešavanja klijentskog
računara.


--
Pozdrav,
Andrija