Commit | Line | Data |
c1cac633 |
1 | package DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server; |
2 | use strict; |
3 | use warnings; |
4 | |
eb0323df |
5 | use base qw/DBIx::Class::Storage::DBI::MSSQL/; |
c1cac633 |
6 | |
7 | sub _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 | |
764a1b60 |
14 | my $alias2src = $self->_resolve_ident_sources($ident); |
15 | my %identity_insert_tables; |
16 | foreach my $bound (@{$bind}) { |
17 | my $col = $bound->[0]; |
18 | my $name_sep = $self->_sql_maker_opts->{name_sep} || '.'; |
19 | |
20 | $col =~ s/^([^\Q${name_sep}\E]*)\Q${name_sep}\E//; |
21 | my $alias = $1 || 'me'; |
22 | my $rsrc = $alias2src->{$alias}; |
23 | |
24 | my $is_auto_increment = $rsrc && $rsrc->column_info($col)->{is_auto_increment}; |
25 | my $table; |
26 | if ($is_auto_increment) { |
27 | $identity_insert_tables{$rsrc->from} = 1; |
259c0e40 |
28 | } |
29 | } |
c1cac633 |
30 | |
764a1b60 |
31 | my $identity_insert_on = join '', map { "SET IDENTITY_INSERT $_ ON; " } keys %identity_insert_tables; |
32 | my $identity_insert_off = join '', map { "SET IDENTITY_INSERT $_ OFF; " } keys %identity_insert_tables; |
33 | $sql = "$identity_insert_on $sql $identity_insert_off"; |
34 | |
259c0e40 |
35 | return ($sql, $bind); |
c1cac633 |
36 | } |
37 | |
2eebd801 |
38 | sub _execute { |
39 | my $self = shift; |
40 | my ($op) = @_; |
c1cac633 |
41 | |
2eebd801 |
42 | my ($rv, $sth, @bind) = $self->dbh_do($self->can('_dbh_execute'), @_); |
77af494b |
43 | if ($op eq 'insert') { |
44 | $self->{_scope_identity} = $sth->fetchrow_array; |
45 | $sth->finish; |
46 | } |
c1cac633 |
47 | |
2eebd801 |
48 | return wantarray ? ($rv, $sth, @bind) : $rv; |
c1cac633 |
49 | } |
50 | |
51 | sub last_insert_id { shift->{_scope_identity} } |
52 | |
c1cac633 |
53 | 1; |
54 | |
55 | __END__ |
56 | |
57 | =head1 NAME |
58 | |
a89c6fc0 |
59 | DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server - Support specific |
60 | to Microsoft SQL Server over ODBC |
c1cac633 |
61 | |
62 | =head1 DESCRIPTION |
63 | |
64 | This class implements support specific to Microsoft SQL Server over ODBC, |
65 | including auto-increment primary keys and SQL::Abstract::Limit dialect. It |
66 | is loaded automatically by by DBIx::Class::Storage::DBI::ODBC when it |
67 | detects a MSSQL back-end. |
68 | |
69 | =head1 IMPLEMENTATION NOTES |
70 | |
71 | Microsoft SQL Server supports three methods of retrieving the IDENTITY |
72 | value for inserted row: IDENT_CURRENT, @@IDENTITY, and SCOPE_IDENTITY(). |
73 | SCOPE_IDENTITY is used here because it is the safest. However, it must |
74 | be called is the same execute statement, not just the same connection. |
75 | |
76 | So, this implementation appends a SELECT SCOPE_IDENTITY() statement |
77 | onto each INSERT to accommodate that requirement. |
78 | |
c1cac633 |
79 | =head1 AUTHORS |
80 | |
81 | Marc Mims C<< <marc@questright.com> >> |
82 | |
83 | =head1 LICENSE |
84 | |
85 | You may distribute this code under the same terms as Perl itself. |
86 | |
87 | =cut |
259c0e40 |
88 | # vim: sw=2 sts=2 |