DBD-SQLAnywhere
view release on metacpan or search on metacpan
returns a boolean.
Added CONFIGURE_REQUIRES parameter.
Changes in DBD::SQLAnywhere 2.12 17 Apr 2015
Fixed compliation problems with versions of ActivePerl that use MinGW, updated README.
Fixed statement preparsing to handle comments when looking for host variables.
Fixed problem with using "long long" with old Microsoft compilers.
Fixed some compiler warnings.
Changes in DBD::SQLAnywhere 2.11 27 Apr 2012
dbd_st_fetch did not return Nullav (end-of-cursor indication) when attempting
to fetch from a statement that is execute-only and can't return any
row (such as INSERT).
Changes in DBD::SQLAnywhere 2.10 15 September 2011
Corrected error reporting from more_results().
Changes in DBD::SQLAnywhere 2.09 23rd August 2011
Added support for more_results() which permits access to multiple result sets.
Example:
$sth->execute();
If fetch was called when there were no more rows, the driver set the err
value to (integer) zero but DBI could interpret that as a warning because
it converted it to a string and saw that it was non-empty. We now set
err to the empty string.
Changes in DBD::ASAny 1.13 7th Mar 2002, 3rd Sept 2003, 29th Oct 2003
Support 64bit UNIX platforms
Avoid compile-time warning about assign_blob()
Added /opt/sybase/SYBS* as default installation directories to search for ASA
An error was reported if execute() was called twice on the same statement
handle. Changed execute() to close a previously opened cursor using that
statement. Also, the prepared statement was being dropped during
finish() rather during destroy & that prevented the prepare_cache from
working.
Updated README to warn about resource governor errors now that statement
handles are not dropped until destroy time.
Set the "state" value on the handle when an error occurs.
Fetching 64-bit integers failed when they contained more than 8 digits
because we fetch them as strings but left the length as the size of the
bigint datatype (8 bytes).
Fixed additional compiler warnings from VC7.
Added CLONE method.
Added better handling for detecting new ASA versions -- should handle
up to version 15 now (version 9 is the highest shipping version).
Implemented the blob_read function which is an undocumented DBI API.
Changed the long string/binary fetching code so that long character strings
are fetched as varchar rather than binary so that character set translation
will be applied to the string.
Added a commit operation after a cursor is closed if AutoCommit is enabled.
Previously, a commit was only performed if a non-cursor statement was
executed. DML executed in procedures returning result sets were not
committed.
Added "-r" switch to sqlpp to generate thread-safe code.
Added dbtasks library to UNIX link lines.
Link against "_r" reentrant versions of ASA libraries when using ithreads
on UNIX platforms.
Avoid warning when building with VS.NET 2003 which has deprecated the
/Gf switch (automatically added by MakeMaker). Changed it to /GF.
Allow ASANY installation directory to be specified by the "ASANY{ver}"
environment variable (ASANY9, ASANY8, etc).
output SQLDA.
Correctly handle NULL output parameters from procedures.
Removed some debug printfs that snuck into v1.10.
Corrected README to show that bind_param_inout is a supported function.
Do not treat warnings as errors (err/errstr are still set but the calls
to execute/fetch will not report a failure).
Changes in DBD::ASAny 1.11 27th March 2001
Calling a procedure or batch that returned a result set for which
the engine could not infer the data types, errors were reported. Fixed
by describing the cursor after it was opened.
Changes in DBD::ASAny 1.10 13th November 2000
Added support for AutoCommit.
Changes in DBD::ASAny 1.09 21st September 2000
Added support for type_info_all and (indirectly) quote()
Added support for the following statement attributes:
TYPE, ASATYPE, SCALE, PRECISION, NULLABLE, CursorName,
Statement, and RowsInCache.
RowsInCache always returns undef.
Changes in DBD::ASAny 1.04 19th November 1999
Fixed inout parameter support.
Moved changes info from Makefile.PL to this file.
Changes in DBD::ASAny 1.03 9th November 1999
Driver now builds on HPUX, AIX, Linux with native and GNU compilers.
Dynamically resize SQLDA for bind variables or output values if the
default size is not large enough.
Avoid "memory leak" caused by dblib holding onto cursor information
so that the cursor can be reopend without being redeclared.
Changes in DBD::ASAny 1.02 21st October 1999
Driver should now be thread safe & it builds with the
threaded version of perl; however, perl threads and/or DBI
in a threaded environment is very unstable. Simple multithreaded
tests easily crash perl.
Changes in DBD::ASAny 1.01 5th August 1999
SQLAnywhere.pm view on Meta::CPAN
connection string.
The following is equivalent to the example above:
$dbh = DBI->connect( 'dbi:SQLAnywhere:ENG=demo', 'dba', 'sql' );
=head2 Prepared Statement and Cursor Limits
To help detect handle leaks in client applications, SQL Anywhere
defaults to limiting the number of prepared statements and open
cursors that any connection can hold at one time to 50 of each. If
that limit is exceeded, a "Resource governor ... exceeded" error is
reported. If you encounter this error, make sure you are dropping all
of your statement handles and, if so, consult the SQL Anywhere
documentation for the MAX_CURSOR_COUNT and MAX_STATEMENT_COUNT
options.
Note that prepared statements are not dropped from the SQL Anywhere
server until the statement handle is destroyed in the perl
script. Calling finish() is not sufficient to drop the handle that the
server is holding onto: use "undef" instead or reuse the same perl
} else {
name = SvPV( ph_namesv, name_len );
}
// FIXME: Why croak() and not just report an error?
if( SvTYPE(newvalue) > SVt_PVLV ) { /* hook for later array logic */
croak( "Can't bind a non-scalar value" );
}
if( SvROK(newvalue) && !IS_DBI_HANDLE(newvalue) ) {
/* dbi handle allowed for cursor variables */
croak( "Can't bind a reference (%s)", neatsvpv(newvalue,0) );
}
if( SvTYPE(newvalue) == SVt_PVLV && is_inout ) { /* may allow later */
croak( "Can't bind ``lvalue'' mode scalar as inout parameter" );
}
if( DBIS->debug >= 2 ) {
PerlIO_printf( DBILOGFP, " bind %s <== %s (type %ld",
name, neatsvpv(newvalue,0), (long)sql_type );
// return value <= -2:error, >=0:ok row count, (-1=unknown count) */
{
dTHR;
dTHX;
D_imp_dbh_from_sth;
int do_commit = FALSE;
int sqlcode;
int num_cols;
SACAPI *sacapi = imp_dbh->sacapi;
// If a cursor is still open, it must be closed before we open another
// one on the same handle.
dbd_st_finish( sth, imp_sth );
if( !really_bind( aTHX_ sth, imp_sth ) ) {
return( -2 );
}
sacapi->api.sqlany_execute( imp_sth->statement );
sqlcode = sacapi->api.sqlany_error( imp_dbh->conn, NULL, 0 );
num_cols = sacapi->api.sqlany_num_cols( imp_sth->statement );
// A failure to execute or there is no cursor open
if( sqlcode == SQLE_NOTFOUND ) {
// num_cols == 0 implies it was execute-only (and no cursor)
if( num_cols == 0 && !assign_output_parameters( aTHX_ sth, imp_sth ) ) {
return( -2 );
}
sv_setpv( DBIc_ERR(imp_sth), "" );
return( 0 ); // No rows affected
}
// This error case for SQLE_TRUNCATED as well because there is no
// way to call GET DATA without a cursor.
if( sqlcode < 0 ) {
ssa_error( aTHX_ sth, imp_dbh->conn, SQLE_ERROR, "execute failed" );
if( DBIS->debug >= 3 ) {
PerlIO_printf( DBILOGFP, " dbd_st_execute failed, rc=%d", sqlcode );
}
return( -2 );
}
if( sqlcode > 0 ) {
// Just a warning
ssa_error( aTHX_ sth, imp_dbh->conn, SQLE_ERROR, "warning during execute" );
if( DBIS->debug >= 3 ) {
PerlIO_printf( DBILOGFP, " dbd_st_execute warning, rc=%d", sqlcode );
}
}
if( num_cols == 0 ) {
// executed already & no cursor
if( !assign_output_parameters( aTHX_ sth, imp_sth ) ) {
return( -2 );
}
imp_sth->row_count = sacapi->api.sqlany_affected_rows( imp_sth->statement );
if( DBIc_has(imp_dbh,DBIcf_AutoCommit) ) {
sacapi->api.sqlany_commit( imp_dbh->conn );
}
} else {
// A cursor is open
if( DBIS->debug >= 2 ) {
PerlIO_printf( DBILOGFP, "Cursor opened\n" );
}
imp_sth->row_count = sacapi->api.sqlany_num_rows( imp_sth->statement );
}
DBIc_NUM_FIELDS(imp_sth) = num_cols;
DBIc_ACTIVE_on(imp_sth);
// Negative row-counts are estimates but dbperl wants a positive
if( !DBIc_ACTIVE(imp_sth) ) {
if( DBIS->debug >= 3 ) {
PerlIO_printf( DBILOGFP, "blob_read on inactive handle\n" );
}
ssa_error( aTHX_ sth, NULL, SQLE_CURSOR_NOT_OPEN, "no statement executing" );
return( 0 );
}
if( imp_sth->statement == NULL ) {
if( DBIS->debug >= 3 ) {
PerlIO_printf( DBILOGFP, "blob_read on non-cursor statement\n" );
}
return( 0 ); // we figured it was just an EXECUTE
}
if( field >= sacapi->api.sqlany_num_cols( imp_sth->statement ) ) {
if( DBIS->debug >= 3 ) {
PerlIO_printf( DBILOGFP, "blob_read: field number too large\n" );
}
return( 0 );
}
eg/blobs.pl view on Meta::CPAN
# discouraged in production code. A best practice for production
# code would be to prompt the user for the userid and password.
use DBI;
use strict;
my $dbh;
my $ins;
my $nrows;
my $upd;
my $cursor;
my $sth;
my $blob1;
my $blob2;
my $bloblen = 1000000;
my $i;
$| = 1;
my $connstr = 'ENG=demo;DBN=demo;DBF=demo.db;UID=dba;PWD=sql';
print "Connecting to Database\n";
eg/blobs.pl view on Meta::CPAN
} else {
printf( "Inserts complete\n" );
}
$ins->finish;
undef $ins;
#
# Check the inserts values by fetching the values back
#
printf( "Checking inserts\n" );
$cursor = $dbh->prepare( "select a, b from blobs" );
$cursor->execute();
$nrows = 0;
while( ($a,$b) = $cursor->fetchrow() ) {
$nrows++;
if( $a ne $blob1 && $a ne $blob2 ) {
die( "******ERROR: Fetched value for column a is incorrect: %s\n", $a );
}
if( $b ne $blob1 && $b ne $blob2 && $b ne "jcs" ) {
die( "******ERROR: Fetched value for column b is incorrect: %s\n", $b );
}
}
if( defined( $cursor->err ) && defined( $cursor->errstr ) ) {
die( "******ERROR: err %d, errstr %s\n", $cursor->err, $cursor->errstr );
} elsif( $nrows != 3 ) {
die( "******ERROR: Incorrect number of rows fetched: %d\n", $nrows );
} else {
printf( "Inserts OK\n" );
}
$cursor->finish();
#
# Do some updates
#
printf( "Doing updates\n" );
$upd = $dbh->prepare( 'update blobs set b=? where a=?' );
$upd->execute( $blob1, $blob1 ) || die( "update failed\n" );
$dbh->commit();
$upd->finish();
#
# Check updates
#
printf( "Checking updates\n" );
$cursor = $dbh->prepare( "select a, b from blobs" );
$cursor->execute();
$nrows = 0;
while( ($a,$b) = $cursor->fetchrow() ) {
$nrows++;
if( $a eq $blob1 && $b ne $blob1 ) {
die( "******ERROR: Update didn't work correctly\n" );
}
if( $a ne $blob1 && $a ne $blob2 ) {
die( "******ERROR: Fetched value for column a is incorrect\n" );
}
if( $b ne $blob1 && $b ne $blob2 && $b ne "jcs" ) {
die( "******ERROR: Fetched value for column b is incorrect\n" );
}
}
if( defined( $cursor->err ) && defined( $cursor->errstr ) ) {
die( "******ERROR: err %d, errstr %s\n", $cursor->err, $cursor->errstr );
} elsif( $nrows != 3 ) {
die( "******ERROR: Incorrect number of rows fetched: %d\n", $nrows );
} else {
printf( "Updates OK\n" );
}
$cursor->finish();
$dbh->commit();
$dbh->do( 'drop table blobs' );
$dbh->disconnect();
undef $dbh;
lib/DBD/SQLAnywhere/GetInfo.pm view on Meta::CPAN
constraint
contains
continue
convert
create
cross
cube
current
current_timestamp
current_user
cursor
date
dbspace
deallocate
dec
decimal
declare
default
delete
deleting
desc
( run in 0.271 second using v1.01-cache-2.11-cpan-4d50c553e7e )