Avatar billede ae03 Novice
11. oktober 2010 - 11:03 Der er 16 kommentarer og
1 løsning

CAST/CONVERT float til int

Jeg har 4 tabeller med hver 200 - 250 kolonner, hvor jeg ønsker at konvertere de fleste fra float til int. Er der en måde, hvorpå jeg kan konvertere mange navngivne kolonner i en tabel på en gang, så jeg slipper for at skrive en CAST eller CONVERT for hver eneste kolonne. Jeg forestillede mig noget i retning af

ALTER TABLE Tabel1
ALTER COLUMN v1, v2, v3 int.

Det virker ikke, hverken med eller uden kommaer mellem kolonnenavnene. Kan nogen angive en metode?

Vh Lars
Avatar billede hrc Mester
11. oktober 2010 - 14:08 #1
Hvis du alligevel skal ind og vurdere de enkelte felter så kan jeg ikke forstå hvorfor nedenstående ikke er ok? Vis opslag i SysObjects og lignende kan du trække alle float-felter og næsten generere nedenstående automatisk:

SELECT so.NAME AS tablename, sc.name AS fieldname
FROM sysobjects so
JOIN syscolumns sc ON (sc.id = so.id)
WHERE sc.xtype = 62

eller sådan her.

SELECT 'UPDATE ' + so.NAME + ' alter column ' + sc.name + ' int'
FROM sysobjects so
JOIN syscolumns sc ON (sc.id = so.id)
WHERE sc.xtype = 62


Så kan du altid rette det igennem bagefter.
Avatar billede janus_007 Nybegynder
11. oktober 2010 - 14:56 #2
Du kan bruge en cursor :)

Lav en liste over de feltnavne du vi have ændret, brug den som input til cursoren

I dit loop i cursoren skriver du

exec('alter table MyTable alter column ' + @columnname + ' int')
Avatar billede ae03 Novice
11. oktober 2010 - 14:59 #3
Der er vist noget sql-database, hvor min kunnen kommer til kort. Har lige læst lidt om sysobjects, for at forsøge at forstå, hvad du mener.

Jeg kan forså principperne i dit første forslag, som jeg også har eksekveret, uden dog at kunne se, at det har relevans for mit spørgsmål om konvertering af type, da det blot lister alle felter af den pågældende type i alle tabeller. Det sidste kan vel klares ved at specificere de relevante tabeller (so.name=xxx) i tillæg til sc.xtype = 62 i WHERE, men det ændrer stadig ikke på typen.

Dit andet forslag kan jeg ikke helt gennemskue, så jeg tør ikke rigtigt bare at køre det. Kan du give et eksempel på resultatet?

Jeg behøver i øvrigt ikke at skulle ind og se på hver enkelt felt. Jeg ved præcist, hvilke felter (alle undtagen 5-6 i hver tabel), der er hvilken type. Problemet er at få ændret typen uden at skulle til den lange proces med at gøre det manuelt for hver enkelt.
Avatar billede ae03 Novice
11. oktober 2010 - 15:00 #4
cursor??? Det skal jeg vist lige læse på
Avatar billede hrc Mester
11. oktober 2010 - 15:11 #5
ae03: Det var bare en variant af det første script som indsætter tabel- og felt-navn i strengen alter table <navn> alter column <felt> int

Det er altså helt harmløst at køre selecten. Output skal gemmes til fil eller klippebord og afvikle i et SQL-query vindue, når du har sorteret eventuelle uønskede felter fra.

Derefter trykker du F5, hvorefter ting og sager sker.

Som janus skriver, kan det også laves med en cursor, resultatet er nok meget lig det der vil ske ved at køre outputtet fra min anden select-sætning - men som jeg læser det, er det ikke alle felter der skal konverteres.
Avatar billede hrc Mester
11. oktober 2010 - 15:15 #6
I øvrigt er xtypen 62 værdien for en float. Hvis det er en anden type du konverterer fra, så kan du finde den via scriptet

SELECT so.NAME as tablename, sc.name as fieldname
FROM sysobjects so
JOIN syscolumns sc ON (sc.id = so.id)
WHERE (so.name = '<tabelnavn>')
  and (sc.name = '<feltnavn>')
Avatar billede ae03 Novice
11. oktober 2010 - 15:20 #7
Det er ganske rigtigt ikke alle felter, der skal konverteres, men jeg skulle gerne ende med en tabel, som rummer alle de oprindelige felter, blot med en ændring af type på nogle.
Avatar billede ae03 Novice
11. oktober 2010 - 15:25 #8
Tak hrc, nu kan jeg se ideen, men hvorfor virker den ikke, når jeg tilføjer "AND so.name = Tabel1" til WHERE-sætningen?
Avatar billede ae03 Novice
11. oktober 2010 - 15:26 #9
Jeg kan selvfølgeligt klare det med at klippe-klistre de relevante dele af resultatet for hele DB, men det ville nu være lettere at kunne lave select'en for en bestemt tabel
Avatar billede ae03 Novice
11. oktober 2010 - 15:40 #10
Glem #8. Den virker fint, når jeg husker kun at bruge selve tabelnavnet.

En lille finesse mere. Ville nedenstående være den rigtige formulering af SELECT'en, når der også skal en angivelse af schema med?

SELECT 'UPDATE ' + so.scema_name + '.' + so.NAME + ' alter column ' + sc.name + ' int'
Avatar billede ae03 Novice
11. oktober 2010 - 16:04 #11
Glem sidste spm. i #10. Jeg kom uden om det ved at skrive 'ALTER TABLE schema1.' i stedet for 'UPDATE '.

hrc: Gi' et svar, og pointene er dine (trods den lille fejl med UPDATE/ALTER TABLE) ;o)

Tak for hjælpen!
Avatar billede hrc Mester
11. oktober 2010 - 19:17 #12
Arrhh. Det så jeg først nu. Havde endda afprøvet det meste på en database. Selv tak
Avatar billede arne_v Ekspert
11. oktober 2010 - 22:07 #13
I.s.f. at rode rund i sysobject med magiske værdier som 62 vil jeg foreslå:

SELECT TABLE_NAME,COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE DATA_TYPE ='float'
Avatar billede hrc Mester
12. oktober 2010 - 09:01 #14
arne: Jeg overvejede også at lave det med information_schema views, men kunne lettere huske de gamle sysobjects og syscolumns ditto. Kan godt lide at springe abstraktionslaget over og gå (næsten) direkte til meta-kilden.

Din select er noget mere læsbar men skal stadig joines med INFORMATION_SCHEMA.TABLES - og det er helt samme operation:

select t.table_name, c.column_name
from information_schema.tables t
join information_schema.columns c on (c.table_name = t.table_name)
where c.data_type = 'float'

Og ja. SysObjects m.fl. er en SQL 2000 ting, men jeg har ikke set at de udfases til fordel for information_schemas.
Avatar billede ae03 Novice
12. oktober 2010 - 09:36 #15
hrc: hvorfor er den join i Arnes forslag nødvendig. Så vidt jeg kan se, står alle relevante informationer til dannelse af de benyttede alter table selects i INFORMATION_SCHEMA.COLUMNS. Eller er der noget, jeg har misforstået?

Tak for forslaget, Arne. Det vil jeg huske til en anden god gang, da det vist er mere tilgængeligt end hrc's forslag. Men da jeg har løst opgaven med hrc's løsning, giver jeg pointene til ham.

Tak til begge for forslag, som har fået mig ind i System Views mappen, hvor der helt tydeligt er mange gode tabeller at benytte. Jeg skal vist prioritere tid til at snuse lidt mere rundt, frem for kun at løse mine opgaver. Den tid er vist godt givet ud på lidt længere sigt.
Avatar billede hrc Mester
12. oktober 2010 - 09:51 #16
hrc (og arne): Du (I) har ret. Jeg er så fokuseret på numeriske fremmednøgler, at jeg ikke fattede betydningen af table_name i columns.
Avatar billede hrc Mester
12. oktober 2010 - 09:52 #17
"ae03", ikke "hrc"!!!
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester