× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



On 06-Nov-2013 04:22 -0800, rob@xxxxxxxxx wrote:
Too bad you can't do something like this
CREATE VIEW QS36F/JIMMYV (MYAMT) AS
SELECT cast(substr(f00002,1,10) as dec(5,2)) as myamt
FROM qs36f/jimmy
-- JIMMY in QS36F not valid for operation. (SQL7008)

If the character string result of the SUBSTR scalar expression was not always a string of alphanumerics representing a valid numeric literal\constant [i.e. optional sign followed by three or fewer digits, followed by an optional decimal separator and more consecutive digits if that separator was included, followed only by blanks], then that casting is not going to function. But most likely the physical numeric data in the S/36 file would not be in that [external\visible] string representation, rather the numeric data would be stored in one of the internal representations: INTEGER, PACKED, or ZONED.

Of course casting a packed field from a substring could be fun.

The mapping from a substring of a binary string of data in the internal Packed BCD form, into a value of a numeric data type with an SQL expression has been documented many times on this list and elsewhere; albeit often somewhat incomplete, no matter where. Although not possible to encapsulate the SELECT in a VIEW, a SQL SELECT can still operate against the program-described file. Rather than including links to some old messages, I will include an example below:

Given there is a binary string of data that represents data for a DEC(19,2) data type value, in the first 10-bytes of the column F00002, then the following expression would likely suffice; i.e. while ignoring an invalid sign nibble produces a positive result rather than an error, invalid digits remain a potential issue:

select
cast( ( Dec( left( hex( substr(F00002, 1, 10) ), 19 ), 19)
* case when
right(hex( substr(F00002, 1, 10) ), 1 ) IN ('D', 'B')
then -1. /* 0xD & 0xB as nibbles -> BCD negative */
else 1. /* assume, ignoring baddta: BCD positive */
end
) / 100.
as decimal(19, 2) )
from jimmy

Or to encapsulate the above expression in a function, a SQL scalar UDF, for example supporting only up to 31 digits and leaving both the division to the invoker in order to effect a desired scale and casting for the desired precision and scale... the following two requests, for example:

create function VCtoDec31( s varchar(16) )
returns dec(31)
language sql /* could add begin\end and return null on error */
return /* expression could change to _fix_ invalid digits too */
dec( left( hex( s ), int( length( s ) * 2 - 1 ) ), 31 )
* case when right( hex( s ), 1 ) in ('D', 'B') then -1. else 1. end

select
cast( VCtoDec31( substr(F00002, 1, 10) ) / 100.
as decimal(19, 2) )
from jimmy


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.