{"id":507,"date":"2011-11-18T08:27:02","date_gmt":"2011-11-18T06:27:02","guid":{"rendered":"http:\/\/www.kristiansborg.dk\/bibliotek\/?page_id=507"},"modified":"2011-11-18T08:28:45","modified_gmt":"2011-11-18T06:28:45","slug":"kapitel-5-databaser-og-asp","status":"publish","type":"page","link":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/","title":{"rendered":"Kapitel 5 Databaser og ASP"},"content":{"rendered":"<p>En af de mest udbredte anvendelser af ASP er til pr\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\u00e5 data i en database. Databaseforesp\u00f8rgslerne er baseret p\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget.<\/p>\n<p>Dern\u00e6st bliver det gennemg\u00e5et, hvordan man opretter forbindelse til sin database fra ASP, hvorefter det beskrives, hvordan man l\u00e6ser oplysninger fra en database, og hvordan man gemmer oplysninger i en database.<\/p>\n<p>I eksemplerne i denne bog bruges Microsoft Access 2000 som database, men fremgangsm\u00e5den er den samme uafh\u00e6ngigt af databasen. Microsoft Access 2000 er valgt, fordi den er let at bruge, forholdsvis udbredt og billig i forhold til st\u00f8rre serverbaserede l\u00f8sninger som Oracle og Microsoft SQL Server.<\/p>\n<div style=\"border: 1px solid red; color: red\">\n<p><b>Du l\u00e6ser en gammel bog<\/b><\/p>\n<p>Den bog, du l\u00e6ser her, er fra 1999, og mange ting kan have \u00e6ndret sig siden da.<br \/>\nVi h\u00e5ber, at du stadig kan finde relevant information i den.<br \/>\nHvis du vil l\u00e6se aktuelle oplysninger om den aktuelle version af ASP.NET, anbefaler vi<br \/>\nbogen <a href=\"http:\/\/clk.tradedoubler.com\/click?p(197229)a(2029446)g(19172914)url(http:\/\/www.adlibris.com\/dk\/product.aspx?isbn=0735643385)\" onclick=\"javascript:pageTracker._trackPageview('\/outbound\/article\/http:\/\/clk.tradedoubler.com\/click?p(197229)a(2029446)g(19172914)url(http:\/\/www.adlibris.com\/dk\/product.aspx?isbn=0735643385)');\"  target=\"_blank\">Programming ASP.NET 4.0<\/a><img decoding=\"async\" src=\"http:\/\/impdk.tradedoubler.com\/imp?type(inv)g(19172914)a(2029446)\" \/>\n<\/div>\n<h1>Introduktion til SQL<\/h1>\n<p>Dette afsnit er en gennemgang af de grundl\u00e6ggende kommandoer i SQL-sproget. Har man ikke i forvejen kendskab til SQL, kan afsnittet bruges til at l\u00e6re de mest basale elementer af sproget. Kender man SQL i forvejen, kan man bruge dette afsnit til opslag, hvis man f\u00e5r behov for at f\u00e5 opfrisket sin hukommelse p\u00e5 enkelte punkter.<\/p>\n<p>Gennemgangen er opbygget som en oversigt over de mest anvendte kommandoer. Det drejer sig om kommandoer til oprettelse af en tabel, inds\u00e6ttelse af data, s\u00f8gning, opdatering og sletning. Der gives en kort beskrivelse af hver enkelt kommando og dens syntaks, ligesom det bliver gennemg\u00e5et, hvilke parametre der kan bruges med den. Der bliver ogs\u00e5 givet et eksempel til hver enkelt kommando.<\/p>\n<p>F\u00e6lles for alle kommandoerne er, at de best\u00e5r af nogle reserverede ord, som udg\u00f8r selve kommandoen, og referencer til elementer i databasen \u2013 eksempelvis tabeller og kolonner.<\/p>\n<h2>Oprettelse af en tabel<\/h2>\n<p>Til at oprette en tabel bruges kommandoen CREATE TABLE. Syntaksen for denne kommando er<\/p>\n<p>&nbsp;<\/p>\n<p>CREATE TABLE [<em>bruger<\/em>.]<em>tabel <\/em>( {<em>kolonne type<\/em> [<em>begr\u00e6nsning<\/em>]} [, {<em>kolonne type<\/em> [<em>begr\u00e6nsning<\/em>]} ] . . .) [AS <em>foresp\u00f8rgsel<\/em>]<\/p>\n<p>&nbsp;<\/p>\n<p>Parameteren <em>bruger<\/em> angiver den bruger, tabellen skal oprettes under. <em>Tabel<\/em> angiver navnet p\u00e5 tabellen. En tabel best\u00e5r af en r\u00e6kke kolonner \u2013 for hver af disse kan man angive kolonnens navn, type og en eventuel begr\u00e6nsning p\u00e5 de data, der kan indtastes. SQL-standarden definerer nedenst\u00e5ende typer, men de enkelte databaser kan anvende andre navne.<\/p>\n<p>&nbsp;<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"326\" valign=\"top\">Type<\/td>\n<td width=\"326\" valign=\"top\">Beskrivelse<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CHAR(<em>n<\/em>)<\/td>\n<td width=\"326\" valign=\"top\">En tekststreng med <em>n<\/em> tegn.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">VARCHAR(<em>n<\/em>)<\/td>\n<td width=\"326\" valign=\"top\">En tekststreng med op til <em>n<\/em> tegn.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">LONG VARCHAR(<em>n<\/em>)<\/td>\n<td width=\"326\" valign=\"top\">En tekststreng med op til <em>n<\/em> tegn.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">DECIMAL(<em>c<\/em>,<em>d<\/em>)<\/td>\n<td width=\"326\" valign=\"top\">Et decimaltal med <em>c<\/em> cifre og <em>d<\/em> decimaler.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">NUMERIC(<em>c<\/em>,<em>d<\/em>)<\/td>\n<td width=\"326\" valign=\"top\">Som DECIMAL<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">SMALLINT<\/td>\n<td width=\"326\" valign=\"top\">Et heltal p\u00e5 to byte.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">INTEGER<\/td>\n<td width=\"326\" valign=\"top\">Et heltal p\u00e5 fire byte.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">REAL<\/td>\n<td width=\"326\" valign=\"top\">Et decimaltal p\u00e5 fire byte.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">FLOAT<\/td>\n<td width=\"326\" valign=\"top\">Et decimaltal p\u00e5 otte byte.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Tabel 5.1: Kolonnetyper i SQL.<\/p>\n<p>&nbsp;<\/p>\n<p>For hver kolonne kan der angives eventuelle begr\u00e6nsninger, som for eksempel at indholdet af kolonnen ikke m\u00e5 v\u00e6re null\u00a0\u2013 det g\u00f8res ved at skrive NOT NULL.<\/p>\n<p>Ved at tilf\u00f8je ordet AS og en foresp\u00f8rgsel kan man oprette tabellen p\u00e5 baggrund af en foresp\u00f8rgsel. Foresp\u00f8rgsler bliver gennemg\u00e5et senere i dette kapitel.<\/p>\n<p>Nedenst\u00e5ende eksempel viser, hvordan man kan oprette en adresse-tabel.<\/p>\n<p>&nbsp;<\/p>\n<p>CREATE TABLE adresse (<\/p>\n<p>Navn\u00a0\u00a0\u00a0\u00a0\u00a0 VARCHAR(30)\u00a0 NOT NULL,<\/p>\n<p>Adresse1\u00a0 VARCHAR(50)\u00a0 NOT NULL,<\/p>\n<p>Adresse2\u00a0 VARCHAR(50),<\/p>\n<p>Postnr\u00a0\u00a0\u00a0 CHAR(4)\u00a0\u00a0\u00a0\u00a0\u00a0 NOT NULL,<\/p>\n<p>Telefon\u00a0\u00a0 CHAR(8)<\/p>\n<p>)<\/p>\n<p>&nbsp;<\/p>\n<h2>Inds\u00e6ttelse af data<\/h2>\n<p>N\u00e5r man skal inds\u00e6tte data i en tabel ved hj\u00e6lp af SQL, bruger man kommandoen INSERT INTO. Denne kommando har f\u00f8lgende syntaks:<\/p>\n<p>&nbsp;<\/p>\n<p>INSERT INTO [<em>bruger<\/em>].<em>tabel<\/em> [(<em>kolonne <\/em>[, <em>kolonne<\/em>] . . .)] { VALUES (<em>v\u00e6rdi <\/em>[, <em>v\u00e6rdi<\/em>]) | <em>foresp\u00f8rgsel<\/em>}<\/p>\n<p>&nbsp;<\/p>\n<p>Ligesom ved CREATE TABLE-kommandoen angiver <em>bruger<\/em>.<em>tabel<\/em> navnet p\u00e5 den tabel, der skal arbejdes p\u00e5. Hvis man kun \u00f8nsker at inds\u00e6tte data i nogle af kolonnerne i tabellen, skal man angive navnene p\u00e5 kolonnerne i kommandoen. Man kan angive lige s\u00e5 mange kolonner, man vil, adskilt af komma.<\/p>\n<p>Man kan enten selv angive de data, der skal inds\u00e6ttes i tabellen, eller generere dem ved hj\u00e6lp af en foresp\u00f8rgsel. Foresp\u00f8rgsler bliver gennemg\u00e5et senere i dette kapitel. Hvis man selv angiver dataene, skal man skrive dem i samme r\u00e6kkef\u00f8lge, som man har n\u00e6vnt kolonnenavnene. Man skal v\u00e6re opm\u00e6rksom p\u00e5, at tekststrenge skal angives i apostroffer \u2013 eksempelvis &#8216;tekst&#8217;.<\/p>\n<p>Nedenst\u00e5ende eksempel viser, hvordan man kan inds\u00e6tte data i den tabel, der blev oprettet i afsnittet om oprettelse af tabel.<\/p>\n<p>&nbsp;<\/p>\n<p>INSERT INTO adresse<\/p>\n<p>(Navn, Adresse1, Postnr, Telefon)<\/p>\n<p>VALUES (&#8216;Egon Jensen&#8217;, &#8216;Svinget 3&#8217;, &#8216;9110&#8217;, &#8216;97123456&#8217;)<\/p>\n<p>&nbsp;<\/p>\n<h2>Foresp\u00f8rgsel p\u00e5 data<\/h2>\n<p>Foresp\u00f8rgsler kan bruges til mange ting i SQL. Man kan naturligvis bruge dem til at tr\u00e6kke oplysninger ud af databasen, men man kan ogs\u00e5 bruge dem som inddata til oprettelse af tabeller, inds\u00e6ttelse af data med mere.<\/p>\n<p>I SQL foretages en foresp\u00f8rgsel med kommandoen SELECT. Denne kommando har f\u00f8lgende syntaks:<\/p>\n<p>&nbsp;<\/p>\n<p>SELECT [ALL|DISTINCT] {* | <em>tabel<\/em>.* | <em>kolonne<\/em> [<em>nyt navn<\/em>]} [,{ <em>tabel<\/em>.* | <em>kolonne<\/em> [<em>nyt navn<\/em>]}] . . . FROM [<em>bruger.<\/em>]<em>tabel<\/em> [<em>nyt navn<\/em>] [,[<em>bruger<\/em>.]<em>tabel<\/em> [<em>nyt navn<\/em>] . . .]<\/p>\n<p>[WHERE <em>betingelse<\/em>]<\/p>\n<p>[CONNECT BY <em>betingelse<\/em>]<\/p>\n<p>[START WITH <em>betingelse<\/em>]<\/p>\n<p>[GROUP BY <em>kolonne<\/em> [, <em>kolonne<\/em>] . . .[HAVING <em>betingelse<\/em>}] ]<\/p>\n<p>[{UNION|INTERSECT|MINUS foresp\u00f8rgsel} . . . ]<\/p>\n<p>[ORDER BY {<em>kolonne<\/em> | <em>position<\/em>) [ASC|DESC] [, <em>kolonne<\/em> | <em>position<\/em>) [ASC|DESC] ] . . .<\/p>\n<p>[FOR UPDATE OF <em>kolonne<\/em> [, <em>kolonne<\/em>] [NOWAIT] ]<\/p>\n<p>&nbsp;<\/p>\n<p>Kommandoen ser umiddelbart forholdsvis kompliceret ud, men det skyldes blot, at den er overm\u00e5de fleksibel og har en lang r\u00e6kke muligheder. Typisk bruger man kun en meget lille del af disse muligheder.<\/p>\n<p>Det centrale i kommandoen er angivelse af den eller kolonner, der skal udv\u00e6lges. Disse skrives efter SELECT. Hvis man eksempelvis vil udv\u00e6lge kolonnerne navn og telefon, skriver man alts\u00e5<\/p>\n<p>&nbsp;<\/p>\n<p>SELECT navn, telefon<\/p>\n<p>&nbsp;<\/p>\n<p>Herefter kan man v\u00e6lge den eller de tabeller, dataene skal udv\u00e6lges fra. I dette eksempel hedder tabellen adresse, og n\u00e5r dette tilf\u00f8jes til kommandoen, kommer den til at se s\u00e5ledes ud:<\/p>\n<p>&nbsp;<\/p>\n<p>SELECT navn, telefon<\/p>\n<p>FROM adresse<\/p>\n<p>&nbsp;<\/p>\n<p>Oftest vil man ikke udv\u00e6lge samtlige poster i tabellen, og man har derfor mulighed for at stille nogle betingelser til de poster, der skal udv\u00e6lges. Dette g\u00f8res efter ordet WHERE. Hvis betingelsen eksempelvis skal v\u00e6re, at postnummeret er 9110, kommer foresp\u00f8rgslen til at se s\u00e5ledes ud:<\/p>\n<p>&nbsp;<\/p>\n<p>SELECT navn, telefon<\/p>\n<p>FROM adresse<\/p>\n<p>WHERE postnr=&#8217;9110&#8242;<\/p>\n<p>&nbsp;<\/p>\n<p>Hvis man vil sortere resultatet, kan man benyttet ORDER BY-parametren. Denne parameter angiver den eller de kolonner, der skal sorteres efter, samt om sorteringen skal foretages i stigende eller faldende orden. ASC angiver stigende orden (<em>ascending<\/em>), mens DESC angiver faldende orden (<em>descending<\/em>). Nedenst\u00e5ende eksempel viser, hvordan man kan sortere resultatet efter navne.<\/p>\n<p>&nbsp;<\/p>\n<p>SELECT navn, telefon<\/p>\n<p>FROM adresse<\/p>\n<p>WHERE postnr=&#8217;9110&#8242;<\/p>\n<p>ORDER BY navn ASC<\/p>\n<p>&nbsp;<\/p>\n<p>Egentlig er det ikke n\u00f8dvendigt at tilf\u00f8je ASC, da data som standard sorteres i stigende orden, hvis andet ikke er angivet.<\/p>\n<p>SELECT-kommandoen giver ogs\u00e5 en r\u00e6kke mere avancerede muligheder.<\/p>\n<p>Ved at angive ALL eller DISTINCT kan man v\u00e6lge, om alle data skal findes, eller om r\u00e6kker, der optr\u00e6der flere gange, kun skal optr\u00e6de en enkelt gang i resultatet. Angiver man ikke DISTINCT bruges ALL.<\/p>\n<p>CONNECT BY angiver, at der er tale om en hierarkisk foresp\u00f8rgsel, og man kan angive den foresp\u00f8rgsel, der skal forbinde foresp\u00f8rgslerne i hierarkiet.<\/p>\n<p>START WITH angiver den eller de r\u00e6kker, der skal v\u00e6re roden i en hierarkisk foresp\u00f8rgsel.<\/p>\n<p>UNION, INTERSECT og MINUS kombinerer flere foresp\u00f8rgsler til \u00e9n foresp\u00f8rgsel.<\/p>\n<p>FOR UPDATE OF angiver, hvilke poster der kan blive opdateret. Derved vil disse poster blive l\u00e5st. Angiver man desuden NOWAIT, vil foresp\u00f8rgslen ikke vente, hvis en eller flere af de \u00f8nskede poster ikke kan l\u00e5ses.<\/p>\n<p>Hvis man \u00f8nsker det, kan man under foresp\u00f8rgslen v\u00e6lge at give kolonner og tabeller nye navne, der g\u00f8r dem lettere at referere til senere.<\/p>\n<h2>Opdatering af data<\/h2>\n<p>Hvis man vil \u00e6ndre i eksisterende data, sker det ved hj\u00e6lp af kommandoen UPDATE. Denne kommando har f\u00f8lgende syntaks.<\/p>\n<p>&nbsp;<\/p>\n<p>UPDATE [<em>bruger<\/em>.]<em>tabel<\/em> SET <em>kolonne<\/em> = <em>data<\/em> [, <em>kolonne<\/em> = <em>data<\/em>] . . . [WHERE <em>betingelse<\/em>]<\/p>\n<p>&nbsp;<\/p>\n<p><em>eller<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>UPDATE [<em>bruger<\/em>.]<em>tabel<\/em> SET (<em>kolonne<\/em> [, <em>kolonne<\/em>] . . .) = (<em>foresp\u00f8rgsel<\/em>) [, . . .] [WHERE <em>betingelse<\/em>]<\/p>\n<p>&nbsp;<\/p>\n<p>Som det ses, kan man enten basere opdateringen p\u00e5 data, man selv indtaster eller p\u00e5 en foresp\u00f8rgsel. I begge tilf\u00e6lde skal man dog angive den tabel, der skal foretages opdateringer i, samt de kolonner der skal opdateres. Angiver man selv dataene, skal man for hvert kolonnenavn angive den nye v\u00e6rdi, mens man ved en foresp\u00f8rgselsbaseret opdatering blot skal angive kolonnernes navne. Hvis man ikke \u00f8nsker at opdatere samtlige poster i databasen, kan man angive en betingelse, og det vil i s\u00e5 fald kun v\u00e6re de poster, som opfylder betingelsen, der vil blive \u00e6ndret.<\/p>\n<p>Nedenst\u00e5ende eksempel viser, hvordan man kan \u00e6ndre et postnummer i databasen.<\/p>\n<p>&nbsp;<\/p>\n<p>UPDATE adresse<\/p>\n<p>SET postnr=&#8217;9111&#8242;<\/p>\n<p>WHERE postnr=&#8217;9110&#8242;<\/p>\n<p>&nbsp;<\/p>\n<h2>Sletning af data<\/h2>\n<p>Til at slette poster fra en tabel i databasen bruges kommandoen DELETE. Syntaksen for denne kommando er som f\u00f8lger:<\/p>\n<p>&nbsp;<\/p>\n<p>DELETE [FROM] [<em>bruger<\/em>.]<em>tabel<\/em> [WHERE <em>betingelse<\/em>]<\/p>\n<p>&nbsp;<\/p>\n<p>Igen angiver <em>bruger<\/em>.<em>tabel<\/em> den tabel, der skal arbejdes p\u00e5. <em>Betingelse<\/em> angiver den betingelse, poster skal opfylde, for at blive slettet.<\/p>\n<p>Nedenst\u00e5ende eksempel viser, hvordan man kan slette alle personer med et bestemt navn.<\/p>\n<p>&nbsp;<\/p>\n<p>DELETE FROM adresse<\/p>\n<p>WHERE navn=&#8217;Anders And&#8217;<\/p>\n<h1>Installation af DSN<\/h1>\n<p>Den mest udbredte m\u00e5de at lave forbindelse mellem ASP og en database er ODBC \u2013 <em>Open Database Connectivity<\/em>. ODBC er en standard defineret af Microsoft. Med ODBC er det muligt at tilg\u00e5 flere forskellige databaser p\u00e5 samme m\u00e5de. Det betyder, at de kommandoer, man bruger i ASP, er de samme, ligegyldigt hvilken database man benytter. Man beh\u00f8ver blot at angive navnet p\u00e5 databasen. For at web-serveren kan finde ud af, hvilken database man refererer til, skal man dog i operativsystemet angive sammenh\u00e6ngen mellem det navn, man angiver, og selve databasen. I Windows g\u00f8res dette i kontrolpanelet under punktet 32-bit ODBC.<\/p>\n<p>Det man skal ops\u00e6tte er et databasesystemnavn (DSN). Der findes tre forskellige former for DSN: Bruger-DSN, system-DSN og fil-DSN. En bruger-DSN er kun tilg\u00e6ngelig for den aktuelle bruger og kun p\u00e5 den lokale maskine. En system-DSN er derimod tilg\u00e6ngelig for alle brugere, og ogs\u00e5 for systemservices. En fil-DSN giver adgang til en database med en driver, og denne DSN kan deles af flere brugere, hvis alle brugere har den samme driver installeret. I forbindelse med ASP skal man bruge en system-DSN.<\/p>\n<p>For at oprette en system-DSN skal man klikke p\u00e5 fanen System-DSN. Herefter skal man klikke p\u00e5 knappen Tilf\u00f8j. Det n\u00e6ste billede viser en liste over de installerede databaser. I dette eksempel v\u00e6lges Access-databasen.<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/05011.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-513\" title=\"0501\" src=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/05011-300x221.png\" alt=\"\" width=\"300\" height=\"221\" srcset=\"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/05011-300x221.png 300w, https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/05011.png 468w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Figur 5.1: Valg af database.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>N\u00e5r man har valgt den \u00f8nskede database, klikker man p\u00e5 udf\u00f8r. Man vil herefter blive pr\u00e6senteret for et vindue, hvor man kan indtaste de oplysninger, der skal bruges for at identificere databasen. Anvender man en Access-database, ser vinduet ud som i figur 5.2.<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0502.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-512\" title=\"0502\" src=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0502-300x191.png\" alt=\"\" width=\"300\" height=\"191\" srcset=\"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0502-300x191.png 300w, https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0502.png 489w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Figur 5.2: Identifikation af database.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Man skal naturligvis angive det navn, man gerne vil bruge til at tilg\u00e5 databasen fra ASP. Dette navn kan man selv v\u00e6lge. Man kan ogs\u00e5 v\u00e6lge at lave en beskrivelse af databasen \u2013 dette er ikke n\u00f8dvendigt, men det g\u00f8r det lettere at skelne mellem databaserne, hvis man har flere forskellige. I dialogboksen skal man ogs\u00e5 angive, hvilken Access-fil der skal knyttes til det angivne navn. Ved at klikke p\u00e5 knappen V\u00e6lg f\u00e5r man vist en dialogboks, hvor man kan v\u00e6lge mellem alle de Access-filer, der ligger p\u00e5 computeren.<\/p>\n<p>Installationen af DSN\u2019en er nu f\u00e6rdig. N\u00e5r man klikker p\u00e5 OK, vender man tilbage til installationsvinduet. Som det ses af nedenst\u00e5ende figur 5.3, er den nye DSN nu blevet tilf\u00f8jet listen. Hvis man senere vil foretage \u00e6ndringer i de oplysninger, man angav under installationen, kan man v\u00e6lge at redigere dem fra dette vindue.<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0503.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-511\" title=\"0503\" src=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0503-300x257.png\" alt=\"\" width=\"300\" height=\"257\" srcset=\"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0503-300x257.png 300w, https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0503.png 461w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Figur 5.3: Oversigt over installerede DSN.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Som n\u00e6vnt bliver der i eksemplerne i denne bog arbejdet p\u00e5 en Access-database. Selvom Access er en udm\u00e6rket database, skal man dog v\u00e6re opm\u00e6rksom p\u00e5, at programmet har nogle ulemper. Eksempelvis bliver poster, der bliver slettet i databasen, ikke slettet fra filen. Det betyder, at filen bliver st\u00f8rre og st\u00f8rre. For at formindske filen igen, skal man v\u00e6lge at komprimere den. Dette kan man g\u00f8re ved at v\u00e6lge Komprimer fra installationsvinduet.<\/p>\n<p>N\u00e5r man har f\u00e6rdiggjort installationen af en system-DSN, kan man begynde at bruge databasen fra ASP.<\/p>\n<h1>Databaseobjekter<\/h1>\n<p>Databaseadgang er ikke indbygget i de scriptsprog, man kan bruge sammen med ASP. For at r\u00e5de bod p\u00e5 dette, er der indbygget nogle objekter, som man kan bruge til at tilg\u00e5 databaser. Disse objekter er baseret p\u00e5 ADO (ActiveX Data Object), som ogs\u00e5 bruges i andre sammenh\u00e6nge.<\/p>\n<p>I ASP er der flere objekter, der repr\u00e6senterer ADO. Det centrale af disse objekter er Connection-objektet, som h\u00e5ndterer forbindelsen til databasen. Man opretter et Connection-objekt ved at skrive<\/p>\n<p>&nbsp;<\/p>\n<p>Connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>Som n\u00e6vnt er Connection-objektet det centrale i arbejdet med databaser. Objekter indeholder derfor en lang r\u00e6kke metoder og variabler. Disse bliver alle kort beskrevet i nedenst\u00e5ende tabeller og gennemg\u00e5et dybere i resten af dette kapitel.<\/p>\n<p>&nbsp;<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"326\" valign=\"top\">Metode<\/td>\n<td width=\"326\" valign=\"top\">Beskrivelse<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">BeginTrans<\/td>\n<td width=\"326\" valign=\"top\">Starter en transaktion.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Close<\/td>\n<td width=\"326\" valign=\"top\">Lukker forbindelsen til databasen.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CommitTrans<\/td>\n<td width=\"326\" valign=\"top\">Udf\u00f8rer en transaktion.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Execute<\/td>\n<td width=\"326\" valign=\"top\">Udf\u00f8rer en foresp\u00f8rgsel.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Open<\/td>\n<td width=\"326\" valign=\"top\">\u00c5bner en forbindelse til databasen.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">OpenSchema<\/td>\n<td width=\"326\" valign=\"top\">\u00c5bner et databaseskema.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">RollbackTrans<\/td>\n<td width=\"326\" valign=\"top\">Ruller en transaktion tilbage.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Tabel 5.2: Metoder i Connection-objektet.<\/p>\n<p>&nbsp;<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"326\" valign=\"top\">Variabel<\/td>\n<td width=\"326\" valign=\"top\">Beskrivelse<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Attributes<\/td>\n<td width=\"326\" valign=\"top\">Angiver om en ny transaktion skal startes, n\u00e5r en   transaktion er fuldf\u00f8rt.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CommandTimeout<\/td>\n<td width=\"326\" valign=\"top\">Angive antallet af sekunder, en kommando har til at blive   udf\u00f8rt.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">ConnectionString<\/td>\n<td width=\"326\" valign=\"top\">Angiver de oplysninger, der er brugt til at lave   forbindelse til databasen.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">ConnectionTimeout<\/td>\n<td width=\"326\" valign=\"top\">Angiver antallet af sekunder, der m\u00e5 bruges p\u00e5 at skabe   forbindelse til databasen.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CursorLocation<\/td>\n<td width=\"326\" valign=\"top\">Angiver om mark\u00f8ren findes p\u00e5 serveren eller p\u00e5 klienten.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">DefaultDatabase<\/td>\n<td width=\"326\" valign=\"top\">Angiver den database, der som standard bruges til   forbindelse.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">IsolationLevel<\/td>\n<td width=\"326\" valign=\"top\">Angiver isolationsniveauet for transaktioner.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Mode<\/td>\n<td width=\"326\" valign=\"top\">Angiver udbyderens adgangsrettigheder.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Provider<\/td>\n<td width=\"326\" valign=\"top\">Angiver udbyderens navn.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">State<\/td>\n<td width=\"326\" valign=\"top\">Angiver om forbindelsen er \u00e5ben eller lukket.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Version<\/td>\n<td width=\"326\" valign=\"top\">Angiver hvilken version af ADO, der bruges.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Tabel 5.3: Variable i Connection-objektet.<\/p>\n<p>&nbsp;<\/p>\n<p>N\u00e5r man har oprettet en Connection, skal man v\u00e6re opm\u00e6rksom p\u00e5, at den endnu ikke refererer til\u00a0 noget. Derfor skal man \u00e5bne den, f\u00f8r man kan bruge den. Databaseforbindelsen \u00e5bnes ved at kalde metoden Open. Denne metoder tager op til tre parametre. Den f\u00f8rste er en forbindelsesstreng, der specificerer, hvilken database der skal \u00e5bnes. De to yderligere parametre er henholdsvis brugernavn og adgangskode til databasen. Hvis der ikke kr\u00e6ves brugernavn og kodeord for at tilg\u00e5 databasen, kan man undlade disse.<\/p>\n<p>Forbindelsesstrengen kan v\u00e6re navnet p\u00e5 en systemdatakilde (DSN), som er registreret i ODBC. Dette er klart den letteste fremgangsm\u00e5de, men ikke den eneste. Man kan ogs\u00e5 opbygge sin forbindelsesstreng manuelt ved at udpege den database, man vil bruge. For at g\u00f8re dette skal man angive en r\u00e6kke oplysninger, der skal bruges af databasen. Disse oplysninger varierer fra database til database.<\/p>\n<p>Hvis man vil \u00e5bne en database, der er registreret med systemdatakildenavnet webbase, skriver man<\/p>\n<p>&nbsp;<\/p>\n<p>connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>connection.open(&#8220;webbase&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>Variablen ConnectionString afspejler den forbindelsesstreng, man angiver. F\u00f8r man \u00e5bner forbindelsen kan man bruge variablen til at angive, hvilken forbindelsesstreng der skal bruges. N\u00e5r forbindelsen er \u00e5bnet, kan man ikke l\u00e6ngere \u00e6ndre ConnectionString, men man kan\u00a0 l\u00e6se indholdet af den og p\u00e5 den m\u00e5de finde den forbindelsesstreng, der blev brugt til at \u00e5bne databaseforbindelsen. Ved at anvende ConnectionString-variablen kan man omskrive ovenst\u00e5ende eksempel til f\u00f8lgende:<\/p>\n<p>&nbsp;<\/p>\n<p>connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>connection.ConnectionString=&#8221;webbase&#8221;;<\/p>\n<p>connection.open();<\/p>\n<p>&nbsp;<\/p>\n<p>I dette eksempel er der ingen fordel ved at bruge denne fremgangsm\u00e5de, men hvis man skal opbygge forbindelsesstrengen af en lang r\u00e6kke variable, eller hvis forbindelsesstrengen afh\u00e6nger af ydre omst\u00e6ndigheder, kan det v\u00e6re en fordel at s\u00e6tte ConnectionString-variablen, f\u00f8r man \u00e5bner databaseforbindelsen.<\/p>\n<p>N\u00e5r man har et Connection-objekt, kan man bruge dette til at udf\u00f8re SQL-foresp\u00f8rgsler. Man kan dog ogs\u00e5 v\u00e6lge at bruge et Command-objekt. N\u00e5r man bruger et Command-objekt, beh\u00f8ver man ikke \u00e5bne en databaseforbindelse. Dette g\u00f8r Command-objektet automatisk. Fordelen ved dette, er at man ikke beh\u00f8ver h\u00e5ndtere \u00e5bning og lukning af databaseforbindelsen, men ulempen er, at man \u00e5bner og lukker forbindelsen for hver foresp\u00f8rgsel. Man b\u00f8r derfor kun bruge Command-objektet, hvis man kun foretager en enkelt foresp\u00f8rgsel.<\/p>\n<p>Command-komponenten hedder ADODB.Command, og man kan lave et objekt af denne komponent ved at skrive<\/p>\n<p>&nbsp;<\/p>\n<p>command = Server.CreateObject(&#8220;ADODB.Command&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>Command-objektet indeholder en r\u00e6kke metoder og variabler, der er beskrevet i nedenst\u00e5ende tabeller.<\/p>\n<p>&nbsp;<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"326\" valign=\"top\">Metode<\/td>\n<td width=\"326\" valign=\"top\">Beskrivelse<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CreateParameter<\/td>\n<td width=\"326\" valign=\"top\">Tilf\u00f8jer en parameter til   parameter-samlingen, der beskrives senere.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Execute<\/td>\n<td width=\"326\" valign=\"top\">Udf\u00f8rer kommandoen.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Tabel 5.4: Metoder i Command-objektet.<\/p>\n<p>&nbsp;<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"326\" valign=\"top\">Variabel<\/td>\n<td width=\"326\" valign=\"top\">Beskrivelse<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">ActiveConnection<\/td>\n<td width=\"326\" valign=\"top\">Angiver den databaseforbindelse, der   skal bruges.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CommandText<\/td>\n<td width=\"326\" valign=\"top\">Teksten til den SQL-foresp\u00f8rgsel, der   skal udf\u00f8res.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CommandTimeout<\/td>\n<td width=\"326\" valign=\"top\">Angiver hvor mange sekunder en   kommando har til at blive udf\u00f8rt.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CommandType<\/td>\n<td width=\"326\" valign=\"top\">Angiver typen p\u00e5 den kommando, CommandText   angiver.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Name<\/td>\n<td width=\"326\" valign=\"top\">Angiver kommandoens navn.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Prepared<\/td>\n<td width=\"326\" valign=\"top\">Angiver, om der skal oprettes et   forberedt udtryk (<em>prepared statement<\/em>) for foresp\u00f8rgslen udf\u00f8res.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">State<\/td>\n<td width=\"326\" valign=\"top\">Angiver om kommandoen er \u00e5ben eller   lukket. Er kommandoen \u00e5ben, returneres adStateOpen, mens adStateClosed   returneres, hvis kommandoen er lukket.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Tabel 5.5: Variable i Command-objektet.<\/p>\n<p>&nbsp;<\/p>\n<p>For at skabe forbindelse til databasen med navnet webbase ved hj\u00e6lp af et Command-objekt skal man skrive<\/p>\n<p>&nbsp;<\/p>\n<p>command = Server.CreateObject(&#8220;ADODB.Command&#8221;);<\/p>\n<p>command.ActiveConnection = &#8220;webbase&#8221;;<\/p>\n<p>&nbsp;<\/p>\n<p>Som n\u00e6vnt kan b\u00e5de Command-objekter og Connection-objekter bruges til at udf\u00f8re SQL-foresp\u00f8rgsler. I begge tilf\u00e6lde er det metoden execute, der skal bruges. Nedenst\u00e5ende eksempel viser, hvordan man kan bruge Connection-objektet til at udf\u00f8re SQL-foresp\u00f8rgsler.<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;% @language=javascript %&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>connection.open(&#8220;eksempel&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>connection.execute(&#8220;INSERT INTO tabel VALUES (&#8216;connection&#8217;)&#8221;);<\/p>\n<p>Response.write(&#8220;Data indsat.&#8221;);<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>For at afvikle ovenst\u00e5ende eksempel kr\u00e6ves en database registreret med navnet eksempel. Denne database skal indeholde en tabel ved navn tabel.<\/p>\n<p>Eksemplet kan forholdsvis nemt omskrives til at bruge et Command-objekt. Det omskrevne eksempel ses herunder.<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;% @language=javascript %&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>command = Server.createObject(&#8220;ADODB.Command&#8221;);<\/p>\n<p>command.ActiveConnection = &#8220;eksempel&#8221;;<\/p>\n<p>command.CommandText=&#8221;INSERT INTO tabel VALUES (&#8216;command&#8217;)&#8221;;<\/p>\n<p>&nbsp;<\/p>\n<p>command.execute();<\/p>\n<p>Response.write(&#8220;Data indsat.&#8221;);<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Den grundl\u00e6ggende teori bag databaser er nu blevet gennemg\u00e5et, ligesom de element\u00e6re objekter er blevet forklaret. De n\u00e6ste afsnit i dette kapitel vil beskrive, hvordan man i praksis kan bruge databaser sammen med ASP.<\/p>\n<h1>Selektion fra en database<\/h1>\n<p>En hyppig anvendelse af en database i forbindelse med web-applikationer er som opbevaring af information, som brugeren kan s\u00f8ge i. Dette kan dreje sig om prislister, ordb\u00f8ger, leksika, adresseoplysninger og meget andet. Eksemplerne i dette afsnit vil tage udgangspunkt i en \u2013 meget lille \u2013 dansk-engelsk ordbog. Ordbogen ligger i en database, der er registreret med DSN eksempel i en tabel ved navn ordbog. Tabellen indeholder kolonnerne dansk og engelsk, der henholdsvis indeholder det danske og det engelske ord.<\/p>\n<p>I introduktionen til SQL blev det n\u00e6vnt, at det er kommandoen SELECT, der bruges til at foresp\u00f8rge p\u00e5 data i en SQL-database.\u00a0 Hvis man eksempelvis vil udtr\u00e6kke det engelske ord svarende til det danske ord <em>bog<\/em>, bliver SQL-foresp\u00f8rgslen SELECT engelsk FROM ordbog WHERE dansk=&#8217;bog&#8217;.<\/p>\n<p>Det foreg\u00e5ende afsnit beskrev, hvordan man opretter databaseforbindelser. Forbindelsen til eksempel-databasen oprettes s\u00e5ledes:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;% @language=javascript %&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>connection.open(&#8220;eksempel&#8221;);<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Til at udf\u00f8re en SQL-foresp\u00f8rgsel bruges som n\u00e6vnt tidligere metoden execute. Tidligere var det nok blot at kalde execute-metoden med den SQL-foresp\u00f8rgsel, der skulle udf\u00f8res \u2013 det er det ikke i dette tilf\u00e6lde. N\u00e5r der foresp\u00f8rges efter data, skal man jo have resultatet af foresp\u00f8rgslen tilbage. Resultatet af foresp\u00f8rgslen returneres i en samling af poster \u2013 et RecordSet. Dette vil blive gennemg\u00e5et senere. Nedenst\u00e5ende kodelinie viser, hvordan man udf\u00f8rer foresp\u00f8rgslen og modtager resultatet.<\/p>\n<p>&nbsp;<\/p>\n<p>res = connection.execute(&#8220;SELECT engelsk FROM ordbog WHERE dansk=&#8217;bog'&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>RecordSet-objektet, der returneres af execute-metoden, indeholder en r\u00e6kke metoder og variable, der gennemg\u00e5s i f\u00f8lgende to tabeller.<\/p>\n<p>&nbsp;<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"326\" valign=\"top\">Metode<\/td>\n<td width=\"326\" valign=\"top\">Beskrivelse<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">AddNew<\/td>\n<td width=\"326\" valign=\"top\">Tilf\u00f8jer et ny post til s\u00e6ttet, hvis   s\u00e6ttet kan opdateres.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CancelBatch<\/td>\n<td width=\"326\" valign=\"top\">Annullerer en batch-opdatering.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CancelUpdate<\/td>\n<td width=\"326\" valign=\"top\">Annullerer \u00e6ndringer i den aktuelle   post eller nye poster.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Clone<\/td>\n<td width=\"326\" valign=\"top\">Opretter en kopi af det eksisterende RecordSet.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Close<\/td>\n<td width=\"326\" valign=\"top\">Lukker s\u00e6ttet.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Delete<\/td>\n<td width=\"326\" valign=\"top\">Sletter den aktuelle post i s\u00e6ttet,   hvis s\u00e6ttet er \u00e5bent.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">GetRows<\/td>\n<td width=\"326\" valign=\"top\">Overf\u00f8rer en del af r\u00e6kkerne i s\u00e6ttet   til et array.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Move<\/td>\n<td width=\"326\" valign=\"top\">Skifter den aktuelle post.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">MoveFirst<\/td>\n<td width=\"326\" valign=\"top\">G\u00f8r den f\u00f8rste post til den aktuelle   post.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">MoveLast<\/td>\n<td width=\"326\" valign=\"top\">G\u00f8r den sidste post til den aktuelle   post.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">MoveNext<\/td>\n<td width=\"326\" valign=\"top\">G\u00f8r den n\u00e6ste post til den aktuelle   post.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">MovePrevious<\/td>\n<td width=\"326\" valign=\"top\">G\u00f8r den forrige post til den aktuelle   post.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">NextRecordSet<\/td>\n<td width=\"326\" valign=\"top\">G\u00e5r videre til det n\u00e6ste RecordSet,   hvis foresp\u00f8rgslen har returneret flere s\u00e6t.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Open<\/td>\n<td width=\"326\" valign=\"top\">\u00c5bner det aktuelle s\u00e6t.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Requery<\/td>\n<td width=\"326\" valign=\"top\">Opdaterer s\u00e6ttet ved at udf\u00f8re   foresp\u00f8rgslen igen.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Resync<\/td>\n<td width=\"326\" valign=\"top\">Opdaterer s\u00e6ttet, men udf\u00f8rer ikke   foresp\u00f8rgslen igen. Dette opdaterer de eksisterende r\u00e6kker, men tilf\u00f8jer ikke   eventuelle nye r\u00e6kker.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Supports<\/td>\n<td width=\"326\" valign=\"top\">Unders\u00f8ger om s\u00e6ttet underst\u00f8tter   specifikke funktioner.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Update<\/td>\n<td width=\"326\" valign=\"top\">Gemmer eventuelle \u00e6ndringer i den   aktuelle post.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">UpdateBatch<\/td>\n<td width=\"326\" valign=\"top\">Skriver alle ventende opdateringer   til disken.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Tabel 5.6: Metoder i RecordSet-objektet.<\/p>\n<p>&nbsp;<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"326\" valign=\"top\">Variabel<\/td>\n<td width=\"326\" valign=\"top\">Beskrivelse<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">AbsolutePage<\/td>\n<td width=\"326\" valign=\"top\">Angiver positionen af den aktuelle   side.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">AbsolutePosition<\/td>\n<td width=\"326\" valign=\"top\">Angiver positionen af den aktuelle   post.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">ActiveConnection<\/td>\n<td width=\"326\" valign=\"top\">Angiver det connection-objekt,   der er brugt til at oprette s\u00e6ttet.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">BOF<\/td>\n<td width=\"326\" valign=\"top\">Angiver om den aktuelle post er f\u00f8r   den f\u00f8rste.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Bookmark<\/td>\n<td width=\"326\" valign=\"top\">Returnerer et bogm\u00e6rke, der   identificerer den nuv\u00e6rende position i s\u00e6ttet.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CacheSize<\/td>\n<td width=\"326\" valign=\"top\">Angiver antallet af poster i   hukommelsen.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">CursorLocation<\/td>\n<td width=\"326\" valign=\"top\">Angiver om mark\u00f8ren er p\u00e5 klienten   eller p\u00e5 serveren. Hvis mark\u00f8ren er p\u00e5 klienten, returneres adUseClient,   ellers returneres adUseServer.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">EditMode<\/td>\n<td width=\"326\" valign=\"top\">Angiver den aktuelle posts   redigeringstilstand.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">EOF<\/td>\n<td width=\"326\" valign=\"top\">Angiver om mark\u00f8ren er efter den   sidste post.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Filter<\/td>\n<td width=\"326\" valign=\"top\">Angiver et filter for s\u00e6ttet.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">LockType<\/td>\n<td width=\"326\" valign=\"top\">Angiver hvilken type l\u00e5se, der bruges   til at l\u00e5se posterne under redigering.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">MarshalOptions<\/td>\n<td width=\"326\" valign=\"top\">Angiver hvilke poster, der skal   sendes tilbage til serveren, n\u00e5r man bruger et resultats\u00e6t p\u00e5 klienten.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">MaxRecords<\/td>\n<td width=\"326\" valign=\"top\">Angiver det maksimale antal poster,   der skal returneres.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">PageCount<\/td>\n<td width=\"326\" valign=\"top\">Angiver antallet af sider i s\u00e6ttet.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">PageSize<\/td>\n<td width=\"326\" valign=\"top\">Angiver sidest\u00f8rrelsen i poster.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">RecordCount<\/td>\n<td width=\"326\" valign=\"top\">Angiver antallet af poster i s\u00e6ttet.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Source<\/td>\n<td width=\"326\" valign=\"top\">Angiver kildeteksten p\u00e5 den   foresp\u00f8rgsel, der resulterede i s\u00e6ttet.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">State<\/td>\n<td width=\"326\" valign=\"top\">Angiver om s\u00e6ttet er \u00e5bent eller   lukket.<\/td>\n<\/tr>\n<tr>\n<td width=\"326\" valign=\"top\">Status<\/td>\n<td width=\"326\" valign=\"top\">Angiver status p\u00e5 den aktuelle post.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Tabel 5.7: Variable i RecordSet-objektet.<\/p>\n<p>&nbsp;<\/p>\n<p>Udover de metoder og variabler, der er gennemg\u00e5et i ovenst\u00e5ende tabeller, indeholder RecordSet-objektet en samling ved navn Fields. Denne samling best\u00e5r af indholdet af kolonnerne i den aktuelle post. De enkelte celler kan tilg\u00e5s p\u00e5 to forskellige m\u00e5der: enten ved angive navnet p\u00e5 kolonnen eller ved at angive kolonnens placering i resultats\u00e6ttet.<\/p>\n<p>Hvordan man v\u00e6lger at tilg\u00e5 cellerne afh\u00e6nger af den applikation, man er ved at lave. Hvis man tilg\u00e5r cellerne ved hj\u00e6lp af kolonnens placering, g\u00f8r man applikationen uafh\u00e6ngig af navnene p\u00e5 kolonnerne \u2013 dette vil typisk v\u00e6re mere generelt end at bruge kolonnenavnene. At bruge kolonnenavnene har til geng\u00e6ld den fordel, at man ikke f\u00e5r problemer, hvis man tilf\u00f8jer eller fjerner en kolonne, s\u00e5 kolonnenumrene \u00e6ndres. Det er ogs\u00e5 lettere at forst\u00e5 kildeteksten, hvis kolonnernes navne st\u00e5r der i stedet for blot numrene.<\/p>\n<p>For at vise resultatet af det eksempel, der blev gennemg\u00e5et tidligere i dette afsnit, kan man bruge f\u00f8lgende kode:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Det danske ord &lt;b&gt;Bog&lt;\/b&gt; hedder &lt;b&gt;&lt;%= res.Fields(&#8220;engelsk&#8221;)%&gt;&lt;\/b&gt; p\u00e5 engelsk.<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Eksemplet viser, hvordan man kan tilg\u00e5 kolonnen ved hj\u00e6lp af dens navn. Som n\u00e6vnt kan man ogs\u00e5 bruge kolonnens position til at tilg\u00e5 dataene. Det viser nedenst\u00e5ende eksempel:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Det danske ord &lt;b&gt;Bog&lt;\/b&gt; hedder &lt;b&gt;&lt;%= res.Fields(0)%&gt;&lt;\/b&gt; p\u00e5 engelsk.<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Udover at kunne bruges til at tilg\u00e5 data med, kan Fields-samlingen ogs\u00e5 bruges til at f\u00e5 oplysninger om antallet af felter i posten. Det sker med count-variablen. Samlingen indeholder en samling ved navn Item \u2013 det er faktisk denne samling, der indeholder dataene fra posten. N\u00e5r man bruger Fields-samlingen til at tilg\u00e5 data i den aktuelle post, udnytter man, at Item-samlingen er standardsamlingen i Fields-samlingen \u2013 derfor kan man n\u00f8jes med at skrive Fields(<em>navn<\/em>) for at tilg\u00e5 cellerne.<\/p>\n<p>I ovenst\u00e5ende ekstempel indeholdt resultatet kun en enkelt post, men et RecordSet kan best\u00e5 af en lang r\u00e6kke poster. Til at angive hvilken post man \u00f8nsker at arbejde p\u00e5, bruges en mark\u00f8r. Hvis man forestiller sig resultatet som en liste af poster, kan man forestille sig mark\u00f8ren som en pil, der peger p\u00e5 den aktuelle post \u2013 det viser nedenst\u00e5ende figur:<\/p>\n<p>&nbsp;<\/p>\n<p>Post1<\/p>\n<p>Post2<\/p>\n<p>Post3 \u00df mark\u00f8r<\/p>\n<p>Post4<\/p>\n<p>Post5<\/p>\n<p>&nbsp;<\/p>\n<p>Hvis man udf\u00f8rer en metode p\u00e5 s\u00e6ttet, som arbejder p\u00e5 en enkelt post, vil den arbejde p\u00e5 den post, mark\u00f8ren peger p\u00e5. Som det fremg\u00e5r af metoderne i RecordSet-objektet, kan man bev\u00e6ge mark\u00f8ren til at pege p\u00e5 den post, man \u00f8nsker at arbejde p\u00e5. Man kan bruge variablen EOF til at se, om mark\u00f8ren er placeret efter den sidste post. Nedenst\u00e5ende eksempel viser, hvordan man ved hj\u00e6lp af MoveNext og EOF kan gennemg\u00e5 et s\u00e6t.<\/p>\n<p>&nbsp;<\/p>\n<p>while (!res.EOF) {<\/p>\n<p>\/\/ behandl den aktuelle post<\/p>\n<p>res.MoveNext();<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>I eksemplet fra f\u00f8r kunne man forestille sig, at man vil vide, hvad ordet <em>skat<\/em> hedder p\u00e5 engelsk. Her er der flere forskellige muligheder, og det er ASP-siden naturligvis n\u00f8dt til at h\u00e5ndtere. Nedenst\u00e5ende eksempel viser, hvordan det kan g\u00f8res:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;% @language=javascript %&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>connection.open(&#8220;eksempel&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>res = connection.execute(&#8220;SELECT engelsk FROM ordbog WHERE dansk=&#8217;skat'&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Det danske ord &lt;b&gt;Skat&lt;\/b&gt; kan p\u00e5 engelsk hedde:<\/p>\n<p>&lt;ol&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>while (!res.EOF) {<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;li&gt;&lt;b&gt;&lt;%=res.Fields(&#8220;engelsk&#8221;)%&gt;&lt;\/b&gt;&lt;\/li&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>res.MoveNext();<\/p>\n<p>}<\/p>\n<p>%&gt;<\/p>\n<p>&lt;\/ol&gt;<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<br \/>\n<script type=\"text\/javascript\"><!--\ngoogle_ad_client = \"ca-pub-3400894606969585\";\n\/* Bibliotek - ASP *\/\ngoogle_ad_slot = \"2386722770\";\ngoogle_ad_width = 336;\ngoogle_ad_height = 280;\n\/\/-->\n<\/script><br \/>\n<script type=\"text\/javascript\"\nsrc=\"http:\/\/pagead2.googlesyndication.com\/pagead\/show_ads.js\">\n<\/script><\/p>\n<h2>Sortering<\/h2>\n<p>Hvis man skal vise mange oplysninger ad gangen, er det som regel en god id\u00e9 at sortere dem. Selvom JavaScript er et forholdsvis begr\u00e6nset sprog, er det muligt at implementere de fleste sorteringsalgoritmer i det, men n\u00e5r man arbejder med databaser, kan det ikke anbefales. Dels er det omfattende at skrive algoritmerne i JavaScript, og dels er det ogs\u00e5 forholdsvis langsomt at afvikle. Det er meget lettere og v\u00e6sentligt mere effektivt at bruge sorteringsmulighederne i SQL.<\/p>\n<p>Som det blev beskrevet i introduktionen til SQL, kan man i en SELECT-foresp\u00f8rgsel angive, hvilken orden dataene skal sorteres i. Dette sker ved at f\u00f8je ORDER BY til foresp\u00f8rgslen.<\/p>\n<p>Hvis man for eksempel vil vise indholdet af hele ordbogen i eksemplet fra f\u00f8r, er det nok en god id\u00e9 at sortere ordene. Nedenst\u00e5ende eksempel viser, hvordan man kan vise ordene i alfabetisk orden. I eksemplet har brugeren selv mulighed for at v\u00e6lge, om det skal v\u00e6re de danske eller de engelske ord, der skal sorteres. Sorteringen \u00e6ndres ved at klikke p\u00e5 overskriften.<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;% @language=javascript %&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>connection.open(&#8220;eksempel&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>sql = &#8220;SELECT * FROM ordbog ORDER BY &#8220;;<\/p>\n<p>if (Request.QueryString(&#8220;sprog&#8221;) == &#8220;engelsk&#8221;) {<\/p>\n<p>sql += &#8220;engelsk&#8221;;<\/p>\n<p>} else {<\/p>\n<p>sql += &#8220;dansk&#8221;;<\/p>\n<p>}<\/p>\n<p>res = connection.execute(sql);<\/p>\n<p>&nbsp;<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>&lt;table&gt;<\/p>\n<p>&lt;thead&gt;<\/p>\n<p>&lt;th&gt;&lt;a href=ordbog.asp?sprog=dansk&gt;Dansk&lt;\/a&gt;&lt;\/th&gt;<\/p>\n<p>&lt;th&gt;&lt;a href=ordbog.asp?sprog=engelsk&gt;Engelsk&lt;\/a&gt;&lt;\/th&gt;<\/p>\n<p>&lt;\/thead&gt;<\/p>\n<p>&lt;tbody&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>while (!res.EOF) {<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td&gt;&lt;%=res.Fields(&#8220;dansk&#8221;)%&gt;&lt;\/td&gt;<\/p>\n<p>&lt;td&gt;&lt;%=res.Fields(&#8220;engelsk&#8221;)%&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>res.MoveNext();<\/p>\n<p>}<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0504.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-510\" title=\"0504\" src=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0504.png\" alt=\"\" width=\"377\" height=\"435\" srcset=\"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0504.png 377w, https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0504-260x300.png 260w\" sizes=\"auto, (max-width: 377px) 100vw, 377px\" \/><\/a><\/p>\n<p>Figur 5.4: Indholdet af ordbogen.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Eksemplet kontrollerer, om parameteren sprog er sat til engelsk. Hvis dette er tilf\u00e6ldet, betyder det, at oversigten skal sorteres efter de engelske ord. Er den ikke sat til engelsk, betyder det enten, at parameteren slet ikke er sat, eller at den er sat til dansk; i begge tilf\u00e6lde skal oversigten sorteres efter de danske ord.<\/p>\n<p>&nbsp;<\/p>\n<h2>Lad brugeren v\u00e6lge<\/h2>\n<p>Det forrige eksempel tog hul p\u00e5 emnet at lade brugeren v\u00e6lge. For det er naturligvis oftest brugeren, der direkte eller indirekte bestemmer, hvilke data der skal foresp\u00f8rges p\u00e5 i databasen.<\/p>\n<p>N\u00e5r det er en bruger af web-stedet, der er med til at bestemme foresp\u00f8rgslen, er der en r\u00e6kke ting, man skal tage h\u00f8jde for. Man kan for eksempel ikke v\u00e6re sikker p\u00e5, at der bliver fundet poster, ligesom man skal kontrollere, at brugeren har indtastet noget gyldigt. Forventer databasen eksempelvis en numerisk v\u00e6rdi, nytter det ikke meget, at man giver den en tekst, blot fordi brugeren har indtastet bogstaver i stedet for tal.<\/p>\n<p>I dette afsnit vil ordbogseksemplet blive udvidet, s\u00e5 brugeren f\u00e5r mulighed for at indtaste, hvilket ord der skal sl\u00e5s op, og v\u00e6lge hvilket sprog opslaget skal foretages p\u00e5. Eksemplet best\u00e5r af en HTML-side, der indeholder den formular, brugeren udfylder, og en ASP-side, der genererer svaret.<\/p>\n<p>Kildeteksten til HTML -dokumentet ser s\u00e5ledes ud:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>&lt;b&gt;Online ordbog&lt;\/b&gt;&lt;br&gt;<\/p>\n<p>&lt;form action=opslag.asp method=get&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;table&gt;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td&gt;V\u00e6lg m\u00e5de&lt;\/td&gt;<\/p>\n<p>&lt;td&gt;Indtast ord&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td&gt;<\/p>\n<p>&lt;select name = sprog&gt;<\/p>\n<p>&lt;option value=dansk&gt;Fra dansk til engelsk&lt;\/option&gt;<\/p>\n<p>&lt;option value=engelsk&gt;Fra engelsk til dansk&lt;\/option&gt;<\/p>\n<p>&lt;\/td&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;td&gt;<\/p>\n<p>&lt;input type=text name=ord&gt;<\/p>\n<p>&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td colspan=2 align=center&gt;<\/p>\n<p>&lt;input type=submit value=&#8221;Sl\u00e5 op&#8221;&gt;<\/p>\n<p>&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&lt;\/table&gt;<\/p>\n<p>&lt;\/form&gt;<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Ovenst\u00e5ende HTML-kode giver et billede svarende til figur5.5.<\/p>\n<p><a href=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0505.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-509\" title=\"0505\" src=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0505.png\" alt=\"\" width=\"377\" height=\"435\" srcset=\"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0505.png 377w, https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0505-260x300.png 260w\" sizes=\"auto, (max-width: 377px) 100vw, 377px\" \/><\/a><\/p>\n<p>Figur 5.5: Online-ordbog.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Siden kalder opslag.asp med to parametre: parameteren sprog kan enten v\u00e6re dansk eller engelsk. Parameteren ord angiver det ord, der skal sl\u00e5s op p\u00e5 det p\u00e5g\u00e6ldende sprog.<\/p>\n<p>Kildeteksten til opslag.asp ser s\u00e5ledes ud:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;% @language=JavaScript %&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>connection.open(&#8220;eksempel&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>if (Request.QueryString(&#8220;sprog&#8221;) == &#8220;dansk&#8221;) {<\/p>\n<p>sql = &#8220;SELECT engelsk FROM ordbog WHERE dansk ='&#8221; + Request.QueryString(&#8220;ord&#8221;) + &#8220;&#8216;&#8221;;<\/p>\n<p>} else {<\/p>\n<p>sql = &#8220;SELECT dansk FROM ordbog WHERE engelsk ='&#8221; + Request.QueryString(&#8220;ord&#8221;) + &#8220;&#8216;&#8221;;<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>res = connection.Execute(sql);<\/p>\n<p>&nbsp;<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Ordet &lt;b&gt;&lt;%=Request.QueryString(&#8220;ord&#8221;)%&gt;&lt;\/b&gt; kan betyde<\/p>\n<p>&lt;ol&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>while (!res.EOF) {<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;li&gt;&lt;b&gt;&lt;%= res.Fields(0)%&gt;&lt;\/b&gt;&lt;\/li&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>res.MoveNext();<\/p>\n<p>}<\/p>\n<p>%&gt;<\/p>\n<p>&lt;\/ol&gt;<\/p>\n<p>&lt;p&gt;<\/p>\n<p>&lt;a href = opslag.html&gt;Tilbage&lt;\/a&gt;<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>I denne form h\u00e5ndterer siden ikke nogen af de problemer, der kan opst\u00e5, hvis brugeren indtaster anden data, end ASP-siden forventer. Hvis brugeren indtaster et ord, der ikke findes, vil der blive vist en side, der ser ret uheldig ud.<\/p>\n<p>Hvis man vil kontrollere, om en foresp\u00f8rgsel giver et resultat, kan man kontrollere, om EOF er sand umiddelbart efter foresp\u00f8rgslen er foretaget. Hvis denne \u00e6ndring skal indf\u00f8res i forrige eksempel, kommer kildeteksten til at se s\u00e5ledes ud:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;% @language=JavaScript %&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>connection.open(&#8220;eksempel&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>if (Request.QueryString(&#8220;sprog&#8221;) == &#8220;dansk&#8221;) {<\/p>\n<p>sql = &#8220;SELECT engelsk FROM ordbog WHERE dansk ='&#8221; + Request.QueryString(&#8220;ord&#8221;) + &#8220;&#8216;&#8221;;<\/p>\n<p>} else {<\/p>\n<p>sql = &#8220;SELECT dansk FROM ordbog WHERE engelsk ='&#8221; + Request.QueryString(&#8220;ord&#8221;) + &#8220;&#8216;&#8221;;<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>res = connection.Execute(sql);<\/p>\n<p>&nbsp;<\/p>\n<p>if (res.EOF) {<\/p>\n<p>%&gt;<\/p>\n<p>Ordet &lt;b&gt;&lt;%=Request.QueryString(&#8220;ord&#8221;)%&gt;&lt;\/b&gt; kunne desv\u00e6rre ikke findes i ordbogen.<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>} else {<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Ordet &lt;b&gt;&lt;%=Request.QueryString(&#8220;ord&#8221;)%&gt;&lt;\/b&gt; kan betyde<\/p>\n<p>&lt;ol&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>while (!res.EOF) {<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;li&gt;&lt;b&gt;&lt;%= res.Fields(0)%&gt;&lt;\/b&gt;&lt;\/li&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>res.MoveNext();<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>%&gt;<\/p>\n<p>&lt;\/ol&gt;<\/p>\n<p>&lt;p&gt;<\/p>\n<p>&lt;a href = opslag.html&gt;Tilbage&lt;\/a&gt;<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Der er ogs\u00e5 et andet problem, der skal h\u00e5ndteres. Det er brugerens indtastninger. I dette eksempel er det ikke n\u00f8dvendigt at kontrollere, om det er tal eller bogstaver, der bliver indtastet \u2013 systemet kan h\u00e5ndtere begge dele. Der er dog et problem, hvis brugeren eksempelvis indtaster en apostrof (&#8216;). Apostroffer er en del af SQL-syntaksen, og m\u00e5 derfor ikke indg\u00e5 i den tekst, der skal s\u00f8ges efter. Derfor er det en god ide med en metode, der fjerner eventuelle apostroffer fra opslagsordet. Denne funktionalitet kan implementeres p\u00e5 mange forskellige m\u00e5der \u2013 nedenst\u00e5ende metode er blot et eksempel p\u00e5, hvordan funktionaliteten kan implementeres:<\/p>\n<p>&nbsp;<\/p>\n<p>function checkInput(s) {<\/p>\n<p>t = &#8220;&#8221;;<\/p>\n<p>s = &#8220;&#8221; + s;<\/p>\n<p>for (i = 0; i &lt; s.length; i++) {<\/p>\n<p>if (s.charAt(i) != &#8220;&#8216;&#8221;) {<\/p>\n<p>t += s.charAt(i);<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>}<\/p>\n<p>return t;<\/p>\n<p>}<\/p>\n<h1>Publicering til databasen<\/h1>\n<p>At hente oplysninger ud af databasen er naturligvis kun en del af at bruge databaser. Det ville jo v\u00e6re rart, hvis man ogs\u00e5 kunne tilf\u00f8je oplysninger til databasen fra web-stedet. Det kan man blandt andet bruge til selv at opdatere databasen via web-stedet, og man kan ogs\u00e5 bruge teknikken til at lade bes\u00f8gende p\u00e5 web-stedet indsende oplysninger, der kan gemmes i databasen.<\/p>\n<p>I dette eksempel vil det b\u00e5de blive gennemg\u00e5et, hvordan man gemmer en formular i databasen, og hvordan man laver statistik over web-stedet.<\/p>\n<p>&nbsp;<\/p>\n<h2>Statistik<\/h2>\n<p>En statistik p\u00e5 et web-sted kan registrere en lang r\u00e6kke ting. Det kan eksempelvis v\u00e6re oplysninger om de bes\u00f8gendes IP-adresser, bes\u00f8gstidspunkter, brugernavn og lignende. I dette eksempel vil der for simpelhedens skyld kun blive registreret, hvilke sider brugeren bes\u00f8ger.<\/p>\n<p>Statistiksystemet opbygges omkring en funktion, der registrerer et bes\u00f8g p\u00e5 en given side. Denne funktion skal indeholde en identifikation af siden. I dette eksempel vil det v\u00e6re adressen p\u00e5 siden. Statistikfunktionen skal kaldes fra alle sider p\u00e5 web-stedet.<\/p>\n<p>Statistikfunktionen registrerer bes\u00f8get i databasen. Databasen indeholder en tabel, der har en post for hver side p\u00e5 web-stedet.<\/p>\n<p>Den funktion, der registrerer bes\u00f8gende p\u00e5 web-stedet, kan se s\u00e5ledes ud:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;% @language=javascript %&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>function stat(id) {<\/p>\n<p>connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>connection.open(&#8220;eksempel&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>res = connection.Execute(&#8220;SELECT antal FROM statistik WHERE side = &#8216;&#8221; + id + &#8220;&#8216;&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>antal = res.fields(&#8220;antal&#8221;);<\/p>\n<p>antal++;<\/p>\n<p>&nbsp;<\/p>\n<p>connection.Execute(&#8220;UPDATE statistik SET antal=&#8221; + antal + &#8221; WHERE side = &#8216;&#8221; + id + &#8220;&#8216;&#8221;);<\/p>\n<p>return antal;<\/p>\n<p>}<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Funktionen starter med at l\u00e6se, hvor mange gange siden allerede er blevet bes\u00f8gt. Dette g\u00f8res ved at tage indholdet af antal-kolonnen i databasen i den r\u00e6kke, hvor siden svarer til det id, der er givet med som parameter til funktionen. Dern\u00e6st t\u00e6lles antallet op, og indholdet af databasen bliver opdateret. Metoden returnerer det aktuelle antal bes\u00f8gende p\u00e5 siden, s\u00e5 man har mulighed for at arbejde videre med tallet og eventuelt vise det til de bes\u00f8gende.<\/p>\n<p>Nedenst\u00e5ende kildetekst viser, hvordan kaldet til statistik-funktionen kan implementeres i et ASP-dokument:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>Denne side er blevet bes\u00f8gt &lt;%= stat(&#8220;statistik.asp&#8221;)%&gt; gange.<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>At indsamle oplysningerne til statistikken er imidlertid kun halvdelen af arbejdet. Oplysningerne skal ogs\u00e5 kunne vises. Typisk vil man kunne sortere og gruppere statistikken efter alle de oplysninger, der er indsamlet. I dette eksempel er det imidlertid ikke n\u00f8dvendigt, da der som n\u00e6vnt kun indsamles en enkelt oplysning. Siden til at vise statistikken giver derfor kun mulighed for at vise antal bes\u00f8gende pr. side, samt en total opt\u00e6lling.<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;% @language = javascript %&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;h1&gt;Statistik&lt;\/h1&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;table&gt;<\/p>\n<p>&lt;thead&gt;<\/p>\n<p>&lt;th align=left&gt;Side&lt;\/th&gt;<\/p>\n<p>&lt;th align=right&gt;Antal bes\u00f8gende&lt;\/th&gt;<\/p>\n<p>&lt;\/thead&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>connection = Server.CreateObject(&#8220;ADODB.Connection&#8221;);<\/p>\n<p>connection.open(&#8220;eksempel&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>res = connection.Execute(&#8220;SELECT * FROM statistik ORDER BY antal DESC&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>while (!res.EOF) {<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td&gt;&lt;%=res.fields(&#8220;side&#8221;)%&gt;&lt;\/td&gt;<\/p>\n<p>&lt;td align=right&gt;&lt;%=res.fields(&#8220;antal&#8221;)%&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;%<\/p>\n<p>res.MoveNext();<\/p>\n<p>}<\/p>\n<p>%&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;\/table&gt;<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>ASP-siden foresp\u00f8rger p\u00e5 indholdet af statistik-tabellen og pr\u00e6senterer indholdet i en tabel sorteret, s\u00e5 den side med flest bes\u00f8gende vises \u00f8verst p\u00e5 listen.<\/p>\n<p>&nbsp;<\/p>\n<h2>At gemme en formular<\/h2>\n<p>Man vil ofte have brug for at lade web-stedets g\u00e6ster indsende oplysninger, der gemmes i databasen. Det kan eksempelvis v\u00e6re tilmelding til en mailingliste, bestilling af varer eller oplysninger eller noget helt andet. I dette afsnit vil der blive taget udgangspunkt i et ASP-program, der simulerer en g\u00e6stebog, som brugeren kan indtaste oplysninger i.<\/p>\n<p>N\u00e5r man designer databasen og den HTML-formular, dens oplysninger skal indtastes i, b\u00f8r man t\u00e6nke p\u00e5, at de to dele skal arbejde sammen. Hvis man bruger forskellige navne til oplysninger i formularen og i databasen, skal man i ASP-siden konvertere mellem de to navne. Derfor kan man med fordel bruge det samme navn begge steder.<\/p>\n<p>Tabellen i dette eksempel indeholder felterne navn, email, overskrift og tekst. Disse oplysninger skal brugeren indtaste for at skrive i g\u00e6stebogen. Nedenst\u00e5ende kildetekst viser, hvordan HTML-siden til indtastning af oplysninger kan laves.<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>&lt;h1&gt;Skriv i g\u00e6stebogen&lt;\/h1&gt;<\/p>\n<p>For at skrive i g\u00e6stebogen skal du indtaste f\u00f8lgende oplysninger:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;form action=guest.asp method=post&gt;<\/p>\n<p>&lt;table&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td&gt;Dit navn&lt;\/td&gt;<\/p>\n<p>&lt;td&gt;&lt;input type=text name=navn size=50&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td&gt;Din e-mail-adresse&lt;\/td&gt;<\/p>\n<p>&lt;td&gt;&lt;input type=text name=email size=50&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td&gt;Overskrift&lt;\/td&gt;<\/p>\n<p>&lt;td&gt;&lt;input type=text name=overskrift size=50&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td valign=top&gt;Besked&lt;\/td&gt;<\/p>\n<p>&lt;td&gt;&lt;textarea name=tekst cols=50 rows=10&gt;&lt;\/textarea&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td colspan=2 align=center&gt;&lt;input type=submit value=&#8221;Indsend&#8221;&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;\/table&gt;<\/p>\n<p>&lt;\/form&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Ovenst\u00e5ende kildetekst giver en HTML-side som den i figur 5.6.<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0506.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-508\" title=\"0506\" src=\"http:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0506-300x288.png\" alt=\"\" width=\"300\" height=\"288\" srcset=\"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0506-300x288.png 300w, https:\/\/www.kristiansborg.dk\/bibliotek\/wp-content\/uploads\/2011\/11\/0506.png 617w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Figur 5.6: HTML-side til indtastning af oplysninger til g\u00e6stebog.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Der skal naturligvis en ASP-side til at h\u00e5ndtere de indsendte oplysninger. I dette tilf\u00e6lde hedder siden guest.asp, og i kildeteksten til siden kan man se fordelen ved at bruge de samme navne i HTML-formularen og tabellen. Kildeteksten ser s\u00e5ledes ud:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;html&gt;<\/p>\n<p>&lt;body&gt;<\/p>\n<p>&lt;h1&gt;Skriv i g\u00e6stebogen&lt;\/h1&gt;<\/p>\n<p>For at skrive i g\u00e6stebogen skal du indtaste f\u00f8lgende oplysninger:<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;form action=guest.asp method=post&gt;<\/p>\n<p>&lt;table&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td&gt;Dit navn&lt;\/td&gt;<\/p>\n<p>&lt;td&gt;&lt;input type=text name=navn size=50&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td&gt;Din e-mail-adresse&lt;\/td&gt;<\/p>\n<p>&lt;td&gt;&lt;input type=text name=email size=50&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td&gt;Overskrift&lt;\/td&gt;<\/p>\n<p>&lt;td&gt;&lt;input type=text name=overskrift size=50&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td valign=top&gt;Besked&lt;\/td&gt;<\/p>\n<p>&lt;td&gt;&lt;textarea name=tekst cols=50 rows=10&gt;&lt;\/textarea&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;tr&gt;<\/p>\n<p>&lt;td colspan=2 align=center&gt;&lt;input type=submit value=&#8221;Indsend&#8221;&gt;&lt;\/td&gt;<\/p>\n<p>&lt;\/tr&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;\/table&gt;<\/p>\n<p>&lt;\/form&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&lt;\/body&gt;<\/p>\n<p>&lt;\/html&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>Som n\u00e6vnt tidligere udnytter ASP-siden, at navnene i formularen og tabellen er ens. ASP-siden beh\u00f8ver derfor slet ikke have kendskab til navnene \u2013 den beh\u00f8ver blot at opdatere tabellen med de felter, siden modtager som parametre.<\/p>\n<p>Rent praktisk g\u00f8res dette ved hj\u00e6lp af en Enumeration, som kan bruges til at g\u00e5 igennem alle de parametre, der gives til siden. Disse bruges til at bygge den SQL-foresp\u00f8rgsel, der tilf\u00f8jer oplysningerne til databasen.<\/p>\n<h1>Sammenfatning<\/h1>\n<p>I dette kapitel er databaseadgang fra ASP blevet gennemg\u00e5et. F\u00f8r man begynder at bruge databaser, er det imidlertid en god id\u00e9 at have et kendskab til SQL, og derfor indledtes dette kapitel med en kort introduktion til SQL.<\/p>\n<p>Dern\u00e6st blev det beskrevet, hvordan man s\u00e6tter serveren op til at kunne tilg\u00e5 en database ved hj\u00e6lp af ODBC.<\/p>\n<p>Da det grundl\u00e6ggende var p\u00e5 plads, blev det gennemg\u00e5et, hvordan man skriver databaseprogrammer i ASP. Det blev b\u00e5de gennemg\u00e5et, hvordan man udv\u00e6lger data fra en database, og hvordan man inds\u00e6tter data.<\/p>\n<div style=\"border: 1px solid red; color: red\">\n<p><b>Du l\u00e6ser en gammel bog<\/b><\/p>\n<p>Den bog, du l\u00e6ser her, er fra 1999, og mange ting kan have \u00e6ndret sig siden da.<br \/>\nVi h\u00e5ber, at du stadig kan finde relevant information i den.<br \/>\nHvis du vil l\u00e6se aktuelle oplysninger om den aktuelle version af ASP.NET, anbefaler vi<br \/>\nbogen <a href=\"http:\/\/clk.tradedoubler.com\/click?p(197229)a(2029446)g(19172914)url(http:\/\/www.adlibris.com\/dk\/product.aspx?isbn=0735643385)\" onclick=\"javascript:pageTracker._trackPageview('\/outbound\/article\/http:\/\/clk.tradedoubler.com\/click?p(197229)a(2029446)g(19172914)url(http:\/\/www.adlibris.com\/dk\/product.aspx?isbn=0735643385)');\"  target=\"_blank\">Programming ASP.NET 4.0<\/a><img decoding=\"async\" src=\"http:\/\/impdk.tradedoubler.com\/imp?type(inv)g(19172914)a(2029446)\" \/>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>En af de mest udbredte anvendelser af ASP er til pr\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\u00e5 data i en database. Databaseforesp\u00f8rgslerne er baseret p\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget. Dern\u00e6st bliver det gennemg\u00e5et, hvordan [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":452,"menu_order":50,"comment_status":"closed","ping_status":"open","template":"","meta":{"_monsterinsights_skip_tracking":false,"footnotes":""},"class_list":["post-507","page","type-page","status-publish","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"En af de mest udbredte anvendelser af ASP er til pr\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\u00e5 data i en database. Databaseforesp\u00f8rgslerne er baseret p\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"keywords\" content=\"asp,database,sql,access,odbc,mysql,oracle,connection,password,brugernavn,g\u00e6stebog,dsn\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Biblioteket | Samling af artikler og b\u00f8ger\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Databaser og ASP | Biblioteket\" \/>\n\t\t<meta property=\"og:description\" content=\"En af de mest udbredte anvendelser af ASP er til pr\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\u00e5 data i en database. Databaseforesp\u00f8rgslerne er baseret p\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2011-11-18T06:27:02+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2011-11-18T06:28:45+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Databaser og ASP | Biblioteket\" \/>\n\t\t<meta name=\"twitter:description\" content=\"En af de mest udbredte anvendelser af ASP er til pr\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\u00e5 data i en database. Databaseforesp\u00f8rgslerne er baseret p\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/active-server-pages\\\/kapitel-5-databaser-og-asp\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/#listItem\",\"name\":\"B\\u00f8ger\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/#listItem\",\"position\":2,\"name\":\"B\\u00f8ger\",\"item\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/active-server-pages\\\/#listItem\",\"name\":\"Active Server Pages\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/active-server-pages\\\/#listItem\",\"position\":3,\"name\":\"Active Server Pages\",\"item\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/active-server-pages\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/active-server-pages\\\/kapitel-5-databaser-og-asp\\\/#listItem\",\"name\":\"Kapitel 5 Databaser og ASP\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/#listItem\",\"name\":\"B\\u00f8ger\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/active-server-pages\\\/kapitel-5-databaser-og-asp\\\/#listItem\",\"position\":4,\"name\":\"Kapitel 5 Databaser og ASP\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/active-server-pages\\\/#listItem\",\"name\":\"Active Server Pages\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/#organization\",\"name\":\"Biblioteket\",\"description\":\"Samling af artikler og b\\u00f8ger\",\"url\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/active-server-pages\\\/kapitel-5-databaser-og-asp\\\/#webpage\",\"url\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/active-server-pages\\\/kapitel-5-databaser-og-asp\\\/\",\"name\":\"Databaser og ASP | Biblioteket\",\"description\":\"En af de mest udbredte anvendelser af ASP er til pr\\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\\u00e5 data i en database. Databaseforesp\\u00f8rgslerne er baseret p\\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget.\",\"inLanguage\":\"da-DK\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/b%c3%b8ger\\\/active-server-pages\\\/kapitel-5-databaser-og-asp\\\/#breadcrumblist\"},\"datePublished\":\"2011-11-18T08:27:02+02:00\",\"dateModified\":\"2011-11-18T08:28:45+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/#website\",\"url\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/\",\"name\":\"Biblioteket\",\"description\":\"Samling af artikler og b\\u00f8ger\",\"inLanguage\":\"da-DK\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.kristiansborg.dk\\\/bibliotek\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Databaser og ASP | Biblioteket","description":"En af de mest udbredte anvendelser af ASP er til pr\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\u00e5 data i en database. Databaseforesp\u00f8rgslerne er baseret p\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget.","canonical_url":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/","robots":"max-image-preview:large","keywords":"asp,database,sql,access,odbc,mysql,oracle,connection,password,brugernavn,g\u00e6stebog,dsn","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.kristiansborg.dk\/bibliotek#listItem","position":1,"name":"Home","item":"https:\/\/www.kristiansborg.dk\/bibliotek","nextItem":{"@type":"ListItem","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/#listItem","name":"B\u00f8ger"}},{"@type":"ListItem","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/#listItem","position":2,"name":"B\u00f8ger","item":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/#listItem","name":"Active Server Pages"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.kristiansborg.dk\/bibliotek#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/#listItem","position":3,"name":"Active Server Pages","item":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/#listItem","name":"Kapitel 5 Databaser og ASP"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/#listItem","name":"B\u00f8ger"}},{"@type":"ListItem","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/#listItem","position":4,"name":"Kapitel 5 Databaser og ASP","previousItem":{"@type":"ListItem","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/#listItem","name":"Active Server Pages"}}]},{"@type":"Organization","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/#organization","name":"Biblioteket","description":"Samling af artikler og b\u00f8ger","url":"https:\/\/www.kristiansborg.dk\/bibliotek\/"},{"@type":"WebPage","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/#webpage","url":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/","name":"Databaser og ASP | Biblioteket","description":"En af de mest udbredte anvendelser af ASP er til pr\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\u00e5 data i en database. Databaseforesp\u00f8rgslerne er baseret p\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget.","inLanguage":"da-DK","isPartOf":{"@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/#website"},"breadcrumb":{"@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/#breadcrumblist"},"datePublished":"2011-11-18T08:27:02+02:00","dateModified":"2011-11-18T08:28:45+02:00"},{"@type":"WebSite","@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/#website","url":"https:\/\/www.kristiansborg.dk\/bibliotek\/","name":"Biblioteket","description":"Samling af artikler og b\u00f8ger","inLanguage":"da-DK","publisher":{"@id":"https:\/\/www.kristiansborg.dk\/bibliotek\/#organization"}}]},"og:locale":"da_DK","og:site_name":"Biblioteket | Samling af artikler og b\u00f8ger","og:type":"article","og:title":"Databaser og ASP | Biblioteket","og:description":"En af de mest udbredte anvendelser af ASP er til pr\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\u00e5 data i en database. Databaseforesp\u00f8rgslerne er baseret p\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget.","og:url":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/","article:published_time":"2011-11-18T06:27:02+00:00","article:modified_time":"2011-11-18T06:28:45+00:00","twitter:card":"summary","twitter:title":"Databaser og ASP | Biblioteket","twitter:description":"En af de mest udbredte anvendelser af ASP er til pr\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\u00e5 data i en database. Databaseforesp\u00f8rgslerne er baseret p\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget."},"aioseo_meta_data":{"post_id":"507","title":"Databaser og ASP | #site_title","description":"En af de mest udbredte anvendelser af ASP er til pr\u00e6sentation af data, der ligger i en database. I dette kapitel vil det blive beskrevet, hvordan man fra ASP kan tilg\u00e5 data i en database. Databaseforesp\u00f8rgslerne er baseret p\u00e5 SQL, og kapitlet starter derfor med en kort introduktion til SQL-sproget.","keywords":[{"label":"ASP","value":"ASP"},{"label":"Database","value":"Database"},{"label":"SQL","value":"SQL"},{"label":"Access","value":"Access"},{"label":"ODBC","value":"ODBC"},{"label":"MySQL","value":"MySQL"},{"label":"Oracle","value":"Oracle"},{"label":"Connection","value":"Connection"},{"label":"password","value":"password"},{"label":"brugernavn,g\u00e6stebog","value":"brugernavn,g\u00e6stebog"},{"label":"DSN","value":"DSN"}],"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[],"defaultGraph":"","defaultPostTypeGraph":""},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2020-12-21 06:59:15","updated":"2025-06-04 02:19:25","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.kristiansborg.dk\/bibliotek\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/\" title=\"B\u00f8ger\">B\u00f8ger<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/\" title=\"Active Server Pages\">Active Server Pages<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tKapitel 5 Databaser og ASP\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.kristiansborg.dk\/bibliotek"},{"label":"B\u00f8ger","link":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/"},{"label":"Active Server Pages","link":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/"},{"label":"Kapitel 5 Databaser og ASP","link":"https:\/\/www.kristiansborg.dk\/bibliotek\/b%c3%b8ger\/active-server-pages\/kapitel-5-databaser-og-asp\/"}],"_links":{"self":[{"href":"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-json\/wp\/v2\/pages\/507","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-json\/wp\/v2\/comments?post=507"}],"version-history":[{"count":3,"href":"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-json\/wp\/v2\/pages\/507\/revisions"}],"predecessor-version":[{"id":515,"href":"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-json\/wp\/v2\/pages\/507\/revisions\/515"}],"up":[{"embeddable":true,"href":"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-json\/wp\/v2\/pages\/452"}],"wp:attachment":[{"href":"https:\/\/www.kristiansborg.dk\/bibliotek\/wp-json\/wp\/v2\/media?parent=507"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}