1 package DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server;
5 use base qw/DBIx::Class::Storage::DBI::MSSQL/;
8 my ($self, $source, $cols, $data) = @_;
10 my $identity_insert = 0;
13 foreach my $col (@{$cols}) {
14 if ($source->column_info($col)->{is_auto_increment}) {
20 my $table = $source->from;
21 if ($identity_insert) {
22 $source->storage->dbh_do(sub {
23 my ($storage, $dbh, @cols) = @_;
24 $dbh->do("SET IDENTITY_INSERT $table ON;");
30 if ($identity_insert) {
31 $source->storage->dbh_do(sub {
32 my ($storage, $dbh, @cols) = @_;
33 $dbh->do("SET IDENTITY_INSERT $table OFF;");
39 sub _prep_for_execute {
41 my ($op, $extra_bind, $ident, $args) = @_;
43 my ($sql, $bind) = $self->next::method (@_);
44 $sql .= ';SELECT SCOPE_IDENTITY()' if $op eq 'insert';
46 my %identity_insert_tables;
47 my $col_info = $self->_resolve_column_info($ident, [map $_->[0], @{$bind}]);
49 foreach my $bound (@{$bind}) {
50 my $col = $bound->[0];
51 if ($col_info->{$col}->{is_auto_increment}) {
52 my $table = $col_info->{$col}->{-result_source}->from;
53 $identity_insert_tables{$table} = 1;
57 my $identity_insert_on = join '', map { "SET IDENTITY_INSERT $_ ON; " } keys %identity_insert_tables;
58 my $identity_insert_off = join '', map { "SET IDENTITY_INSERT $_ OFF; " } keys %identity_insert_tables;
59 $sql = "$identity_insert_on $sql $identity_insert_off";
68 my ($rv, $sth, @bind) = $self->dbh_do($self->can('_dbh_execute'), @_);
69 if ($op eq 'insert') {
70 $self->{_scope_identity} = $sth->fetchrow_array;
74 return wantarray ? ($rv, $sth, @bind) : $rv;
77 sub last_insert_id { shift->{_scope_identity} }
85 DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server - Support specific
86 to Microsoft SQL Server over ODBC
90 This class implements support specific to Microsoft SQL Server over ODBC,
91 including auto-increment primary keys and SQL::Abstract::Limit dialect. It
92 is loaded automatically by by DBIx::Class::Storage::DBI::ODBC when it
93 detects a MSSQL back-end.
95 =head1 IMPLEMENTATION NOTES
97 Microsoft SQL Server supports three methods of retrieving the IDENTITY
98 value for inserted row: IDENT_CURRENT, @@IDENTITY, and SCOPE_IDENTITY().
99 SCOPE_IDENTITY is used here because it is the safest. However, it must
100 be called is the same execute statement, not just the same connection.
102 So, this implementation appends a SELECT SCOPE_IDENTITY() statement
103 onto each INSERT to accommodate that requirement.
107 Marc Mims C<< <marc@questright.com> >>
111 You may distribute this code under the same terms as Perl itself.