Actually, the tokens '(pickup, pmonth, pday, pyear)' are field names for the following 'values ($pickup, $pmonth, $pday, $pyear)' part of the statement, which is perfectly valid, no quoting required. You can't assume that pickup, pmonth, pday and pyear are the only fields in the table either (others may be auto defaulted) or that the order of the fields in the table is the same table definition (they may have to be inserted in a different order).
The real problem is that the entire query is contained in single quotes and the variables will never be filled in (in the first example). Checking errors as has been suggested would confirm this. The query would never execute successfully with literals like $pickup in them. The second example may be equally broken depending on the values of the variables. Numbers can go unquoted, but string values would definitely need quotes around them. Again checking errors would confirm this to.
Maybe it's a simple case of table permission. The MySQL database user may be able to read the table but not insert values. Again with the checking errors.
I can't agree more on the use of place holders (++). This also works:
my $affInfo = $dbh->do(
'INSERT into teach_info (pickup,pmonth,pday,pyear) values (?,?,?,?)',
$pickup, $pmonth, $pday, $pyear);