11

I've this problem with a Sybase IQ database (version SELECT @@version shows Adaptive Server IQ/12.5.0/0306) using the PHP SQL Anywhere extension.

I can't select all rows, i.e. SELECT * from anytable always returns 30 rows.

The only workaround I've found is using SELECT TOP 1000 * from anytable (maximum is 32767) but there are certain situations where I need all rows.

Any help is much appreciated.

EDIT: example script (much like the documentation)

$conn = sasql_connect("HOST=host:port;DBN=dbn;UID=uid;PWD=pwd");
if (!$conn) { echo "Connection failed."; die(); }

$result = sasql_query($conn, "SELECT * FROM dba.anytable" );
sasql_result_all($result); // display 30 rows in a formatted table
sasql_free_result($result);
sasql_disconnect($conn);

EDIT: specs of both machines where I'm experiencing the same exact problem:

Development machine:

Production sever:

gremo
  • 47,186
  • 75
  • 257
  • 421
  • A lot of SQL development environments limit the rows via program preferences... though for it to be defaulted to 30, I am not sure if any program developer would do that. – insidesin Aug 07 '15 at 08:45
  • @insidesin indeed it could be, but I need to find a way to select all rows, no matter how heavy is... – gremo Aug 07 '15 at 08:50
  • I'm looking at the docs and there is an another value `all` just like `TOP` as a parameter which says `includes all rows in the results. all is the default.` try `SELECT all FROM dba.anytable` http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc36272.1570/html/commands/X35229.htm – Stanimir Dimitrov Aug 20 '15 at 16:04

2 Answers2

5

Probably a stupid question, but just to be sure.

Did you check in Client --> Tools -> Sybase IQ -> Maximum number of rows to display.

(sry for posting this as an answer, but i dont have enough rep to ask you in comments.) Cheers

theweeknd
  • 277
  • 1
  • 12
  • While this could work for the client I don't think it will affect the PHP connection and extension... I will give it a try asap – gremo Aug 10 '15 at 16:27
  • What does "select count(*) from table" shows you, does it count the hole table or just 30 rows? – theweeknd Aug 11 '15 at 07:55
  • Count the whole table as expected – gremo Aug 11 '15 at 09:42
  • And in client everything works normal, select * from table shows all rows? – theweeknd Aug 11 '15 at 11:20
  • check the php.ini file, and see if you have this line: sqlanywhere.row_counts=Off – theweeknd Aug 11 '15 at 11:22
  • I didn't set any php.ini option for the extension, so yes, I think sqlanywhere.row_counts=Off is there (it's the default). How this would affect the total number of rows? – gremo Aug 17 '15 at 07:52
  • sqlanywhere.row_counts=30 would always show you just 30 results – theweeknd Aug 17 '15 at 08:28
  • It seems it can be set to `true` or `false`, but changing it doesn't not solve the problem. I've updated the question with a code example, it may help. – gremo Aug 17 '15 at 09:32
3

Well, there is probably some configurable property somewhere that will release you from the evil clutches of 30. I do not know where that property is. I hope someone finds it.

In case nobody does, however, here is a big hack which orders by the primary key of the given table, retrieves as many rows as it can given your constraints, and keeps track of the last fetched primary key in order to retrieve the next batch of rows. It would be better to adapt this to use START AT or LIMIT / OFFSET if available, but I'm assuming they're not. If one of those is available, you could use this approach for any table. If not, this approach can be adapted to any table which has a unique non-null key.

$conn = sasql_connect("HOST=host:port;DBN=dbn;UID=uid;PWD=pwd");
if (!$conn) {echo "Connection failed."; die(); }

$highest_id = -1;
$num_rows_retrieved = 0;

do {
  if (!sasql_real_query($conn, "SELECT TOP 32767 * FROM dba.anytable where anytable_id > $highest_id order by anytable_id")) {
    echo "Query failed.";
    die();
  }
  $result = sasql_use_result($conn);
  if (!$result) {
    echo "No result set.";
    die();
  }
  $num_rows_retrieved = 0;
  $num_fields = sasql_num_fields($result);
  while ($row = sasql_fetch_row($result)) {
    $highest_id = $row[0];  // assumes anytable_id is the first field
    $i = 0;
    while ($i < $num_fields) {
      echo "$row[$i]\t"; 
      $i++;
    }
    $num_rows_retrieved++;
    echo "\n";
  }
  sasql_free_result($result);
} while ($num_rows_retrieved == 32767);

sasql_disconnect($conn);
heenenee
  • 19,914
  • 1
  • 60
  • 86
  • Can you provide a sample PHP code (like mine in the question) to set rowcount before executing the query? – gremo Aug 17 '15 at 22:20
  • @gremo I'm not sure... I updated my answer with ways that work for me in my Sybase IQ instance. Hopefully one of them works in your env with either `sasql_query` or `sasql_real_query`. Depending on your results, I can update or retract my answer. Also, I don't know if it's an option for you, but one of them might work with the Sybase CT extension. http://php.net/manual/en/book.sybase.php – heenenee Aug 18 '15 at 06:19
  • Still no luck. I modified the script so that now the query is `set rowcount 0 SELECT * FROM dba.anytable`: still 30 rows. Funny thing is when I set it to a number less than 30 it works (i.e. 10), setting a value greater than 30 and it doesn't. – gremo Aug 18 '15 at 08:27
  • @gremo That's weird behavior. But you get more than 30 rows back with `SELECT TOP`? Anyway, I changed my answer to do a more manual iteration of the rows than `sasql_query` / `sasql_result_all` thinking that maybe there's a hidden limit with one of those behind the scenes. Can you try out my code sample please? Also, I'd be interested in knowing the output of `$num_rows`. – heenenee Aug 18 '15 at 20:25
  • Yes, actually `TOP n` is the only way I have to select more rows (I can get **32767** at maximum). Your example output: `num_fields: 10 num_rows: -1` while 30 rows are printed. Thanks for helping. – gremo Aug 18 '15 at 20:56
  • @gremo I saw a couple of other possible config options, but nothing I'm confident about, and I wouldn't know how to apply them in a PHP script anyway. I changed my answer to the best I could do given the circumstances. Good luck. – heenenee Aug 19 '15 at 05:43