On Tue, Jan 29, 2002 at 07:56:36AM -0800, Michael Peppler wrote:
> [ redirected to dbi-users ]
> 
> Abi Pothen writes:
>  > Hi,
>  >   I am having a problem with DBD::ODBC (version 0.31) that has fixes to 
>  > handle multiple result set. This fix is working fine only when the number of 
>  > columns of the previous result set is equal to or greater than the number of 
>  > columns of the following result set. If the number of columns of the result 
>  > set of the previous result set is greater than the following, SQLFetch 
>  > function call is failing and returning -1.
> 
> I've had to handle that in DBD::Sybase (as well as clearing the
> NAME_xx attribute cache between result sets).
> 
> I'm not sure that I've got the best solution, but I have code like
> this in dbdimp.c between result sets:
> 
>     av = DBIS->get_fbav(imp_sth);
>     num_fields = AvFILL(av)+1;
> 
>     /* XXX
>        The code in the if() below is likely to break with new versions
>        of DBI!!! */
>     if(num_fields < imp_sth->numCols) {
>       int isReadonly = SvREADONLY(av);
>       if(isReadonly)
>           SvREADONLY_off(av);         /* DBI sets this readonly  */
>       i = imp_sth->numCols - 1;
>       while(i >= num_fields)
>           av_store(av, i--, newSV(0));
>       num_fields = AvFILL(av)+1;
>       if(isReadonly)
>           SvREADONLY_on(av);          /* protect against shift @$row etc */
>     } else if(num_fields > imp_sth->numCols) {
>       int isReadonly = SvREADONLY(av);
>       if(isReadonly)
>           SvREADONLY_off(av);         /* DBI sets this readonly  */
>       av_fill(av, imp_sth->numCols - 1);
>       num_fields = AvFILL(av)+1;
>       if(isReadonly)
>           SvREADONLY_on(av);          /* protect against shift @$row etc */
>     }
> 
> and
> 
>             if(imp_sth->done_desc) {
>                 HV *hv = (HV*)SvRV(sth);
>                 HE *he;
> 
>                 cleanUp(imp_sth);
>                 
>                 hv_iterinit(hv);
>                 while((he = hv_iternext(hv))) {
>                     I32 i;
>                     char *key = hv_iterkey(he, &i);
>                     SV *sv = hv_iterval(hv, he);
> 
>                     if(strnEQ(key, "NAME", 4)) {
>                         if(dbis->debug >= 3)
>                             PerlIO_printf(DBILOGFP, 
>                              "    st_next_result() -> delete key %s (%s) from 
>cache\n",
>                                           key, neatsvpv(sv, 0));
> 
>                         hv_delete(hv, key, i, G_DISCARD);
>                     }
>                 }
>             }
> 
> I'm not really sure that this last bit is all that is needed, or the
> correct way to clear the cached attributes, but it seems to work.

There's also TYPE, PRECISION, SCALE, NULLABLE etc.

Umm, I should probably have the DBI provide a way to do that.
Thanks for posting the code.

 >>todo

Tim.

Reply via email to