📄 00000001.htm
字号:
The bulk of this function's work is performed by other functions. This is because other parts of the CGI program have similar needs so it is efficient to factor the common code into shared functions. The first such function is find_last_student, which <BR>examined the form data and returns a list of the form numbers--the form numbers are not related to the ID numbers in the database--of each student entered by the user. This is necessary because, as mentioned earlier, the previous form is dynamically <BR>generated and there is no way to immediately know how many students are included. <BR> <BR>sub find_last_student { <BR> my @params = param; <BR> my @list = (); <BR> foreach (@params) { <BR> next if not param($_); # Skip any 'empty' fields <BR> if (/^(first|middle|last|ext)(\d+)/) { <BR> my $num = $2; <BR> if (not grep(/^$num$/,@list)) { push(@list,$num); } <BR> } <BR> } <BR> @list = sort { $a <=> $b} @list; <BR> return @list; <BR>} <BR>Note that the function returns all of the numbers, not just the last number--which would presumably be the number of students entered. Even though the previous form printed out the number of entries the user requested, there is no guarantee that the <BR>user filled all of them out. He or she may have missed or skipped a row, which would not be included with the form data. Therefore, it is necessary to find out each number that was entered. The output of this function is then sent to the next "helper" <BR>function: find_matching_students, as shown in the following: <BR> <BR>sub find_matching_students { <BR> my @list = @_; <BR> my ($i,@students,@notstudents); <BR> @students = (); <BR> @notstudents = (); <BR> if (@list) { <BR> foreach $i (@list) { <BR> my @query = (); <BR> # Build a query that looks for a specific student. <BR> my $query = "select id, subjects from student where "; <BR> foreach ('first','middle','last','ext') { <BR> if (param("$_$i")) { <BR> my $temp = param("$_$i"); <BR> # Single quotes are the field delimiters for mSQL (and MySQL), <BR> # so they must be preceded with the escape character "\", <BR> # which is escaped itself so that it is interpreted literally. <BR> $temp =~ s/'/\\'/g; <BR> push(@query,"$_ = '$temp'"); <BR> } <BR> } <BR> $query .= join(" and ",@query); <BR> <BR> # Send the query to the database. <BR> my $out = $dbh->query($query); <BR> # If the database doesn't return anything, add the <BR> # student to the @notstudents array. <BR> if (not $out->numrows) { <BR> push(@notstudents,[ param("first$i"), <BR> param("middle$i"), <BR> param("last$i"), param("ext$i") ]); <BR> # Otherwise add the student to the @students array. <BR> } else { <BR> my ($id,$subjects) = $out->fetchrow; <BR> push(@students,[$id,$subjects]); <BR> } <BR> } <BR> } <BR> return(\@students,\@notstudents); <BR>} <BR>This function goes through each of the given student names and checks the database to see if they already exist. If they do exist their information is stored in an array called @students, otherwise they are put in <A HREF="mailto:@notstudents.">@notstudents.</A> The information about <BR>each student is kept in an anonymous array, creating a student object of sorts. Finally the function returns references to both of the arrays. It cannot return the data as regular arrays because there would be no way to tell where one array ended and <BR>the other began. <BR> <BR>The final helper function is update_students, which adds the class to each existing student's list of classes. <BR> <BR>sub update_students { <BR> my $id = shift; <BR> my @students = @_; <BR> foreach (@students) { <BR> my($sid,$subjects)=@$_; <BR> if (not $subjects) { $subjects = ":$id:"; } <BR> elsif ($subjects !~ /:$id:/) { $subjects .= "$id:"; } <BR> my $query = "update student set subjects='$subjects' <BR> where id=$id"; <BR> $dbh->query($query); <BR> } <BR>} <BR>This function queries the student table, which is entirely separate from the subject table. Within a single CGI program, you can interact with any number of different tables within a database. You can even switch between databases, but you can only <BR>have one database selected at a time. This function retrieves the subject list for each given student and adds the new subject to their list if it is not there already. <BR> <BR>At this point all contingencies are taken care of except for the case where the subject has students that do not already exist in the student table. For this case, the list of new students are sent to the add4 function as shown in the following: <BR> <BR>sub add4 { <BR> # Get list of @students and @notstudents <BR> &update_students($id,@students) if @students; <BR> &insert_students($id,@notstudents) if @notstudents; <BR> <BR> # Print success page. <BR>} <BR>This function separates the list of students into existing and nonexisting students using the same method as add3. It then updates the existing students using update_students shown earlier. Nonexisting students, shown in the following, are sent to the <BR>new helper function insert_students: <BR> <BR>sub insert_students { <BR> foreach $i (@list) { <BR> # This selects the next number in the sequence defined on the <BR> # table. We then use this number as the ID of the student. <BR> my $out = $dbh->query('select _seq from student'); <BR> my($sid) = $out->fetchrow; <BR> <BR> # We have to quote all of the text strings for inclusion <BR> # in the database. <BR> my ($first, $middle, $last, $ext) = ( <BR> $dbh->quote(param("first$i")), <BR> $dbh->quote(param("middle$i")), <BR> $dbh->quote(param("last$i")), <BR> $dbh->quote(param("ext$i")) <BR> ); <BR> my $query = "insert into student (id, first, middle, last, <BR> ext, subjects) VALUES ($sid, $first, $middle, <BR> $last, $ext, ':$id:')"; <BR> $dbh->query($query); <BR> } <BR>} <BR>This function again accesses the student table rather than the subject table. An ID number for the new students is retrieved from the sequence defined on the student table, and then the student is inserted into the table using that ID. <BR> <BR> <BR> <BR>-- <BR>※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 162.105.17.153] <BR><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -