in reply to Re^5: CGI Action call
in thread CGI Action call

I have a form with a navigator control I made. Works fine except when I want to scroll with a different order in place.

The 4 SQL statements work fine in PHPAdmin. I issue an "alter table users order by lastname asc and the table is so ordered. Shows as such in browse. I execute the various SQL statements below and the returned records are as expected. next, next, previous, beginning and end. The ORDER remains in place.

On the form I search for last name and set the alter table based on the search selected. This all works as intended per my logging. When I try to scroll the records with the navigator it is returning records based on the user_id order. I tried correcting this by reasserting the alter table again with each scroll but to no avail.

Don't understand why the process works in PHP MyAdmin but not with my code.

#==================================== #Navigation navigate_Records Buttons 1-4 # 1 Beginning # 2 Previous # 3 Next # 4 End sub navigate_Records { my $kind = $query->param('kind'); my $rowpointer = $query->param('searchterm'); my ($sth, $stmt); my @row; warn("Entered update_tables.cgi Open Database return First Record +with action: = '$action'"); warn("Search Parameter = '$kind'"); warn("rowpointer = '$rowpointer'"); my $minrowpointer; my $maxrowpointer; my $searchfield; warn("sortindex = '$sortindex'"); #Set by selection in search_Rec +ords if (!$sortindex) { $sortindex = 0; } if ($sortindex == 0){ $searchfield = 'user_id'; $minrowpointer = 1; $maxrowpointer = 14999; } elsif ($sortindex == 1) { $searchfield = 'lastname'; $minrowpointer = 'a%'; $maxrowpointer = 'z%'; } elsif ($sortindex == 2) { $searchfield = 'business'; $minrowpointer = 'a%'; $maxrowpointer = 'z%'; } #kind 0 & 3 ok with direct hard coded SQL if ($kind == 0){ #beginning record Tested Good $stmt= "SELECT * FROM ( SELECT * FROM users WHERE $searchfield + <= ? AND $searchfield >= ? ORDER BY $searchfield ASC LIMIT 1 ) sub O +RDER BY $searchfield ASC"; # example user_id # $stmt = "SELECT * FROM ( SELECT * FROM users WHERE user_id <= + 14999 AND user_id >= 1 ORDER BY user_id ASC LIMIT 1 ) sub ORDER BY u +ser_id ASC"; #Works fine hard coded #example lastname SELECT * FROM ( SELECT * FROM users WHERE la +stname <='z%' AND lastname >= 'a%'ORDER BY lastname ASC LIMIT 1 ) sub + ORDER BY lastname ASC #Works fine hard coded #example business SELECT * FROM ( SELECT * FROM users WHERE bu +siness <='z%' AND business >= 'a%'ORDER BY business ASC LIMIT 1 ) sub + ORDER BY business ASC } if ($kind == 1){ #previous record Tested Good $stmt = "SELECT * FROM users WHERE $searchfield <= (SELECT MAX +($searchfield) FROM users WHERE $searchfield < ?) ORDER BY $searchfie +ld DESC LIMIT 1"; } if ($kind == 2){ #next record Tested Good $stmt = "SELECT * FROM users WHERE $searchfield >= (SELECT MIN +($searchfield) FROM users WHERE $searchfield > ?) ORDER BY $searchfie +ld ASC LIMIT 1"; } if ($kind == 3){ #Last record Tested Good $stmt = "SELECT * FROM ( SELECT * FROM users WHERE $searchfiel +d <= ? AND $searchfield >= ? ORDER BY $searchfield DESC LIMIT 1 ) sub + ORDER BY $searchfield ASC"; #example user_id # $stmt = "SELECT * FROM ( SELECT * FROM users WHERE user_id <= +14999 AND user_id >= 1 ORDER BY user_id DESC LIMIT 1 ) sub ORDER BY u +ser_id ASC"; #Works fine hard coded #example lastname SELECT * FROM ( SELECT * FROM users WHERE la +stname >='z%' AND lastname >= 'a%'ORDER BY user_id DESC LIMIT 1 ) sub + ORDER BY lastname ASC #Works fine hard coded #example business SELECT * FROM ( SELECT * FROM users WHERE bu +siness >='z%' AND business >= 'a%'ORDER BY business DESC LIMIT 1 ) su +b ORDER BY business ASC } warn("statement = '$stmt'"); $sth = $dbh->prepare ($stmt) or die "Error Preparing:\n" . $stmt . + "\nDBI returned: \n", $dbh->errstr; # warn("'$maxrowpointer' '$minrowpointer' '$searchfield' '$rowpoint +er'"); if (($kind == 0) || ($kind == 3)){ warn("kind = '$kind' maxrowpointer = '$maxrowpointer' minrowpo +inter = '$minrowpointer'"); $sth->execute ($maxrowpointer,$minrowpointer) or die "Unable to + execute query: " . $sth->errstr; } elsif (($kind == 1) || ($kind == 2)){ warn("kind = '$kind' rowpointer = '$rowpointer'"); $sth->execute($rowpointer) or die "Unable to execute query: " . + $sth->errstr; } my $navResult = $sth->fetchrow_hashref(); warn("navResult = '$navResult'"); my $count = $sth->rows; warn("count = '$count'"); if ($count == 0) { my %navFail = ( Count => $count); my $json = JSON->new; $json->canonical(1); $json = encode_json(\%navFail); print "Content-Type: application/json\n\n"; print $json; warn("Finished print 0 count $json"); exit(1); } else { warn("count = '$count'"); my $json = JSON->new; $json->canonical(1); $json = encode_json($navResult); print "Content-Type: application/json\n\n"; print $json; warn("Finished print $json"); exit(0); } }

More code

#Search Records & Return Found 3 buttons # 0 Member ID # 1 Last Name # 2 Business Name #elsif ($action eq "search_Records") sub search_Records { warn("Entered search_Records"); my $kind = $query->param('kind'); my $searchterm = $query->param('searchterm'); my $result; warn("searchterm = '$searchterm'"); my $searchfield = ""; if ($kind == 0) { $searchfield = 'user_id'; } if ($kind == 1) { $searchfield = 'lastname'; } if ($kind == 2) { $searchfield = 'business'; } $sortindex = $kind; restoreOrder($kind); #Sort Index For The Three Kinds Of ORDER Supposed to be global. warn("sortindex = '$sortindex'"); warn("searchfield = '$searchfield'"); $stmt = "SELECT * FROM users WHERE $searchfield = ? ORDER BY ? ASC +"; # my $stmt = "SELECT * FROM users WHERE user_id = 15 ORDER BY user_ +id ASC"; warn("statement = '$stmt'"); $sth = $dbh->prepare ($stmt) or die "Error Preparing:\n" . $stmt . + "\nDBI returned: \n", $dbh->errstr; $sth->execute($searchterm, $searchfield) or die "Unable to execute + query: " . $sth->errstr; # $sth->execute() or die "Unable to execute query: " . $sth->errstr +; my $searchResult = $sth->fetchrow_hashref(); my $count = $sth->rows; warn("count = '$count'"); if ($count == 0) { warn("Failed Search: '$searchfield' equal to '$searchterm' "); my %searchFail = ( SearchError => $kind); my $json = JSON->new; $json->canonical(1); $json = encode_json(\%searchFail); print "Content-Type: application/json\n\n"; print $json; warn("Finished print 0 count $json"); exit(1); } #{"SearchError":0} Good else { warn("count = '$count'"); my $json = JSON->new; $json->canonical(1); $json = encode_json($searchResult); print "Content-Type: application/json\n\n"; print $json; warn("Finished print $json"); exit(0); } }

And yet more code

#================================== #Set up "order by clause" depending on searchfield sub restoreOrder{ my $searchIndex = shift; if ($searchIndex == 0) { $searchfield = "user_id"; } elsif ($searchIndex == 1) { $searchfield = "lastname"; } elsif ($searchIndex == 1) { $searchfield = "business"; } warn("in restoreOrder index = '$searchIndex'"); my $stmt = "alter table users order by $searchfield asc"; my $sth = $dbh->prepare ($stmt) or die "Error Preparing:\n" . $stm +t . "\nDBI returned: \n", $dbh->errstr; DBI->trace(3,$dbitracelog); $sth->execute() or die "Unable to execute query: " . $sth->errstr; + }

Replies are listed 'Best First'.
Re^7: CGI Action call
by poj (Abbot) on Mar 27, 2018 at 20:31 UTC

    Why use sub selects here

    SELECT * FROM users WHERE $searchfield <= ( SELECT MAX($searchfield) FROM users WHERE $searchfield < ?) ORDER BY $searchfield DESC LIMIT 1

    instead of the simpler

    SELECT * FROM users WHERE $searchfield < ? ORDER BY $searchfield DESC LIMIT 1
    poj
Re^7: CGI Action call
by Corion (Patriarch) on Mar 27, 2018 at 17:05 UTC
    alter table users order by lastname asc

    I don't think that this is how SQL works. In fact, I'm surprised that such a statement parses at all and doesn't raise an error.

    In SQL, tables don't have any kind of order that you can change. SELECT statements have an order clause and if you want to have a specific order, you need to specify that in every SELECT statement.

      The alter table MyTable order by MyField works in PHP Admin and is in the MySQL docs as well as testing and explanation in Work Log Wl#3681 Report BUG#24562

      MySQL Docs: ALTER TABLE tbl_name [alter_specification ORDER BY col_name , col_name ...

      My question remains: Why it works in PHP MyAdmin and not in my program?????

      Best regards

        Maybe some other instance of your program is changing the sort order at the same time?

        Even the MySQL documentation tells us that this ordering will not respect changes to the table.

        You shouldn't rely on such a feature but use the order by clause in your SELECT statements.

        Also, you should show some representative examples of data in your table, and the exact SELECT statements you run, and the exact output you get, and the exact output you expect. It makes it relatively hard for us to slog through the reams of code you post, half of which is commented-out debris from other attempts by you.

        Please take some time to prepare a short, self-contained example that we can run to reproduce and maybe fix your problem. It should be shorter than 20 lines.