The easy way to get rid of the \n at the end of a line is chomp. Chomp deletes the last char from a sting IF that char is a \n.Pointers
$good_iput = chomp($input);
A neat discussion of pointers in Perl (called references) can be found at http://www.sitecircus.com/tricks/scalars.html.Don't Split and Die
This code is wrong. Split just returns the items split in a scalar context, or the items in a list context. But it does not return true/falseHow do get column information from a table ?
$count = split(/-/, $nations);
@n = split(/-/, $nations);
@n = split(/-/, $nations) or die "This is bad code!!";
#!/usr/bin/perlHow do I get the number of columns a query will generate?
# connect to db
my $dbh = DBI->connect(bla..bla..bla);
my $sql_q = "SHOW COLUMNS FROM $table";
my $sth = $dbh->prepare($sql_q);
$sth->execute;
while (@row = $sth->fetchrow_array){
print"Field Type Null Key Default Extra\n";
print"----------------------------------------------------\n";
print"$row[0] $row[1] $row[2] $row[3] $row[4] $row[5]\n";
}
# This will return one row which contains
# the number of rows found
my $sql = q(select count(*) from $table where field = ?);
my $sth = $dbh->prepare($sql);
$sth->execute('$value');
my $rows = $sth->fetchrow_arrayref->[0];
$sth->finish;w do I get the number of rows a query might generate?
You can Join the Same Table Twice
mysql> select A.name, B.name, length from borders, nations A, nations B where code1 = "rs" and code2 = "ch" and A.code = code1 and B.code = code2;Fetching from a database
+--------+-------+---------+
| name | name | length |
+--------+-------+---------+
| Russia | China | 2259.90 |
+--------+-------+---------+
Another way to fetch from a database isCaching the Database Connectionmy($id, $name, $phone);
$sth->bind_columns(undef, \$id, \$name, \$phone);for my $month (@months) {
print "People born in $month:\n";# Execute the statement for this $month
$sth->execute();# Fetch each row and print out the values
while ($sth->fetch) {
print "\t", join("\t", $id, $name, $phone), "\n";
}
}
If Perl is going to run out of Apache, then you can use Apachi:DBI to cache the database connections. See http://www.perlmonks.org/index.pl?node=Tricks%20with%20DBI&lastnode_id=954 .Transactions
Some databases need to be
told whether to commit or abort the transaction. Other times for
your own reasons you might want to cause a rollback.
sub new_employee {
# Arguments: database
handle; first and last names of new employee;
# department ID number
for new employee's work assignment
my ($dbh, $first, $last,
$department) = @_;
my ($insert_handle,
$update_handle);
my $insert_handle =
$dbh->prepare_cached('INSERT INTO employees VALUES (?,?,?)');
my $update_handle =
$dbh->prepare_cached('UPDATE departments
SET num_members = num_members + 1
WHERE id = ?');
die "Couldn't prepare
queries; aborting"
unless defined $insert_handle && defined $update_handle;
my $success = 1;
$success &&=
$insert_handle->execute($first, $last, $department);
$success &&=
$update_handle->execute($department);
my $result = ($success
? $dbh->commit : $dbh->rollback);
unless ($result) {
die "Couldn't finish transaction: " . $dbh->errstr
}
return $success;
}
Automatic Error Handling
When you make the connect call, you can specify a RaiseErrors option that handles errors for you automatically. When an error occurs, DBI will abort your program instead of returning a failure code. If all you want is to abort the program on an error, this can be convenient:User Inputmy $dbh = DBI->connect('DBI:Oracle:payroll',
{RaiseError => 1},)
or die "Couldn't connect to database: " . DBI->errstr;
People are always writing code like this:while ($lastname = <>) {
my $sth = $dbh->prepare("SELECT * FROM people WHERE lastname = '$lastname'");
$sth->execute();
# and so on ...
}Here we interpolated the value of $lastname directly into the SQL in the prepare call.
This is a bad thing to do for three reasons.
First, prepare calls can take a long time. The database server has to compile the SQL and figure out how it is going to run the query. If you have many similar queries, that is a waste of time.
Second, it will not work if $lastname contains a name like O'Malley or D'Amico or some other name with an '. The ' has a special meaning in SQL, and the database will not understand when you ask it to prepare a statement that looks like
SELECT * FROM people WHERE lastname = 'O'Malley'It will see that you have three 's and complain that you don't have a fourth matching ' somewhere else.
Finally, if you're going to be constructing your query based on a user input, as we did in the example program, it's unsafe to simply interpolate the input directly into the query, because the user can construct a strange input in an attempt to trick your program into doing something it didn't expect. For example, suppose the user enters the following bizarre value for $input:
x' or lastname = lastname or lastname = 'y
Now our query has become something very surprising:
SELECT * FROM people WHERE lastname = 'x' or lastname = lastname or lastname = 'y'
The part of this query that our sneaky user is interested in is the second or clause. This clause selects all the records for which lastname is equal to lastname; that is, all of them. We thought that the user was only going to be able to see a few records at a time, and now they've found a way to get them all at once. This probably wasn't what we wanted.
Solution
$sth = $dbh->prepare("select * from table where name = ?")
then
$sth->execute($userinput);