× 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.


  • Subject: Re: Retrieving formatted message in SQL
  • From: Buck Calabro <kc2hiz@xxxxxxxxx>
  • Date: Fri, 15 Feb 2019 16:01:11 -0500
  • Autocrypt: addr=kc2hiz@xxxxxxxxx; keydata= mQGiBEcbaT4RBADqmM9OgXil65pjrxclJpxuAF6vraI3kkmJbEHb5ElL7EquHE3QDuFqFgIB 4NZLHDbVAh0AD5exAX+r+xg//UvtBc2k34HROnCpWTMnIOaSVhhVjpYEbZGLz6wfrRpu4Qyn 45iaKT4F0qcHo+0LrGQPef3xrFkUhxURgzY5zgo6+wCg/XjYJ155witPWB2CbNf6RAm9QT0D /jSp6YhvE3xPE12aBuRYM678JTbaQfuYv4HUfug1Wz/0zH5btfEihWVN4wbKaoQ/H/29v2TP /Lyh8XTVd3Z0rz4iaSD5fGicn81WPANBeIepLB8vpfEik6UhHpN1DJkz6Ryw2mgx8p53LhHV Ck4Jt0HP2TAl3f7QTXGFOiFzJwEqBACsHk/gFpKAHdv7n4vJoHqp0RNgOOyhnTThlulPilt6 tAaSe10FOrrugBuLMn7wXBANQ1ApmIb5yNjhYqPREj65OVv2MUbw8H2HnQs//Z6aodyR/kzU 2q2G9A/YFI1LL0m/gvaVbEj/wE0ybBgFkrcoEFeStkqS5HzLEFGUDFXhD7QfQnVjayBDYWxh YnJvIDxrYzJoaXpAZ21haWwuY29tPoiFBBMRAgBFAhsDBgsJCAcDAgQVAggDBBYCAwECHgEC F4AFAkcbdMokGGh0dHA6Ly9rZXlzZXJ2ZXIudmVyaWRpcy5jb206MTEzNzEvAAoJEN7KcclH umuRfngAoNXU6AXqyTR8FRuoXKBGS4k7bPUEAJ912WKSkjpCt0axjrq6j22e5XgWzbkCDQRH G2k+EAgAnLXJ9hOqedgsIYM3LuomBBNN+7WTFSVaJ3Rqz8XVZtJvLL0bIRAvpVK9L9rYXlCR cPAm0YNK6H2DR7sQxWlxEH4mWB+jTCTALpcVq+Kpfbw5qDdn+9DVMS7tBOchtTlPSGgdKgn7 sTObra8cHtX/ddTB6OLzHeTXr4PZbUwVeQdIStdwMmozKBQvgjXWKi1GiuYbwYkCM/zJEUCs J36BIE4li9xohJ5O4iKC20YVckMJfZLbn1a2gVgn6Re8C5ezNewT0qM8ZDCUNENWAxsU/c9J UCFQ2QcMU+25b84D5yPxnEKna5U9Fz2JjRjWy5ZKZx2+WhZj0r2Tw6/kGb28AwADBgf/WBsn JSMHxyVfg+LKLHpdANwa9jdrKOt2WjJbWOiJ9l7SmqD0oi3c22FFxRXKsFfjCikLk9wbLZKH SqqnOePvMMHqNcqQTSv7+ARjxnBH4g6dhqg+zmebKpt8zV2awQzYSSm4YY6IqzkWmPNAN7BU zUtSAfL4UU2PljTnT9m443aVCTXMne5l90HQv/gdJ121owg5KuGE6LodTpoR4hn9nbdKWtfY pDNoykvR+GN5y335yF2Zp/j6QgdxWezjou5Y3/6PUZLEsJagWe9hAcKb1eiO2bmg+1bFYu0T g5Mvb27nqfFeHHFysC7a7sXtxp/pqNLNDcK6j/7Th6vF7/n98YhJBBgRAgAJBQJHG2k+AhsM AAoJEN7KcclHumuR9SgAnRuJWHon4GP58xbqCiFR/jSUfvRgAJ47KZ1UNoXgdftoePnbrZu6 W+poEw==
  • List-archive: <https://archive.midrange.com/midrange-l/>
  • List-help: <mailto:midrange-l-request@lists.midrange.com?subject=help>
  • List-id: Midrange Systems Technical Discussion <midrange-l.lists.midrange.com>
  • List-post: <mailto:midrange-l@lists.midrange.com>
  • List-subscribe: <https://lists.midrange.com/mailman/listinfo/midrange-l>, <mailto:midrange-l-request@lists.midrange.com?subject=subscribe>
  • List-unsubscribe: <https://lists.midrange.com/mailman/options/midrange-l>, <mailto:midrange-l-request@lists.midrange.com?subject=unsubscribe>

On 2/15/2019 2:51 PM, dlclark@xxxxxxxxxxxxxxxx wrote:
"MIDRANGE-L" <midrange-l-bounces@xxxxxxxxxxxxxxxxxx> wrote on 02/15/2019
11:45:13 AM:
I've written a UDTF by myself based on the QMHRTVM API.

Mit freundlichen Grüßen / Best regards

Birgitta Hauser


Birgitta, any chance I could get a copy of it for the purpose of
learning by example? I haven't written a UDTF before. I also wonder how
you're using the API from SQL?

I apologise for being so brief; I'm in the middle of a bunch of stuff
:-/ Here is a proof of concept that returns n rows of QRPGLESRC:

h* SQL User Defined Table Function proof of concept
h/copy qrpglesrc,stdhspec
hCCSID(*exact)

* create function buck.SQLUDTF(rows_to_retrieve int)
* returns table
* ( source_sequence numeric (6, 2),
* source_date numeric (6, 0),
* source_data char (100) )
* language rpgle
* parameter style db2sql
* not deterministic
* reads sql data
* returns null on null input
* external action
* not fenced
* program type main
* no final call
* disallow parallel
* no scratchpad
* external name BUCK.SQLUDTF
* cardinality 100;
*
* select * from table(buck.SQLUDTF(4)) as source;

dSQLUDTF pr
d*input
d nbrToRtv_in 10i 0 const
d*output
d seq 6s 2
d date 6s 0
d source_data 100
d*input null map
d nbrToRtv_in_null...
d like(IS_NULL) const
d*output null map
d seq_null...
d like(IS_NULL)
d date_null...
d like(IS_NULL)
d source_data_null...
d like(IS_NULL)
d*SQL feedback
d sqlstate_out 5a
d functname 517 const options(*varsize) varying
d specname 128 const options(*varsize) varying
d errormsg 70 options(*varsize) varying
d calltype 10i 0

dSQLUDTF pi
d*input
d nbrToRtv_in 10i 0 const
d*output
d seq 6s 2
d date 6s 0
d source_data 100
d*input null map
d nbrToRtv_in_null...
d like(IS_NULL) const
d*output null map
d seq_null...
d like(IS_NULL)
d date_null...
d like(IS_NULL)
d source_data_null...
d like(IS_NULL)
d*SQL feedback
d sqlstate_out 5a
d functname 517 const options(*varsize) varying
d specname 128 const options(*varsize) varying
d errormsg 70 options(*varsize) varying
d calltype 10i 0

d* work fields
d SQL_NORMAL s 5 inz('00000')
d SQL_NODATA s 5 inz('02000')
d IS_NULL s 5i 0 inz(-1)
d NOT_NULL s 5i 0 inz(0)
d rows_returned s 10i 0 inz
d r s 10i 0

c/free

exec sql
set option naming = *sys, closqlcsr = *endactgrp, commit = *none,
dynusrprf=*owner;

// External UDTFs like this get called many times for a given SQL
statement
// once for open (-1)
// many times each for fetch (0)
// once for close (1)
// WE tell the database when we're done by setting the outbound
SQLstate

sqlstate_out = SQL_NORMAL;

select;
when calltype = -1;
exsr UDTF_open;
when calltype = 0;
exsr UDTF_fetch;
when calltype = 1;
exsr UDTF_close;
*inlr = *on;
endsl;

// No LR until we're really done done.
return;

//------------------------------------------------------------------
begsr UDTF_open;

// number of rows retrieved so far
r = 0;

exec sql
declare SOURCE_RECORDS cursor for
select SRCSEQ, SRCDAT, SRCDTA
from QRPGLESRC
order by SRCSEQ;

exec sql
open SOURCE_RECORDS;

// if abnormal, forward the SQLSTT to the database manager and quit
// really needs some error handling but this is a demo
if sqlstate <> SQL_NORMAL;
sqlstate_out = sqlstate;
dump(a) 'open()';
*inlr = *on;
endif;

endsr;

//------------------------------------------------------------------
begsr UDTF_fetch;

exec sql
fetch next
from SOURCE_RECORDS
into :seq, :date, :source_data;

// tell the database manager how this FETCH went
sqlstate_out = sqlstt;
r += 1;

if sqlstt = SQL_NORMAL;
rows_returned = sqler3;
// we got rows; set all columns to NOT NULL
seq_null = NOT_NULL;
date_null = NOT_NULL;
source_data_null = NOT_NULL;
else;
if sqlstt = SQL_NODATA;
// return to database manager with NODATA set
// the next call to the UDTF will be to CLOSE
return;
else;
// needs real error handling!
dump(a) 'fetch()';
return;
endif;
endif;

// if we have read the requested number of rows, exit early
if nbrToRtv_in_null = NOT_NULL and
r > nbrToRtv_in;
sqlstate_out = SQL_NODATA;
endif;

if r = 1;
// for kicks, set this row to NULL
seq_null = IS_NULL;
date_null = IS_NULL;
endif;

endsr;


//------------------------------------------------------------------
begsr UDTF_close;
exec sql
close SOURCE_RECORDS;
endsr;


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.