1 package DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server;
5 use base qw/DBIx::Class::Storage::DBI::MSSQL/;
12 my ($source, $cols, $data) = @_;
14 my $identity_insert = 0;
17 foreach my $col (@{$cols}) {
18 if ($source->column_info($col)->{is_auto_increment}) {
24 if ($identity_insert) {
25 my $table = $source->from;
26 $self->dbh->do("SET IDENTITY_INSERT $table ON");
29 $self->next::method(@_);
31 if ($identity_insert) {
32 my $table = $source->from;
33 $self->dbh->do("SET IDENTITY_INSERT $table OFF");
37 sub _prep_for_execute {
39 my ($op, $extra_bind, $ident, $args) = @_;
41 # cast MONEY values properly
42 if ($op eq 'insert' || $op eq 'update') {
43 my $fields = $args->[0];
44 my $col_info = $self->_resolve_column_info($ident, [keys %$fields]);
46 for my $col (keys %$fields) {
47 if ($col_info->{$col}{data_type} =~ /^money\z/i) {
48 my $val = $fields->{$col};
49 $fields->{$col} = \['CAST(? AS MONEY)', [ $col => $val ]];
54 my ($sql, $bind) = $self->next::method (@_);
56 if ($op eq 'insert') {
57 $sql .= ';SELECT SCOPE_IDENTITY()';
59 my $col_info = $self->_resolve_column_info($ident, [map $_->[0], @{$bind}]);
60 if (List::Util::first { $_->{is_auto_increment} } (values %$col_info) ) {
62 my $table = $ident->from;
63 my $identity_insert_on = "SET IDENTITY_INSERT $table ON";
64 my $identity_insert_off = "SET IDENTITY_INSERT $table OFF";
65 $sql = "$identity_insert_on; $sql; $identity_insert_off";
76 my ($rv, $sth, @bind) = $self->dbh_do($self->can('_dbh_execute'), @_);
77 if ($op eq 'insert') {
78 $self->{_scope_identity} = $sth->fetchrow_array;
82 return wantarray ? ($rv, $sth, @bind) : $rv;
85 sub last_insert_id { shift->{_scope_identity} }
93 DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server - Support specific
94 to Microsoft SQL Server over ODBC
98 This class implements support specific to Microsoft SQL Server over ODBC,
99 including auto-increment primary keys and SQL::Abstract::Limit dialect. It
100 is loaded automatically by by DBIx::Class::Storage::DBI::ODBC when it
101 detects a MSSQL back-end.
103 =head1 IMPLEMENTATION NOTES
105 Microsoft SQL Server supports three methods of retrieving the IDENTITY
106 value for inserted row: IDENT_CURRENT, @@IDENTITY, and SCOPE_IDENTITY().
107 SCOPE_IDENTITY is used here because it is the safest. However, it must
108 be called is the same execute statement, not just the same connection.
110 So, this implementation appends a SELECT SCOPE_IDENTITY() statement
111 onto each INSERT to accommodate that requirement.
115 Marc Mims C<< <marc@questright.com> >>
119 You may distribute this code under the same terms as Perl itself.