Hopp til innhold
NorscodeNorscode

Lagre og hente data

EksempelAv Norscode-prosjektet

Opprett en tabell, skriv rader og les dem ut igjen — med de innebygde databasefunksjonene, og uten ett spørsmål per rad.

Databasefunksjonene ligger i selve kjøretiden, så du trenger ingen ekstern driver. Du åpner en fil, kjører SQL, og lukker.

bruk src.kjerne.noformat som nf

funksjon start() -> heltall {
    la conn = db.open("notat.db")
    db.execute(conn, "CREATE TABLE IF NOT EXISTS notat (id INTEGER PRIMARY KEY, tekst TEXT NOT NULL);")

    la notatet = "Handle melk"
    db.execute(conn, "INSERT INTO notat (tekst) VALUES (" + nf.sql_text(notatet) + ");")

    la antall = db.query_int(conn, "SELECT COUNT(*) FROM notat;")
    skriv("Notater: " + tekst(antall))
    db.close(conn)
    returner 0
}

Hva som skjer her

db.open åpner — eller oppretter — en databasefil. Mønsteret med å opprette tabellen bare hvis den ikke finnes, gjør at programmet kan kjøres om igjen uten å feile på at tabellen allerede er der. Det er mønsteret du vil ha i alt som skal kjøre mer enn én gang.

Merk nf.sql_text rundt verdien. Uten den ville en tekst som inneholder et enkelt anførselstegn brekke SQL-setningen — i beste fall med en feil, i verste fall som en injeksjon der noen andre bestemmer hva spørringen gjør. Regelen er den samme som for HTML: aldri lim brukerdata rett inn i strukturert tekst.

db.query_int er for spørringer som gir ett tall. Det finnes en tilsvarende db.query_text for én tekstverdi. Begge er tynne, men dekker overraskende mye når du kombinerer dem med SQL som gjør arbeidet.

Hent mange rader i ett spørsmål

la raa = db.query_text(conn, "SELECT group_concat(id || char(9) || tekst, char(10)) FROM notat;")
la rader = builtin.split(raa, "\n")
la i = 0
mens i < lengde(rader) {
    la felt = builtin.split(rader[i], "\t")
    hvis lengde(felt) == 2 { skriv(felt[0] + ": " + felt[1]) }
    i = i + 1
}

Hvorfor ikke en løkke med én spørring per rad

Dette er den viktigste vanen å lære tidlig. Det nærliggende er å hente antall rader, og så hente rad null, rad én, rad to. Det gir ett spørsmål mot basen per rad, og hvert av dem har en fast kostnad. Med ti rader merker du ingenting. Med ti tusen tar det minutter.

Mønsteret over gjør i stedet alt arbeidet i SQL. Funksjonen group_concat setter sammen hele resultatet til én streng, med tabulator mellom feltene og linjeskift mellom radene. Norscode får tilbake én streng og deler den opp. Ett spørsmål, uansett hvor mange rader.

Vær oppmerksom på en felle: dersom tekstkolonnene selv kan inneholde tabulator eller linjeskift, må du skrubbe dem ut i SQL-en før sammenslåingen, ellers ryker oppdelingen. En nøstet replace som bytter begge tegnene mot mellomrom gjør jobben.

Les også

Tilbake til oversikten