Re: Error I've not seen before from oracle DBD

"Martin J. Evans" <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.dbi.general
Organization Easysoft Limited
Message-ID <[email protected]>
On 29/03/12 22:10, Bruce Johnson wrote:
>
> On Mar 29, 2012, at 1:58 PM, Bill Ward wrote:
>
>> Try not using numbers for the placeholder names?
>>
>
> That worked...
>
> my $sq_res_pend = "insert into reservations_pend (pid, email, cn, purpose, reserver_affstring) values(:A,:B,:C,:D,:E) returning reservations_pend_id into :NEWID";
>
> my $csr_res_pend = $lda->prepare($sq_res_pend) or die $DBI::errstr;
> $csr_res_pend->bind_param(':A',$res_pid) or die $DBI::errstr;
> $csr_res_pend->bind_param(':B',$res_email) or die $DBI::errstr;
> $csr_res_pend->bind_param(':C',$res_name) or die $DBI::errstr;
> $csr_res_pend->bind_param(':D',$res_purp) or die $DBI::errstr;
> $csr_res_pend->bind_param(':E',$res_affil) or die $DBI::errstr;
> $csr_res_pend->bind_param_inout(":NEWID",\$new_res_id, 25) or die $DBI::errstr;
>
> $csr_res_pend->execute();
>
> Got right through.
>
> Is this a bug or a rule I'm not aware of?
>
>

It is a rule in so far that, that is what the code says. Placeholders of the form :N (where N is a number) are deemed different from placeholders of the form :A (where the first chr of A is not a number) are deemed different from placeholders of the form ?.

Looking at the code (which I did not write) :N is a special case in that you cannot have multiple Ns in the SQL where :A forms can be repeated in the SQL. The ? form is just changed to :N internally in the code.

The relevant code is:

if (*start == '?') {		/* X/Open standard	*/
	sprintf(start,":p%d", ++idx); /* '?' -> ':p1' (etc)	*/
	dest = start+strlen(start);
	style = "?";

}
else if (isDIGIT(*src)) {	/* ':1'		*/
	idx = atoi(src);
	*dest++ = 'p';		/* ':1'->':p1'	*/
	if (idx <= 0)
		croak("Placeholder :%d invalid, placeholders must be >= 1", idx);

	while(isDIGIT(*src))
		*dest++ = *src++;
	style = ":1";

}
else if (isALNUM(*src)) {	/* ':foo'	*/
	while(isALNUM(*src))	/* includes '_'	*/
		*dest++ = toLOWER(*src), src++;
	style = ":foo";

} else {			/* perhaps ':=' PL/SQL construct */
	/* if (src == ':') *dest++ = *src++; XXX? move past '::'? */
	continue;
}

*dest = '\0';			/* handy for debugging	*/
namelen = (dest-start);
if (laststyle && style != laststyle)
	croak("Can't mix placeholder styles (%s/%s)",style,laststyle);

The DBI documentation is too vague in this respect to say DBD::Oracle is wrong here. I also know some drivers which support :xxx but then when you call bind_param you don't specify the leading ':' (subject of a dbi-dev posting of mine some years back). There are also drivers which support :xxx but you cannot put that exact :xxx more than once in the SQL (you can with DBD::Oracle).

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.