Gå til innhold

[Løst]MSSQL: varchar og overflødig whitespace


Anbefalte innlegg

Har en lagret prosedyre som tar flere parametere av typen varchar.

Oftest så er de innkommende parameterene kortere enn maksgrensen jeg har satt i prosedyren.

Saken er at feltene blir fylt ut med whitespacer til maksgrensen og blir med når jeg henter ut verdiene igjen.

 

Kanskje jeg bruker feil datatype?

Lenke til kommentar
Videoannonse
Annonse

Tok litt tid, men her er den:

 

@filename varchar (256),

@filesize int,

@serverpath varchar(256),

@url varchar,

@username varchar(100)

 

AS

 

declare @owner int

EXEC GetIdByUserName @username, @owner OUTPUT

 

IF(@owner != -1)

BEGIN

INSERT INTO Filesystem(Filename,Filesize,ServerPath,Owner,LastUpdate,Created,URL)

VALUES(@filename,@filesize,@serverpath,@owner,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,@url)

 

END

Endret av Techster
Lenke til kommentar

Det er ingenting galt i prosedyren, med unntak av at variabel @URL er definert uten lengde, noe som gjør at SQL Server benytter varchar(1).

 

Kan du gi meg kolonnedefinisjonene for FILESYSTEM tabellen (det er en tabell, og ikke et view?). Er det noen INSERT-triggere definert på tabellen?

Lenke til kommentar

@URL skal være @URL varchar(500)

 

[iD] [int] IDENTITY(1,1) NOT NULL,

[Filename] [nchar](256) NOT NULL,

[Filesize] [int] NOT NULL,

[serverPath] [nchar](256) NOT NULL,

[Owner] [int] NOT NULL,

[LastUpdate] [datetime] NOT NULL,

[Created] [datetime] NOT NULL,

[nchar](500) NOT NULL,

 

Får forresten samme resultatet om jeg kjører prosedyren direkte på serverene og ikke via programmet mitt.

Lenke til kommentar
Ingen insert triggere definert og ja det er en tabell.

Er litt rart hvis variablene blir padda med spaces fordi tabellen du setter inn i har nchar-felt synes jeg, men det ser ut som det er dét som skjer?

 

Visste ikke at nchar/char skulle white-paddes engang jeg. Trodde de faktisk skulle lagre nøyaktig den strengen man setter inn, uten padding, men også uten å spare plass på den måten som varchar gjør.

 

Har du sjekket hva som faktisk legges i tabellen?

Lenke til kommentar

Problemet ditt er at du har brukt nchar i tabellen. nchar er unicode-versjonen av char, og char (og da også nchar) er en fast-lengde datatype.

 

Dvs at du alltid bruker 512 (256*2 pga unicode) bytes for hver rad i kolonne Filename og tilsvarende for kolonne ServerPath. Jeg kjenner kun SQL Servers måte å håndtere whitespace padding på, og jeg kan bekrefte at "ubrukt" lengde paddes med space.

 

Er det noen spesiell grunn for at du har valgt å bruker nchar istedet for nvarchar? Jeg har per dags dato aldri selv hatt behov for å benytte char/nchar. Les mer om forskjellene her: http://bytes.com/topic/sql-server/answers/...char-vs-varchar

Endret av kaffenils
Lenke til kommentar
Jeg kjenner kun SQL Servers måte å håndtere whitespace padding på, og jeg kan bekrefte at "ubrukt" lengde paddes med space.

Ser etter litt googling at det paddes med whitespace, ja.

 

Men er litt usikker på problemet her jeg. Hva menes med «hente ut igjen»? Hente ut fra tabellen eller fra variablene? Har paddingen sneket seg inni variablene i prosedyren er det merkelig, hvis det bare er snakk om padding i tabellen er det trivielt.

Lenke til kommentar

Har ikke jobbet noe særlig med databaser før, men mente at jeg hadde sjekket ut dette.

 

Problemet ble løst ved å bytte til nvarchar.

 

Takk for hjelpen! :D

 

Han mener nok når han SELECTer fra tabellen. Da vil spacene returneres og han må RTRIMe dem enten i spørringen eller på klientsiden.

 

Helt riktig.

Lenke til kommentar

Det eneste problemet ditt nå er at tabellen inneholder mye ubrukt plass som aldri vil bli brukt igjen uten noen triks.

Når du endrer en char til varchar så blir alle radene kopiert til nye data pages, noe som betyr at plassbruke dobles. Hvis du har en clustered index i tabellen så holder det å kjøre DBCC DBREINDEX('Filesystem').

 

Kjør følgende før og etter DBCC DBREINDEX så ser du hvor mye plass du får tilbake.

exec  sp_spaceused @objname='Filesystem',@updateusage =  'true'

 

Dette vil dessverre ikke fjerne den ubrukte nchar plassen internt i hver data page. Da må det "sterkere" lut til. Med det mener jeg at kolonnen du endret til varchar må kopieres til en ny kolonne. Deretter må den gamle kolonnen slettes, DBCC CLEANTABLE og DBCC DBREINDEX kjøres, og til slutt må den nye kolonnen renames til navnet til den gamle.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...