Re: InnoDB Transaction and LAST_INSERT_ID()

2006-11-28 Thread Mike Kruckenberg

Andre Matos wrote:
Thanks Mike. 


I understand the possible "gaps" that I might have if I use the ROLLBACK.
This is acceptable in my case.

What I really want to avoid is what I am doing now: open one transaction to
insert, or update, or delete certain information and close with the commit.
Then, I get the LAST_INSERT_ID() and open another transaction to write my
audit trail. However, if the first one went through ok but if I got a
problem at the second transaction, I need to delete the inserted or updated
or move back the deleted information. This doesn't work well.


Let's expand my "staff" and "change" tables to have this structure to
simulate my problem:

++--++
| ID | Name | Gender |
++--++

++-+---+---+---+
| ID | Key | Table | Field | Value |
++-+---+---+---+

And do this:

SET AUTOCOMMIT=0;
START TRANSACTION;

INSERT INTO staff (`Name`, `M`) VALUES ('ABC');

INSERT INTO changes (`Key`, `Table`, `Field`, `Value`) VALUES
(LAST_INSERT_ID(), 'Staff', 'ID', LAST_INSERT_ID());
INSERT INTO changes (`Key`, `Table`, `Field`, `Value`) VALUES
(LAST_INSERT_ID(), 'Staff', 'Name', 'ABC');
INSERT INTO changes (`Key`, `Table`, `Field`, `Value`) VALUES
(LAST_INSERT_ID(), 'Staff', 'Gender', 'M');

COMMIT;
SET AUTOCOMMIT=1;


I will get something like this:

mysql> select * from staff;
++--++
| ID | Name | Gender |
++--++
|  1 | ABC  | M  |
++--++
1 row in set (0.00 sec)

mysql> select * from changes;
++-+---+---+---+
| ID | Key | Table | Field | Value |
++-+---+---+---+
|  1 | 1   | staff | ID| 1 |
++-+---+---+---+
|  2 | 1   | staff | Name  | ABC   |
++-+---+---+---+
|  3 | 2   | staff | Gender| M |
++-+---+---+---+
3 row in set (0.00 sec)

See that I have a problem in the third line at the "Key" column where I
should have "1" but I got "2" instead. This happened because of
LAST_INSERT_ID() used the ID from the "changes" table instead of the desired
"staff" table.

Is there any way to avoid this? What about the mysql_insert_id()?
  
I see. In this case you could make it two operations and use the 
mysql_insert_id() to capture the id from the first insert, setting a 
variable to that in PHP and using that variable to ensure the same number.


What I would consider is setting a database variable inside the 
transaction to store the id - the @ signifies it's a session variable 
that is specific to this connection:


SET AUTOCOMMIT=0;
START TRANSACTION;

INSERT INTO staff (`Name`, `Gender`) VALUES ('ABC','M');

SET @staff_id = LAST_INSERT_ID();

INSERT INTO changes (`Key`, `Table`, `Field`, `Value`) VALUES
(@staff_id, 'Staff', 'ID', @staff_id);
INSERT INTO changes (`Key`, `Table`, `Field`, `Value`) VALUES
(@staff_id, 'Staff', 'Name', 'ABC');
INSERT INTO changes (`Key`, `Table`, `Field`, `Value`) VALUES
(@staff_id, 'Staff', 'Gender', 'M');

COMMIT;
SET AUTOCOMMIT=1;


So you store the value after the first insert and then reuse. You can 
see it in the following string of SQL commands to demonstrate:


mysql> INSERT INTO staff (`Name`, `Gender`) VALUES ('ABC','M');
Query OK, 1 row affected (0.01 sec)

mysql> SET @staff_id = LAST_INSERT_ID();
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT @staff_id;
+---+
| @staff_id |
+---+
| 3 |
+---+
1 row in set (0.00 sec)

mysql> INSERT INTO changes (`Key`, `Table`, `Value`) VALUES 
(LAST_INSERT_ID(), 'staff', 'ABC');

Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO changes (`Key`, `Table`, `Value`) VALUES 
(LAST_INSERT_ID(), 'staff', 'ABC');

Query OK, 1 row affected (0.00 sec)

mysql> select LAST_INSERT_ID();
+--+
| LAST_INSERT_ID() |
+--+
|5 |
+--+
1 row in set (0.00 sec)

mysql> SELECT @staff_id;
+---+
| @staff_id |
+---+
| 3 |
+---+
1 row in set (0.00 sec)

--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: InnoDB Transaction and LAST_INSERT_ID()

2006-11-28 Thread Mike Kruckenberg

Andre Matos wrote:

SET AUTOCOMMIT=0;
START TRANSACTION;
INSERT INTO staff (`Name`) VALUES ('ABC');
INSERT INTO changes (`Key`, `Table`, `Value`) VALUES (LAST_INSERT_ID(),
'staff', 'ABC');
COMMIT;
SET AUTOCOMMIT=1;

This works fine in my test environment, however what about many users doing
at the same time. Does the LAST_INSERT_ID() get the correct ID for each
user?

Is there a better way to do this or this is fine? I will be using this with
PHP4.
  
To further clarify (my initial reply didn't give much detail), when an 
auto increment value is created for inserting it is in the scope of the 
current connection, and is not changed by the outcome of the transaction.


If you follow the string of SQL statements against your tables you'll 
see that the ID assigned to the record is not released on a rollback, 
the second insert gets a new auto increment value.


mysql> SET AUTOCOMMIT=0;
Query OK, 0 rows affected (0.00 sec)

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO staff (`Name`) VALUES ('ABC');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO changes (`Key`, `Table`, `Value`) VALUES 
(LAST_INSERT_ID(),

   -> 'staff', 'ABC');
Query OK, 1 row affected (0.00 sec)

mysql> select * from staff;
++--+
| ID | Name |
++--+
|  1 | ABC  |
++--+
1 row in set (0.00 sec)

mysql> select * from changes;
++-+---+---+
| ID | Key | Table | Value |
++-+---+---+
|  1 | 1   | staff | ABC   |
++-+---+---+
1 row in set (0.00 sec)

mysql> select last_insert_id();
+--+
| last_insert_id() |
+--+
|1 |
+--+
1 row in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.26 sec)

mysql> select * from staff;
Empty set (0.00 sec)

mysql> select * from changes;
Empty set (0.00 sec)

mysql> INSERT INTO staff (`Name`) VALUES ('ABC');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO changes (`Key`, `Table`, `Value`) VALUES 
(LAST_INSERT_ID(),

   -> 'staff', 'ABC');
Query OK, 1 row affected (0.00 sec)

mysql> select * from staff;
++--+
| ID | Name |
++--+
|  2 | ABC  |
++--+
1 row in set (0.00 sec)

mysql> select * from changes;
++-+---+---+
| ID | Key | Table | Value |
++-+---+---+
|  2 | 2   | staff | ABC   |
++-+---+---+
1 row in set (0.00 sec)


--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: InnoDB Transaction and LAST_INSERT_ID()

2006-11-28 Thread Mike Kruckenberg

Andre Matos wrote:

The idea is to have a audit trail to record the changes made. So, I want to
insert a new record in the "staff" table and right after this, insert a
record in the "changes" table.

SET AUTOCOMMIT=0;
START TRANSACTION;
INSERT INTO staff (`Name`) VALUES ('ABC');
INSERT INTO changes (`Key`, `Table`, `Value`) VALUES (LAST_INSERT_ID(),
'staff', 'ABC');
COMMIT;
SET AUTOCOMMIT=1;

This works fine in my test environment, however what about many users doing
at the same time. Does the LAST_INSERT_ID() get the correct ID for each
user?
  
LAST_INSERT_ID() is connection-specific so the ID will be the one that 
was assigned during this particular PHP page's connection to the database.



--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: Calling Stored Procedures from PHP

2006-11-27 Thread Mike Kruckenberg

Filipe Freitas wrote:

Hi,

This is not a mysql thing but maybe you can help me.
I want to call a stored procedure from PHP, so I tried it like normal 
querys: mysql_query("CALL mySP();"); with no success.
What is happening when you make the call? That might help get some more 
precise advice.


My understanding of using PHP with MySQL stored procedures is that you 
have to call them through the mysqli extension. It doesn't appear that 
you are using them. With them your  would be using the mysqli_query() 
function.


I don't do a lot of PHP, but I stumbled into a similar problem and using 
the mysqli extensions solved the issue.


--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: create function in mysql 5.0.26-3

2006-11-27 Thread Mike Kruckenberg

Anakreon Mejdi wrote:

I am trying to create a stored function.
From the docs I saw the code for this function:
CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
DETERMINISTIC
RETURN CONCAT('Hello, ',s,'!');

The version from the docs did not contain the DETERMINISTIC keyword.
I added because it would not compile.

The problem is that if I change the code to:
CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
DETERMINISTIC
LANGUAGE SQL
BEGIN
RETURN CONCAT('Hello, ',s,'!');
END;
I get the error message:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax to use near 'END' 
at line 1
  
In this example you need to change the delimiter to something other than 
; otherwise the MySQL client things that's the stopping point for a 
statement and attempts to process.


mysql> delimiter //
mysql> CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
   -> DETERMINISTIC
   -> LANGUAGE SQL
   -> BEGIN
   -> RETURN CONCAT('Hello, ',s,'!');
   -> END;
   ->
   -> //
Query OK, 0 rows affected (0.01 sec)

mysql> delimiter ;
mysql> select hello("Mike");
+---+
| hello("Mike") |
+---+
| Hello, Mike!  |
+---+
1 row in set (0.00 sec)

Hope that helps. Functions are covered pretty well in Pro MySQL 
(Apress). I'm one of the authors.


--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: mysqlhotcopy errors osx

2006-11-17 Thread Mike Kruckenberg
DBD::mysqlPP is the pure Perl driver for DBI. Is there a reason you are 
using that instead of DBD::mysql? I haven't done Perl/MySQL on OS X 
before but on other platforms (and from the error you're getting here) 
DBD::mysql is the typical driver for using DBI with MySQL. It also is 
the driver that mysqlhotcopy is built to use.


Mike

James Tu wrote:
The first time I tried to run the mysqlhotcopy script, I got an error 
that indicated that Perl couldn't find the DBI module.
So, I found a site (http://www.quicomm.com/apm_dbddbi.htm) that 
stepped me through making and installing
MySQL DBD and the DBI modules(? don't know if I'm using the right 
terminology here)



However, during the 'make' step of the DBD module I got a warning:
prompt$ sudo Perl Makefile.PL
Checking if your kit is complete...
Looks good
Warning: prerequisite Net::MySQL 0.08 not found.
Writing Makefile for DBD::mysqlPP


So I decided to try to 'make install' anyway and I got...
$ sudo make install
Installing /Library/Perl/5.8.6/DBD/mysqlPP.pm
Installing /usr/local/man/man3/DBD::mysqlPP.3pm
Writing 
/Library/Perl/5.8.6/darwin-thread-multi-2level/auto/DBD/mysqlPP/.packlist
Appending installation info to 
//System/Library/Perl/5.8.6/darwin-thread-multi-2level/perllocal.pod


trying to run mysqlhotcopy again, I got...
$ mysqlhotcopy --dryrun imaginon
install_driver(mysql) failed: Can't locate DBD/mysql.pm in @INC (@INC 
contains: /System/Library/Perl/5.8.6/darwin-thread-multi-2level 
/System/Library/Perl/5.8.6 
/Library/Perl/5.8.6/darwin-thread-multi-2level /Library/Perl/5.8.6 
/Library/Perl /Network/Library/Perl/5.8.6/darwin-thread-multi-2level 
/Network/Library/Perl/5.8.6 /Network/Library/Perl 
/System/Library/Perl/Extras/5.8.6/darwin-thread-multi-2level 
/System/Library/Perl/Extras/5.8.6 /Library/Perl/5.8.1 .) at (eval 7) 
line 3.

Perhaps the DBD::mysql perl module hasn't been fully installed,
or perhaps the capitalisation of 'mysql' isn't right.
Available drivers: DBM, ExampleP, File, Proxy, Sponge, mysqlPP.
at /usr/local/mysql/bin/mysqlhotcopy line 178


line 178 of the script looks like:

my $dbh = 
DBI->connect("dbi:mysql:$dsn;mysql_read_default_group=mysqlhotcopy",

$opt{user}, $opt{password},

should I change the "dbi:mysql" part to "dbi:mysqlPP" ???

or should I fix the earlier warning about Net:MySQL 0.08 not found 
first.  Do I just install the Net package?



...OK

I actually downloaded and installed Net:MySQL...
sudo Perl Makefile.PL
sudo make
sudo make test
sudo make install
...all went ok

then I did the same steps for DBD
...all went ok and no warnings...

But I'm still getting the same 'line 178' error.



What am I not doing correctly?
Thanks.
-James


--MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:
http://lists.mysql.com/[EMAIL PROTECTED]





--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: How Do I Know If mySQL is using MyISAM or InnoDB?

2006-11-17 Thread Mike Kruckenberg

This is in 4.0, it has changed in more recent versions.

Mike Kruckenberg wrote:

For any specific table if you do:

show create table ;

It will tell you what the able was created using. To create tables 
using a specific engine add ENGINE= to the end of your create 
statement.


To see the default that is used (I think this is what the table_type 
variable does):


mysql> show variables like 'table_type';
+---++
| Variable_name | Value  |
+---++
| table_type| MYISAM |
+---++
1 row in set (0.00 sec)

John Kopanas wrote:
Is there a command at the command line that can tell me if I am using 
MyISAM

or InnoDB?  Thanks :-).







--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: How Do I Know If mySQL is using MyISAM or InnoDB?

2006-11-17 Thread Mike Kruckenberg

For any specific table if you do:

show create table ;

It will tell you what the able was created using. To create tables using 
a specific engine add ENGINE= to the end of your create statement.


To see the default that is used (I think this is what the table_type 
variable does):


mysql> show variables like 'table_type';
+---++
| Variable_name | Value  |
+---++
| table_type| MYISAM |
+---++
1 row in set (0.00 sec)

John Kopanas wrote:
Is there a command at the command line that can tell me if I am using 
MyISAM

or InnoDB?  Thanks :-).




--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]