Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

MySQL row_count and DBI

by msh210 (Monk)
on Apr 13, 2016 at 20:05 UTC ( [id://1160339]=perlquestion: print w/replies, xml ) Need Help??

msh210 has asked for the wisdom of the Perl Monks concerning the following question:

O Monks,

I am using MariaDB 5.5 (which for most intents and purposes is MySQL 5.5), and am using DBI with mysql as the driver name. The DBI documentation indicates that its rows method — and, for non-select statements, its execute method — returns the number of rows affected by the last statement.

Now, the MariaDB row_count function returns the number of rows affected, too. But it counts them funny; for example:

  • On an insert ... on duplicate key update, row_count includes the attempted-insert rows whether successful or not and also the updated rows (and counts the same row twice if relevant).
  • If a foreign key causes rows elsewhere to be deleted, row_count doesn't count them.

My question is: Using mysql as the driver name, do DBI's rows and execute methods return the same row count as MariaDB's/MySQL's row_count? If not, what row count do the DBI methods return? (Specifically, I want to know about the case of insert ... on duplicate key update, but the more general question is interesting, too.)

This question does not appear to be addressed on any of the following pages: DBI pod, DBI FAQ, mysql pod, short guide, Reading, Tricks, OK. Nor is Google helping.

$_="msh210";$"=$\;@_=@{[split//,uc]}[2,0];$_="@_$\1";$\=$/;++$_[0]for$...1;print lc substr crypt($_,"@_"),1,6

Replies are listed 'Best First'.
Re: MySQL row_count and DBI
by graff (Chancellor) on Apr 13, 2016 at 21:51 UTC
    This seems like the sort of question that could be answered by experimentation. If you have access to both a Mysql and a MariaDB, you could set up the same test tables and data, and run the same operations on both to see if they return the same numbers.

    If you only have access to MariaDB, I guess it's a matter of setting up test tables, test data, and test operations in such a way that you can confirm what the return values actually correspond to (in some set of scenarios relevant to your application).

    If it really matters to you how this compares to a Mysql server, but you don't have access to try that out, perhaps you could post your experimental tables, data and operations here, and someone who does have Mysql could try it out and tell you what they get.

      Okay, good idea, graff. Here's what I did:

      use strict; use warnings; use DBI; use Try::Tiny; $|=1; my $redo; my $dbh; print 'mysql username: '; chomp(my $username=<STDIN>); print 'mysql password: '; system('stty','-echo');chomp(my $pw=<STDIN>);system('stty','echo'); print $/; sub reconn { $dbh = DBI->connect('dbi:mysql:scratch;mysql_enable_utf8=1',$usernam +e,$pw,{mysql_auto_reconnect => 1}) or die $DBI::errstr; } reconn; my $sth; # MariaDB [scratch]> create table foo(bar int,baz int,primary key(bar) +); # Query OK, 0 rows affected (0.02 sec) # # MariaDB [scratch]> insert foo(bar)value(1); # Query OK, 1 row affected (0.01 sec) # # MariaDB [scratch]> desc foo; # +-------+---------+------+-----+---------+-------+ # | Field | Type | Null | Key | Default | Extra | # +-------+---------+------+-----+---------+-------+ # | bar | int(11) | NO | PRI | 0 | | # | baz | int(11) | YES | | NULL | | # +-------+---------+------+-----+---------+-------+ # 2 rows in set (0.00 sec) # # # MariaDB [scratch]> select * from foo; # +-----+------+ # | bar | baz | # +-----+------+ # | 1 | NULL | # +-----+------+ # 1 row in set (0.00 sec) $\=$/; my $rows; $dbh->ping or reconn; $sth = $dbh->prepare("insert foo(bar)value(2);"); $redo = 1; while ($redo) {$redo=0; try {$rows=$sth->execute();} catch +{$redo = /deadlock found/i;}} print "new: $rows"; undef $rows; $dbh->ping or reconn; $sth = $dbh->prepare("insert ignore foo(bar)value(1);"); $redo = 1; while ($redo) {$redo=0; try {$rows=$sth->execute();} catch +{$redo = /deadlock found/i;}} print "old ignore: $rows"; undef $rows; $dbh->ping or reconn; $sth = $dbh->prepare("insert foo(bar)value(1) on duplicate key update +baz=1;"); $redo = 1; while ($redo) {$redo=0; try {$rows=$sth->execute();} catch +{$redo = /deadlock found/i;}} print "old on duplicate key update: $rows";

      And the results were:

      new: 1 old ignore: 0E0 old on duplicate key update: 2

      And row_count gives the same numbers (in these cases):

      # MariaDB [scratch]> select * from foo; # +-----+------+ # | bar | baz | # +-----+------+ # | 1 | NULL | # +-----+------+ # 1 row in set (0.00 sec) # # MariaDB [scratch]> insert foo(bar)value(2); # Query OK, 1 row affected (0.00 sec) # # MariaDB [scratch]> select row_count(); # +-------------+ # | row_count() | # +-------------+ # | 1 | # +-------------+ # 1 row in set (0.00 sec) # # MariaDB [scratch]> insert ignore foo(bar)value(1); # Query OK, 0 rows affected, 1 warning (0.00 sec) # # MariaDB [scratch]> select row_count(); # +-------------+ # | row_count() | # +-------------+ # | 0 | # +-------------+ # 1 row in set (0.01 sec) # # MariaDB [scratch]> insert foo(bar)value(1) on duplicate key update b +az=1; # Query OK, 2 rows affected (0.00 sec) # # MariaDB [scratch]> select row_count(); # +-------------+ # | row_count() | # +-------------+ # | 2 | # +-------------+ # 1 row in set (0.00 sec)
      $_="msh210";$"=$\;@_=@{[split//,uc]}[2,0];$_="@_$\1";$\=$/;++$_[0]for$...1;print lc substr crypt($_,"@_"),1,6

        Ah, but now I've tried an on duplicate key update where the update didn't actually change anything (the value to update to was there already), and select row_count() gave 0, but execute returned 1. So they're not always the same.

        (The query was insert foo(bar)value(1)on duplicate key update baz=1; and the table already had 1 in each column.)

        $_="msh210";$"=$\;@_=@{[split//,uc]}[2,0];$_="@_$\1";$\=$/;++$_[0]for$...1;print lc substr crypt($_,"@_"),1,6

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1160339]
Approved by graff
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2024-04-24 06:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found