13. januar 2005 - 12:13Der er
17 kommentarer og 1 løsning
Trigger for Unicode data
Hejsa,
Har en tabel, der gemmer Unicode data. Kolonnen er selvfølgelig oprettet som en ntext. Derfor skal man indsætte med N-prefixet, ie. INSERT INTO test (data) VALUES ( N'Αποστολή')
Mit problem er dog, at data indsættes via et program, som jeg ikke kan rette i, og det bruger ikke N-prefikset. Det betyder, at data ikke bliver unicode-formatteret, og derfor til tider er ulæselig.
Nogen der har nogen idéer til, hvordan dette kan løses ?
Jeg prøvede selv med at oprette en insteadof-trigger, der kørte på insert/update. Idéen var, at triggeren skulle tilføje N-prefixet. Problemet er dog, at jeg ikke kan konkatenere en ntext - og i øvrigt ikke har nogen datatyper til rådighed i en trigger, der kan holde ntext værdien..
Så nu er jeg gået lidt i stå - kan du hjælpe mig ??
En trigger kan slet ikke se ntext, text og image felter - så det er som du har opdaget ikke løsningen.
Du kan prøve at omdøbe tabellen og så lave et view ovenpå den omdøbte tabel. Viewet får så navnet på den oprindelige tabel.
I viewet må du så lege med typekonvertering til/fra Ntext - jeg kan umiddelbart ikke huske om du kan sætte collation på et view, men det er noget du må afprøve.
Hm.. så vidt jeg forstår (se nedenstående) har collation ikke noget med det her at gøre (?)
All Unicode data uses the same Unicode code page. Collations do not control the code page used for Unicode columns, only attributes such as comparison rules and case sensitivity.
Har heller ikke kunne generere en SECLET-statement, der fik data korrekt ud - hvis bare det var så let :-)
Det program som indsætter og ikke bruger N - hvordan skal det kunne indsætte non-ISO-8859-1 tegn ? Og hvis det kun indsætter ISO-8859-1 hvorfor så NTEXT ?
Programmet indsætter unicode text i en ntext kolonne - spørg mig ikke, hvorfor de ikke har medtaget N'et da de kodede sql'en .. sikkert en forglemmelse - det er et amerikansk produkt :)
Altså de indsætter f.eks. en streng 'ABCD' i.s.f. N'ABCD' og det bliver til "\u4142\u4344" i databasen fremfor det korrekte "\u0041\u0042\u0043\u0044" ?
Det er jo nemt at håndtere i et periodisk konverterings job (C++/Java/C#/whatever).
Men real time er den nok ond. Som jeg har forstået det vil det i SQLServer 2005 være nemt at skrive sådan noget kode i C#. Men i 2000 har jeg svært ved at se mulighederne.
arne_v: Jeg kan ikke lige overskue dine \u-strenge, men det er sikkert det, der sker. Jeg kan se, at den anvendte sql-insert ikke har N-prefixet. Og jeg kan ikke finde nogen måde at select'e data så det bliver korrekt. Jeg har svært ved at se, hvordan et eksternt job skulle løse problemet - måske har jeg misforstået noget, men jeg troede bare, at der gik noget tegn-information tabt, når man gemte det i alm. 8byte ? Hvis man kan lave et batch job i C# eller noget andet er jeg også åben over for det - men det kræver jo, at vi kan lave en sql-select :)
Hvis man hypotese er korrekt så kan man lave en SELECT ind i en C# string (som er unicode) og for hver enkelt char i den string lave 2 nye chars og appende til en ny string som så skulle være læsbar.
Collation har ikke betydning for rene unicode data - men kommer ind i det når du skal konvertere fra text til ntext (ansi -> unicode) men prøv blot at at definere viewet således
1. opdøb din tabel "mytable" til "mytable_org"
2. lav et view som følger:
create view dbo.mytable as select cast(X as text) as x, ,,,, // alle kolonnenavne her from dbo.mytable_org go
create table test (data ntext) insert into test (data) values ('Περισσότερες') select data from test select cast(data as ntext) as data from test
Det giver følgende resultat: data -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ?e??ss?te?e?
ie. jeg kan ikke få data ud med et alm. select statement.
Så til arne_v: Jeg har svært ved at se, hvordan C# skal kunne hjælpe mig, hvis mit sql-statement ikke returnerer data korrekt.. men ok, det er et forsøg værd. Jeg har prøvet at lave et lille C# program, der udskriver data på skærmen - men desværre giver det samme resultat - der udskrives "?e??ss?te?e?" ..
Det havde virket, hvis der havde stået N' foran den indsatte streng med græske bogstaver - men den SQL kan jeg som sagt ikke ændre - så hvad gør jeg ?
Tak arne_v, men det virker ikke :-( Jeg kan godt se, at dit eksempel virker - og det virker også hos mig - men når jeg bruger min streng fra databasen i stedet for s, så virker det ikke..
Hej igen - tror efterhånden jeg nærmer mig målet, idet jeg alligevel er gået tilbage til trigger-løsningen.. denne test virker:
---------------- create table test (data ntext) go
create trigger test_unicode on test instead of insert as begin create table #tmp (data nvarchar(4000))
declare @i int set @i=1
declare @len int select @len=datalength(data) from inserted
insert into #tmp (data) values ('')
while @i < @len begin update #tmp set #tmp.data = #tmp.data + isnull(nchar( unicode( substring(inserted.data, @i, 1)) ), ' ') from inserted
set @i=@i+1 end
insert into test (data) select data from #tmp
drop table #tmp end go
insert into test (data) values ('planétaire français Chaussée l’existence d‘un marées dégâts étonnant océans' )
select data from test ---------------
ie. trer: man kan godt bruge ntext/text/osv kolonner i instead-of-triggers.
Mit store problem er dog nu, at tabellen har en identity column, hvilket jeg er nødt til at vedligeholde manuelt fordi jeg bruger en instead-of-trigger. Nogen der har andre idéer til, hvordan dette kunne gøres ?
arne_v: Jeg er i tvivl om, hvordan jeg præcis konverterer til hex - men har brugt følgende algoritme: checked((uint)System.Convert.ToUInt32(s[i])) Dermed bliver fx det bogstav, der skulle have været À (fransk stort A med ecu) til € (euro-tegn) med værdien 8364.
Thja - jeg var for hurtig, checkede lige books online:
"SQL Server 2000 does not allow text, ntext, or image column references in the inserted and deleted tables for AFTER triggers; however, these column references are allowed for INSTEAD OF triggers. For more information, see CREATE TRIGGER."
Men min tanke var mere denne:
create table test_org (data ntext) create view test as select cast(data as ntext) as data from test_org insert into test (data) values ('Περισσότερες') select data from test
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.