SQL server – kolumn alias best practice

Oopps! Upgrade your browser pretty please. Oopps! Upgrade your browser pretty please.

Att använda alias i SQL har många fördelar och är helt nödvändiga i vissa situationer, som exepelvis vid användade av common table expression (CTE). Nedanstående exempel skulle generera ett felmeddelande:

 

;WITH myCTE
AS
(
SELECT GETDATE(), t.Name FROM sys.Tables t
)
SELECT * FROM myCTE;

—————————————–
Msg 8155, Level 16, State 2, Line 1
No column name was specified for column 1 of ‘myCTE’.

 

Enligt ANSI standarden för SQL så skall man använda:

uttryck AS alias

Det innebär att föregående fråga skall då alltså skrivas:

;WITH myCTE AS ( SELECT GETDATE() as currentDateTime, t.Name FROM sys.Tables t ) SELECT * FROM myCTE;

I det här exemplet så är det ganska enkelt att se vad GETDATE() uttrycket har för alias, men anta att du har en komplex uträkning blandat med en lång CASE sats etc, så att antingen raden eller uttrycket blir så lång att du inte kan snabbt se ditt alias. Då blir koden ganska snabbt svår att tolka. Ännu värre blir situationen om du har en INSERT sats där du ska lägga in rätt uttryck i rätt kolumn.

Eftersom antalet columner, datatyper, etc i tabellen där datat skall läggas till måste matchas med kolumnerna i SELECT listan så kan det lätt bli frustrerande när man får fel på grund av :

  1. att fel antal kolumner är angivna i SELECT listan
  2. att någon kolumn i INSERT listan har en annan typ än den kolumnen som är på samma position i SELECT listan
  3. att en kolumn från SELECT listan läggs in i fel kolumn i INSERT tabellen

Eftersom felmeddelandet inte alltid pekar ut vilken rad som innehåller ett fel så kan det bli ganska tidsödande att hitta felet, speciellt om det är så enkelt som att man missat ett kommatecken mellan två kolumner eftersom det då anses vara ett alias på grund av att AS är inte obligatoriskt!

INSERT INTO dbo.yyy (createdDate)
SELECT GETDATE() createdDate FROM xxx

är detsama som

INSERT INTO dbo.yyy (createdDate)
SELECT GETDATE() as createdDate FROM xxx

MEN vad hade hänt anta att du hade velat ha en currentTime baserat på GETDATE() och en kolumn från xxx som heter createdDate. I nedanstående exempel har jag medvetet “missat” ett kommatecken för att visa konsekvensen. GETDATE() får ett alias som heter createdDate och antalet kolumner i INSERT matchar inte antalet i SELECT, vilket resulterar i ett fel.

INSERT INTO dbo.yyy (currentTime, createdDate)
SELECT GETDATE() createdDate FROM xxx

Det här felet hade inte uppstått om vi hade varit tvungen att skriva AS för alias. Det har var dock ett enkelt exempel där det var lätt att se var felet uppstod, men vi har nog alla sett många exempel på svårläst kod så jag undviker att tråka ut er med en sådan.

Nu till ett alternativ som inte är ANSI compliant, men som jag är förespråkare till:

alias = uttryck

Så här skriver man ju i de flesta andra programmeringsspråk, så varför inte i SQL!

INSERT INTO dbo.yyy (currentTime, createdDate)
SELECT currentTime = GETDATE() createdDate FROM xxx

Det är lätt att följa och lätt att matcha SELECT satsen visuellt mot INSERT satsen. Samma kolumnnamn i INSERT listan som i SELECT listan och aliaset står först så att det inte försvinner längst bort i perifirin. Det spelar då ingen roll hur långt uttrycket blir:

INSERT INTO dbo.zzz ( customerID, CountryCode)
SELECT
customerID,
countryCode = CASE countryName
                                WHEN ‘SWEDEN’ THEN ‘SE’
                                WHEN ‘Sverige’  THEN ‘SE’
                                WHEN ‘NORWAY’ THEN ‘NO’
                                WHEN ‘FINLAND’ THEN ‘FI’
                      END
FROM dbo.bbb

är lättare att läsa och följa än:

INSERT INTO dbo.zzz (customerID, CountryCode)
SELECT
customerID,
CASE countryName
                                WHEN ‘SWEDEN’ THEN ‘SE’
                                 WHEN ‘Sverige’  THEN ‘SE’
                                WHEN ‘NORWAY’ THEN ‘NO’
                                WHEN ‘FINLAND’ THEN ‘FI’
END AS countryCode
FROM dbo.bbb

Orolig för att det inte är ANSI standard? Personligen så har jag inte sett så många bra tillämpningar som är helt plattformsoberoende och kan porteras mellan olika databasmotorer utan att det finns några problem, framförallt vad gäller prestanda.

Läs gärna mer om Alias ifrån Aaron Bertrand på http://sqlblog.com/blogs/aaron_bertrand/archive/2012/01/23/bad-habits-to-kick-using-as-instead-of-for-column-aliases.aspx

Kontakta gärna någon av våra SQL server konsulter för att få hjälp att sätta upp en Best Practice för SQL server