beginning of DWIM for IDENTITY_INSERT
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / ODBC / Microsoft_SQL_Server.pm
CommitLineData
c1cac633 1package DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server;
2use strict;
3use warnings;
4
eb0323df 5use base qw/DBIx::Class::Storage::DBI::MSSQL/;
c1cac633 6
7sub _prep_for_execute {
259c0e40 8 my $self = shift;
9 my ($op, $extra_bind, $ident, $args) = @_;
10
11 my ($sql, $bind) = $self->next::method (@_);
12 $sql .= ';SELECT SCOPE_IDENTITY()' if $op eq 'insert';
13
14 use Scalar::Util 'blessed';
15 use List::Util 'first';
16 if ( blessed $ident ) {
17 my %auto_inc_columns;
18 foreach my $column ($ident->columns) {
19 if ($ident->column_info($column)->{is_auto_increment}) {
20 $auto_inc_columns{$column} = 1;
21 }
22 }
c1cac633 23
259c0e40 24 my $table = $ident->from;
25 my $auto_inc_col = 0;
26 BINDS:
27 foreach my $bound (@{$bind}) {
28 my $col = $bound->[0];
29 if ($auto_inc_columns{$col}) {
30 $auto_inc_col = 1;
31 last BINDS;
32 }
33 }
34 if ($auto_inc_col) {
35 $sql = "SET IDENTITY_INSERT $table ON; $sql; SET IDENTITY_INSERT $table OFF;"
36 }
37 }
c1cac633 38
259c0e40 39 return ($sql, $bind);
c1cac633 40}
41
2eebd801 42sub _execute {
43 my $self = shift;
44 my ($op) = @_;
c1cac633 45
2eebd801 46 my ($rv, $sth, @bind) = $self->dbh_do($self->can('_dbh_execute'), @_);
77af494b 47 if ($op eq 'insert') {
48 $self->{_scope_identity} = $sth->fetchrow_array;
49 $sth->finish;
50 }
c1cac633 51
2eebd801 52 return wantarray ? ($rv, $sth, @bind) : $rv;
c1cac633 53}
54
55sub last_insert_id { shift->{_scope_identity} }
56
c1cac633 571;
58
59__END__
60
61=head1 NAME
62
a89c6fc0 63DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server - Support specific
64to Microsoft SQL Server over ODBC
c1cac633 65
66=head1 DESCRIPTION
67
68This class implements support specific to Microsoft SQL Server over ODBC,
69including auto-increment primary keys and SQL::Abstract::Limit dialect. It
70is loaded automatically by by DBIx::Class::Storage::DBI::ODBC when it
71detects a MSSQL back-end.
72
73=head1 IMPLEMENTATION NOTES
74
75Microsoft SQL Server supports three methods of retrieving the IDENTITY
76value for inserted row: IDENT_CURRENT, @@IDENTITY, and SCOPE_IDENTITY().
77SCOPE_IDENTITY is used here because it is the safest. However, it must
78be called is the same execute statement, not just the same connection.
79
80So, this implementation appends a SELECT SCOPE_IDENTITY() statement
81onto each INSERT to accommodate that requirement.
82
c1cac633 83=head1 AUTHORS
84
85Marc Mims C<< <marc@questright.com> >>
86
87=head1 LICENSE
88
89You may distribute this code under the same terms as Perl itself.
90
91=cut
259c0e40 92# vim: sw=2 sts=2