#!/usr/bin/env perl use v5.38; use DBI; my $memory; # = ':memory:'; my $dbname = $memory // '/Users/chap/private/data/music'; my $dbh = create_database(); # insert some songs. watch out for dupes. for my $song (qw{ Alpha Beta Gamma Alpha Delta Omicron }) { my $rowid = insert_unique( 'Songs', 'song', $song ); say "Inserting '$song', got rowid=$rowid"; } sub create_database() { unlink $dbname unless $memory; my $dbms = 'SQLite'; my $dbname = $dbname; my $user = ''; my $passwd = ''; my $dbh = DBI->connect( "DBI:$dbms:dbname=$dbname", $user, $passwd, { RaiseError => 1, AutoCommit => 1 } ) or die "Cannot connect: $DBI::errstr"; my $songs = <<~'EOF'; CREATE TABLE Songs (id INTEGER PRIMARY KEY, song VARCHAR(40) UNIQUE ) EOF $dbh->do($songs); $dbh->do("CREATE INDEX ix_song ON Songs (song)"); return $dbh; } # sub which conditionally inserts a unique value, and returns rowid sub insert_unique( $table, $column, $value ) { state %sths; # cache my prepared statement handles if ( !exists $sths{$table} ) { $sths{$table}{SELECT} = $dbh->prepare("SELECT id FROM $table WHERE $column = (?)"); $sths{$table}{INSERT} = $dbh->prepare("INSERT INTO $table ($column) VALUES (?)"); } my $rowid = $sths{$table}{SELECT}->execute($value) || die; say "Value='$value': attempt to select yielded rowid=$rowid"; if ( $rowid == 0 ) { say "So value needs to be inserted."; $sths{$table}{INSERT}->execute($value); $rowid = $dbh->do("SELECT last_insert_rowid()"); } else { say "So value has been previously inserted."; } return $rowid; }