Udveksling af SQL-udtryk mellem forskellige typer databaser

<< Click to Display Table of Contents >>

Navigation:  SQL Bruger-definerede udtryk >

Udveksling af SQL-udtryk mellem forskellige typer databaser

Previous pageReturn to chapter overviewNext page

SQL universalitet: portabilitet, reproducérbarhed, dokumentation

se også SQL-tips på tværs af databaser samt Noter om AbsBD SQL

Databaseudtræk defineret via SQL-udtryk har den store fordel, at SQL-sproget i sin grundform er underlagt internationale ISO standarder (samt ANSI standard, USA), der gør udtrykkene universelt forståellige på tværs af de forskellige anvendte database systemer.

SQL-udtryk kan således ret let distribueres som tekstudtryk og anvendes af diverse ellers uafhængige databaseinstallationer og forskellige databasesystemer, der blot overholder SQL-standarden.

Trods den foreskrevne SQL-standard (men tilladt indenfor denne) er der alligevel små variationer i SQL-sproget (dialekter), der dog normalt ikke giver fejlresulater men kan blive afvist af det anvendte database system, hvis ikke udtrykkene tilrettes den anvendte dabases SQL-dialekt.
Disse dialekter drejer sig først og fremmest om udformning af udtryk for ekstraktion af underværdier af dato-tids-felter, hvorimod SQL-syntaksen for kodning af datoformat er standardiseret efter ISO-formatet yyyy-mm-dd (dog uden at alle databaser anvender dette standard datoformat) - se også nedenfor.

Temporære in-Memory tabeller vs. SQL-Views som kilde til sekventielle SQL-udtræk

For anvendelse af mellemlagringer i temporære tabeller kan der desuden være forskelle på om de enkelte databasesystemer accepterer virtuelle in memory tabeller og hvordan adressen for disse skrives (f.eks. som MEMORY Temp, "Memory\Temp", @Temp eller lignede).
Hvis sådanne mellemlagrede udtræk genbruges i mange udtryk, kan man i visse databaser (men ikke i NeoBase 6 (Reader)) lagre disse som separate filer, der så blot refereres til i hvert af de afledte udtryk. Sådanne separat lagrede SQL del-udtryk benævnes vanligvis SQL VIEWs og har den fordel ved genbrug som deludtryk i andre SQL-udtræk at kunne redigeres centralt eet sted fremfor som deludtryk i hvert af de evt. talrige afledte SQL-udtryk.
I NeoBase 6 Reader er ovennævnte manglende mulighed for indhentning af VIEWS løst ved at lade hverts SQL-udtryk kunne hente en variabel udformning af den grupperingsbestemmende del af SQL-udtrykket fra den separate øvre del af SQL-vinduet, der ved eksekvering dynamisk lægges sammen til een samlet SQL-kørsel (SQL script).

Varierende grad af SQL-implementering

Herudover vil de enkelte databasesystemer altid have varierende omfang af implementeringer i forhold til de omfattende muligheder som beskrevet i SQL-standarden, der dog sjældent giver problemer mellem de bedre SQL-databasesystemer.

Udover at give den bedste specificitet på tværs af databasesystemer eller specifikke installationer, giver anvendelsen af SQL som definition for opgørelser den bedste mulighed for at kunne dokumentere sine opgørelsers metodik og reproducérbarhed.

SQL dato-tids-værdier

Udtræk fra dato-tids-værdier

Udtræk af sub-enheder fra dato-tids-værdier er genstand for flere dialektiske implementeringer, hvor både MS SQL Server og MS Access anvender deres proprietære Microsoft syntaks, hvorimod bl.a. Absolute Database og en lang række andre databaser anvender standard SQL:

Udtræk af:

Standard SQL (ISO)

MS SQL Server og MS Access

Dag-i-måned

EXTRACT(DAY FROM feltnavn)

DatePart("dd", feltnavn)

Måned

EXTRACT(MONTH FROM feltnavn)

DatePart("mm", feltnavn)

År

EXTRACT(YEAR FROM feltnavn)

DatePart("yyyy", feltnavn)

hvor feltnavn angiver et felt med en dato- eller dato-tids-værdi.

SQL-kodede datoværdier

Angående kodede datoværdier (dvs. datoværdier skrevet som strengværdi direkte i SQL-koden fremfor datoværdier hentet fra et datafelt) er der ligeledes nogen variation af hvordan dette er implementeret i diverse SQL databaser.
Traditionel SQL (før ANSI / ISO / IEC certificeringen) anvender US-formatet 'MM/dd/yyyy' som f.eks.:
 '2/1/2004'   =  1. februar 2004
 '12/31/2004' = 31. december 2004
Denne form anvendes af Paradox på trods af at Paradox er erklæret SQL-92 kompatibel.

MS Access anvender et tilsvarende men let modificeret format:
 #2/1/2004#   =  1. februar 2004
 #12/31/2004# = 31. december 2004

Det officielle ISO dato strengformat, der også er den foreskrevne SQL-standard siden SQL-92, er 'yyyy-MM-dd' som f.eks.:
 '2004-02-01' =  1. februar 2004
 '2004-12-31' = 31. december 2004
der anvendes af alle de nyere SQL-standardiserede databaser inklusiv den hér (i NeoBase 6) anvendte Absolute Database.

SQL-kodede datoværdier kan f.eks. anvendes, hvor man ønsker at filtrere på mere specifikke datointervaller som f.eks.:
 WHERE dato_felt BETWEEN '2004-03-16' AND '2004-09-15'

Udtræk af dato-værdier fra datoformaterede strengværdier

Ved hjælp af funktione CAST vil det normalt være muligt at konvertere en datoformaterede strengværdier til dato-værdier af data-typen DATE.

Dette kan normalt lade sig gøre som f.eks.
 CAST('2014-07-31' AS DATE)     /* ISO datoformat uafhængig af system-format  */
eller
 CAST('31.12.14' AS DATE)       /* datoformat afhængig af system-format  */
eller for Paradox som
 CAST('07/31/14' AS DATE)

En mere dymamisk måde at konvertere strenge til datoformat er at hente dato-værdier udfra feltværdier, f.eks. fra strengværdi definerede CPR-numre som i:
 CAST((SUBSTRING(CPR FROM 1 FOR 2) + '.' + SUBSTRING(CPR FROM 3 FOR 2) + '.' + SUBSTRING(CPR FROM 5 FOR 2)) AS DATE)
der for det viste SUBSTRING-udtræk henter et CPR-felts dato i formatet dd.MM.yy, der via CAST konverteres til dato med den relevante allokering til århundrede udfra databasens definerede tidsvindue for tocifrede årstal og med brug af systemets aktuelt indstillede datoseparator (i dette tilfælde punktum). En mere specifikt præcis allokering af datoer i CPR-numre sker imidlertid udfra CPR-løbenumret efter en langt mere kompleks syntaks.

Denne anvendelse af CAST baseret på SUBSTRING-udtræk kunne imidlertid ikke lade sig gøre med Paradox LocalSQL i NeoBase 3, men er blevet mulig vha. programmets anvendte AbsoluteDB.

Paradox LocalSQL udtryk til standard (ISO) SQL

Her skal man være opmærksom på, at Paradox (LocalSQL) i den tidligere NeoBase 3 ved definition af alias-navne forlangte, at disse præfikses med tabelreference, hvilket ikke er tilladt i standard ISO SQL, idet alias-navne i standard SQL forudsættes at være unikke for det givne SQL-udtryk og ikke betragtes som en oprindelig tabel-kolonne.
Hvis man f.eks. oversætter paradox SQL-udtrykket:
  SELECT n2.PersonId, EXTRACT(YEAR FROM n2.Udskrivelsesdato) AS n2."Udskr-År" FROM Neobase2 n2
skal alias-navnet "Udskr-År" i standard SQL defineres uden tabel-reference (dvs. uden "n2" præfiks):
  SELECT n2.PersonId, EXTRACT(YEAR FROM n2.Udskrivelsesdato) AS "Udskr-År" FROM Neobase2 n2

Division by zero error

Paradox accepterer formler, der indebærer divison med nul (0), der i givet fald returnerer en NULL-værdi, dvs. et tomt udlæsningsfelt.

Standard ISO SQL databaser accepterer ikke divison med nul, hvorfor det for disse er nødvendigt enten at udelukke poster med forekomst af division med nul eller at erstatte formlen af et andet udtryk (f.eks. <konstant>) for de forekomster hvor division med nul forekommer, og hvor dette erstatningsudtryk helt simpelt kan være NULL. Dette kan gøres ved at gøre formeludtrykket betinget via et CASE statement, der til gengæld ikke accepteres af paradox:

I paradox:
[udtryk01 eller felt01]/[udtryk02 eller felt02] AS [table]."Afledt felt"

I ISO SQL database (inklusiv den i dette program replikate NeoBase):
CASE
WHEN [udtryk02 eller felt02] = 0 THEN NULL
ELSE [udtryk01 eller felt01]/[udtryk02 eller felt02]
END
AS "Afledt felt"

Paradox og Microsoft Access?

Begge disse databaser kan anvende SQL men Paradox anvender desværre kun en ret begrænset og for mange situationer helt insufficient del af SQL-92 standarden, som Paradox (fraset forlangende af præfiks af alias-felter) dog holder sig pænt indenfor (dvs. uden proprietære tilføjelser), mens MS Access ikke er helt så mangelfuld, men som til gengæld har en række uhensigtsmæssige non-standard proprietære Microsoft specialiteter/særheder, der i betydelig grad besværliggør oversættelse af SQL-udtryk til eller fra andre systemer.
Til ad hoc at jonglere med diverse udtræk er Access dog udmærket, men man vil hurtigt finde det lettere og mere fleksibelt at tillære sig lidt basal standard SQL anvendt overfor en kvalificeret SQL-database - det gælder specielt, hvis man får brug for kolonnestatistik (aggregation) på afledte (beregnede) kolonneværdier, for temporære tabeller eller for indlejrede SQL-udtryk (sub-queries).

_____________________________

27-10-2017 - © 2003-2017 Niels Knabe