Avatar billede puppetmaster Nybegynder
03. marts 2005 - 14:51 Der er 11 kommentarer og
1 løsning

Konvertere 'brugerdefineret' til tidsformat

Jeg er ved at overføre nogle data fra et Excel regneark til SQL Server, men er stødt ind i et problem med datoer/tidspunkter.
I regnearket er der f.eks. indtastet
12 15 (som er et tidspunkt, selvfølgelig) i en celle som er formateret som Brugerdefineret (00 00)
Dette tidspunkt vil jeg gerne have overført til SQL Server som et "rigtigt" tidspunkt (vha. min DTS pakke), men hvordan?
Det kan desværre komme på tale at ændre formatet på regnearket, og jeg har forsøgt forskellige datatyper på feltet i tabellen. What to do...?
Avatar billede ldanielsen Nybegynder
03. marts 2005 - 15:03 #1
Jeg ville lave en ekstra kolonne i tabellen hvor jeg gemmer tidspunktet som tekst. Derefter vil jeg køre en SQL der henter den tekst ud, behandler den og inserter den i den rigtige kolonne
Avatar billede puppetmaster Nybegynder
03. marts 2005 - 15:04 #2
:(
Avatar billede janus_007 Nybegynder
03. marts 2005 - 18:17 #3
Der findes desværre ikke nogen variabel type i sql der hedder time (der må du vente til 2005), det angives som datetime.

Hvis du har en dato i dit Excel ark også, så begynder det at hjælpe på det :O)

Må jeg spørge om hvad du vil opnå ved lige akkurat at opbevare et tidspunkt som time? Skal det forsåes som et interval eller er det bare et tidspunkt på en relativ dag?
Avatar billede ldanielsen Nybegynder
03. marts 2005 - 22:36 #4
Det ville jeg løse ved at lave alle tidspunkter på den samme dag, 1/1 2000 for eksempel. Hvis det kun er klokkeslættet der skal bruges, så er det jo ligegyldigt hvilken dato det er, men det er erimod måske vigtigt at kl 16 er senere end klokken 15.30. så hvis data skal sorteres efter klokkeslæt vil det være en god ide at alle er på samme dato. i sql kan det for eksempel gøres sådan:

Lad os sige at der i kolonnen strTid er tekststrenge, fx. "21 45", og en smalldatetime der hedder dtmTid der skal udfyldes, og vi vedtager at der er NULL i dtmTid for de poster hvor datoen endnu ikke er "ordnet". Så ville jeg lave dette:

UPDATE tabelnavn set dtmTid = CONVERT(datetime, '2000-01-01 ' + LEFT(strTid, 2) + ':' + RIGHT(strTid, 2), 120)
WHERE dtmTid IS NULL
Avatar billede ldanielsen Nybegynder
03. marts 2005 - 22:38 #5
sorry, det skal naturligvis være CONVERT(smalldatetime, .... osv. for vi vedtog jo at kolonnen dtmTid er smalldatetime
Avatar billede janus_007 Nybegynder
04. marts 2005 - 00:40 #6
ldanielsen-> Både ja og nej, din løsning virker, men ikke optimalt. Det kommer helt an på hvordan tidspunktet skal anvendes. Hvis det blot er en tidsangivelse, så vil det helt sikkert bedre kunne svare sig at droppe den dato som du vil sætte foran. DateTime bruger 8bytes, den smalldatetime som du foreslog bruger 4bytes. Men hvis det som sagt kun er et tidsinterval så ville jeg helt sikkert bare bruge en smallint (2^15) det burde jo være mer end nok :O)

Udover det vil der også ligge en del dårlig performance hvis man havde opbevaret noget med dato foran... Så skulle man måske også lige pludselig til at dele den igen, når man skulle bruge resultatet + som du selv har vist koden til.. en meget performance krævende operation  (left-right) + det at tiden formodentlig kan stå på flere måder end bare tt mm

Men lad os nu høre hvad puppetmaster siger om den time benævnelse.
Avatar billede janus_007 Nybegynder
04. marts 2005 - 00:42 #7
Nåhjaa... ldanielsen-> Du behøver forresten ikke converte til datetime, det ligger implicit i feltets vartype :O)  (bare et godt råd)
Avatar billede ldanielsen Nybegynder
04. marts 2005 - 01:04 #8
Hvis du laver det som smallint, så kan du ikke få at vide hvor mange minuttr der er mellem kl 1020 og kl 11.35, uden at skulle regne på det. Alt det får du forærende med et dato felt. Men igen, hvis der ikke er brug for det heller, så kan man jo lige så godt lade det være et tekstfelt, skulle jeg mene.

det er rigtigt at MSSQL godt kan konvertere tekst til dato, lige som den kan konvertere tal til tekst og omvendt. Men der er ingen mening i at MSSQL selv skal finde ud af at undersøge tekstformatet for at vurdere hvilket format det er i, det er bare ekstra arbejde. Koden ser mere kompliceret ud, men for programmet er det faktisk mere enkelt at afvikle.

I øvrigt:
DECLARE @d smalldatetime
SET @d = '23 16'

det giver en fejl, så du er alligevel nødt til at gøre noget ved tekststrengen. Hvis man erstatter mellemrummet med et kolon så virker det:

DECLARE @d smalldatetime
SET @d = '23:16'

Det virker.
Avatar billede ldanielsen Nybegynder
04. marts 2005 - 01:06 #9
CONVERT(datetime, '2000-01-01 ' + REPLACE(strTid, ' ', ':'), 120) er enklere
Avatar billede puppetmaster Nybegynder
04. marts 2005 - 08:13 #10
:(
Det ser ikke ud til at være så nemt endda og ydermere så skal jeg hente felter fra et andet regneark, SAMTIDIG, for primærnøglen er en sammensat én.
Må bare gemme det som en tekst på 5 tegn. I regnearket er værdierne nemlig en starttid og stoptid, men regnearket regner også tiden derimellem ud, så den overfører jeg også til SQL Serveren (hvis man havde felterne som dato-type, kunne der altid, nemt, kunne beregnes på dem, men nu har jeg tidsforbruget, så må det være godt nok. IKKE optimalt eller særligt "data-sikkert"!)
Avatar billede janus_007 Nybegynder
04. marts 2005 - 10:07 #11
ldanielsen -> Selvfølgelig kan du få at vide hvor mange minutter der er imellem 1020 og 1245. Du tror sikkert at tidspunktet skal opbevares som du ser det, hvilket jo ikke er tilfældet og absolut heller ikke den korrekte måde at løse sådanne ting på.
Tag et kig på Microsoft Time :O)

Og naturligvis bliver du nødt til at replace mellemrummet med ':'! Hvis det nu af uransagelige årsager viser sig at du alligevel vil indsætte en tid vha. den replace så vil den implicitte conversion alligevel være hurtigere end din convert, se her:

drop table #qwe
create table #qwe
(
t smalldatetime
)

insert into #qwe values(replace('12 12', ' ', ':'))
/* Trace */
insert into #qwe values(replace('12 12', ' ', ':'))   
SQL:StmtCompleted    0    0    3    0   
Hvilket viser 0reads og 3ms i duration

og dit forslag:
declare @t datetime

select @t = CONVERT(datetime, '2000-01-01 ' + replace('12 12', ' ', ':'), 120)
insert into #qwe values(@t)
/*Trace*/
insert into #qwe values(@t)      SQL:StmtCompleted    15    0    27    0
Hvilket viser 27reads og 15ms i duration

puppetmaster->
Idéen med tidsforbruget er nu ikke så tosset endda, hvorfor bruger 2 felter på at vise noget der kan vises i et felt, medmindre tidsforbrugets start og slut skal registreres ligeså.
Avatar billede puppetmaster Nybegynder
24. juni 2005 - 13:14 #12
Jeg har lavet feltet som et datetime, det virker med lidt hiv og sving
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