Konverze datových typů   zodpovězená otázka

Databáze

Ahoj, potřeboval bych poradit s konverzí datových typů na SQL serveru 2000. jde o to že mám sloupec s hodnotou nvarchar(20) a potřebuju ho přeměnit na money. Je mi jasné že to není standartní konverze která vždy projde. Právě naopak. Když se pokusím o konverzi vyskočí nějáká všeobecná chyba že tuto konverzi nelze provést. Zkoušel jsem nejdříve konverzi na float, ale tam mě hláška upozorní že ne všechna data lze převést. A já bych právě potřeboval něják nastavit, aby mi to vypsalo čísla řádků, nebo id u položek které není možné konvertovat. Stejně jako to dělá například MS access při importu dat, pokud je někde zadán neodpovídající datový typ.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jenom bych ještě dodal že to je jednorázová akce. Tzn. pouze předělávám starší verzi aplikace na novou a potřebuji aby v nové verzi zůstala všechna data. Takže až nacpu data do nové tabulky, budou se položky standartně ukládat jako Money.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No, záleží v jakém formátu ta měna je, pokud je to třeba ve formátu 123,45 Kč, tak bude asi nejlepší nějakou stringovou funkcí odříznout to , převést desetinnou čárku na desetinnou tečku (na to tam taky bude určitě nějaká funkce) a pak už to na money snad zkonvertujete. Jaký je přesně formát té měny?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Je to standartní číslo s desetinnou čárkou. Desetinná místa nejsou u všech položek. Tam kde bylo 0 haléřů desetinná čísla nejsou. Problém je že nebylo ošetřeno aby šla vložit pouze čísla a záznamů je poměrně hodně. Takže potřebuji zjistit kde je něco jiného než číslo abych takový záznam ručně opravil (takových záznamů bude jenom pár).

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nejsem DB odborník, určitě to půjde i jinak, ale když ten převáděcí skript dáte do bloku TRY..CATCH, zastaví se na řádku, kde došlo k chybě. Pokud dojde k chybě, asi se změny v předešlých řádcích neuloží, to nevím, ale každopádně když si z tabulky vyberete ID a tu měnu převedenou na money, tak se skript zastaví před prvním chybovým řádkem. Ten můžete opravit ručně a pak skript pustit znovu atd.

begin try
  select id, convert(money, cena) from t
end try
begin catch
  print 'chyba'
end catch

Když to pustíte v Server Management Studiu, tak se vám zobrazí jednak převedené řádky, tak i zpráva "chyba", když se nějaký řádek převést nepodařilo. Pokud se zpráva "chyba" nezobrazí, pak už jsou všechny řádky v pořádku.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Bohužel toto mi nefunguje. Trošku jsem hledal a zjistil jsem, že použití bloku TRY-CATCH je implementováno až od SQL server 2005. Já bohužel pracuji s verzí 2000.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No, to je tedy hezké. Zkusím dál pátrat.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Taky zkouším googlit ale bohužel většina návodů je pouze pro SQL server 2005.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak jsem se rozhodl si udělat "udělátko" ve VB. Funguje jednoduše. Mám 2 datagridviewy. Do jednoho načtu tabulku z DB a zadám číslo sloupce u kterého chci zjistit zda jde zkonvertovat na float.Spustím ověřování které dělá to, že ze zadaného sloupce bere jednu položku po druhé a zkouší ji parsnout na typ double. Pokud to nejde vypíše se id položky a špatná hodnota do 2 datagridviewu. Zde stačí pouze kliknout na položku kterou chci opravit, do inputboxu zadám novou hodnotu a po potvrzení se provede update v tabulce. Ale někde je chyba. Myslel jsem si že to co se mi podaří parsnout na typ Double ve VB půjde překonvertovat na typ Float v DB. Aplikace mi ale už žádné chyby nevyhazuje ale sloupec převést nejde:( Pokud se mi to podaří vychytat, upravil bych trochu uživatelské prostředí a pokud by byl zájem dám k dispozici zdrojový kód.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

A nezáleží na tom, jestli je použita desetinná čárka, nebo tečka? Jedna z nich asi v DB převést nepůjde, .NET třeba skousne obě varianty.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To už mě také napadlo, .net mi neskousne desetinnou tečku. To jsem opravil ale nemopohlo mi to. Je mi ale divné že v té samé db jenom v jiné tabulce mám desetinné čárky a funguje to. Dá se někde ve vlastnostech VB projektu (případně kódem) nastavit jestli aplikace má používat desetinnou čárku nebo tečku? Zkusil bych to projet ještě jednou.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

On si ten separátor bere z místního nastavení operačního systému. Pokud je to jednorázová aplikace, doporučuji ve VB.NET vybrat selectem všechny záznamy, vytáhnout si ono desetinné číslo, funkcí Replace z něj vyházet všechny mezery, desetinnou tečku nahradit za desetinnou čárku, a pomocí Double.TryParse zjistit, jestli se to na Double dá nebo nedá převést. A pro každý řádek vygenerovat už rovnou INSERT příkaz pro novou databázi, celé to ukládat do nějakého souboru. Pak už vygenerovaný skript jen spustíte na nové DB a máte vystaráno. Pokud je to navázáno na nějaké další tabulky, doporučuji dočasně vypnout constrainty a aby šly vkládat ID záznamů, před samotnými inserty spustit set identity_insert tabulka on resp. off po nich, kde tabulka je název tabulky, do které vkládáte.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Takže jsem to vyřešil tak, že jsem si v místním nastavení ručně nastavil jako oddělovač desetinných míst tečku, takže v aplikace mi už vyhodila chybové řádky tak jak jsem potřeboval. Pomocí funkce replace (mimochodem děkuji že jste mi jí poradil, doteď jsem nepotřeboval moc s řetězci pracovat takže jsem ji neznal) prošel v cyklu chybové řádky, nahradil čárku za tečku (pro širší použití uživatel může nastavit co hledat a na co to změnit) a rovnou udělal update v databázi. A už není problém s převodem:)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Hledal jsem na netu řešení obdobného problému a narazil jsem na tuto diskuzi, ale potřeboval jsem to řešit trochu obecněji.

Takže možná někomu pomůže tento příspěvek.

Funkce Cdbl při konverzi ze stringu reflektuje místní nastavení systému a tedy za oddělovač desetinného místa považuje v českém (německém,...) prostření čárku, v anglickém (,...) tečku, v řeckém apostrof.

Jaký je v místním nastavení použit oddělovač lze pomocí System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.

Kdesi na netu jsem narazil na příklad, kde hodnotu této property nastavují, mě VB.NET tvrdí, že je ReadOnly (Možná je to tím, že to zkouším ve VS2003 a navíc v compact frameworku).

Pakliže tedy není možné oddělovač nastavit, nezbývá, než se s tím smířit a podle toho se zařídit.

V rámci jedné aplikace mi to stačí a podle aktuálního nastavení se zařídím. Pokud ovšem mám aplikaci, které (např.) přijdou data po Tcp protokolu a já dopředu nevím, s jakým desetinným oddělovačem, vytvořím si funkci, která v příchozím stringu nahradí tečky a čárky (případně další znaky, pokud budu chtít počítat s oddělovači jinými (například řeckým apostrofem:-)). A až pak string převede na Double.


dim DesetinaTeckaCarkaZMistnihoNastaveni as String = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator

Private Function CdblKaslatNaSeparator(ByVal vstup As String) As Double

Return CDbl(vstup.Replace(",", DesetinaTeckaCarkaZMistnihoNastaveni).Replace(".", DesetinaTeckaCarkaZMistnihoNastaveni))

End Function

A pak budu všude požívat místo Cdbl funkci CdblKaslatNaSeparator

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Ahoj, potřeboval bych poradit ohledně visual basicu. Programuji různý výpočty ,jehož výsledky jsou v desetinném provedení, ale visual basic mi vyplivne 8,3333333E-02 místo 0,08333333333.Děkuji za odpověď

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback