Perl Getopt::Long
Diego pointed out that I have been doing it all wrong using standard getopt. Getopt::Long is much neater and more powerful than its predecessor.
Two pointers for how to use it: active-venture and perl.com.
Here’s my sample code:
GetOptions('d=s' => \$C{'DB_DSN'},
'u=s' => \$C{'DB_USER'},
'p=s' => \$C{'DB_PASS'},
'c' => \$C{'DB_CREATE'},
't=s' => \$C{'DB_TABLE'},
's=s' => \$C{'SEP'},
'q:s' => sub { $mode = 2; $C{'DB_QUERY'}=$[1] if ($[1] ne '');},
'i' => sub { $mode = 1; }
) or usage();