MVSFORUMS.com Forum Index MVSFORUMS.com
A Community of and for MVS Professionals
 
 FAQFAQ   SearchSearch   Quick Manuals   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Is it possible to use an array as host variable ?
Goto page 1, 2  Next
 
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Application Programming
View previous topic :: View next topic  
Author Message
Jamylady
Beginner


Joined: 04 Nov 2004
Posts: 68
Topics: 22

PostPosted: Thu Jun 15, 2006 4:16 am    Post subject: Is it possible to use an array as host variable ? Reply with quote

Hi,
Is there any way where I can use an array as a host variable in the where condition of a cursor declaration?
Eg:
01 WS-STATE-ARRAY.
05 WS-STATES OCCOURS 50 TIMES PIC X(02).

01 WS-STATE-ARRAY-RED REDEFINES WS-STATE-ARRAY.
05 WS-STATE-1 PIC X(02) VALUE 'AA'.
.................................................
05 WS-STATE-1 PIC X(02) VALUE 'AZ'.

PROCEDURE DIVISION.
...
EXEC SQL
DECLARE STATE_CURS CURSOR FOR
SELECT STATE_NAME FROM
DNTSTATES
WHERE STATE_CD IN (:WS-STATE-ARRAY)
END-EXEC.
when I tried this, I am getting the follwoing error.
UNDEFINED OR UNUSABLE HOST VARIABLE \"WS-STATE-ARRAY\"
Could any one explain please?
Thanks
JA
Back to top
View user's profile Send private message
dz
Beginner


Joined: 02 Apr 2006
Posts: 26
Topics: 0

PostPosted: Thu Jun 15, 2006 8:17 am    Post subject: Reply with quote

DB2 precompiler can only resolve elementary declarations. For example, if you declare:

01 MAIN-ARRAY.
05 ELEM1 PIC X(02).
.........................
05 ELEM50 PIC X(02).

and use this in the cursor, then it will work. Remember to:
- move elements from OCCURS array to this array
- back fill elements at the end with, say, ELEM1 (assuming you do not need spaces).
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12378
Topics: 75
Location: San Jose

PostPosted: Thu Jun 15, 2006 8:27 am    Post subject: Reply with quote

Jamylady,

Try this code


Code:

01 WS-STATE-ARRAY.                                 
   05 WS-STATE-CODE OCCURS 50 TIMES.               
      10 WS-ST-NAME   PIC X(02).                   
                                                   
01 WS-STATE-R REDEFINES WS-STATE-ARRAY PIC X(100).



EXEC SQL
     DECLARE STATE_CURS CURSOR FOR
      SELECT STATE_NAME
        FROM DNTSTATES
       WHERE STATE_CD IN (:WS-STATE-R)
END-EXEC. 

MOVE 'AL'    TO WS-STATE-CODE(01)
MOVE 'AK'    TO WS-STATE-CODE(02)
....



Hope this helps...

Cheers

Kolusu
_________________
Kolusu
www.linkedin.com/in/kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
mangsk
Beginner


Joined: 05 Jun 2004
Posts: 46
Topics: 18

PostPosted: Thu Apr 09, 2009 5:29 pm    Post subject: Reply with quote

Kolusu,
I was facing the same issue and I searched the forum and found this 3 year old post. I tried the solution you suggested, but unfortunately this does not work.
I tried with 3 values and it gave me SQLCODE=100. But when I run it with just 1 value (only moving 'AL' in your example), then it works.
So, is there any solution on this problem yet?
Thank you.
_________________
Regards,
Mangsk
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12378
Topics: 75
Location: San Jose

PostPosted: Thu Apr 09, 2009 5:43 pm    Post subject: Reply with quote

mangsk,

How is your look up column defined? The example I posted above is when the column is defined as character of 2 bytes. If your Db2 column has a different length then you need to change the length of your host variable too.

Show me your DB2 column definition and a sample data

Kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
mangsk
Beginner


Joined: 05 Jun 2004
Posts: 46
Topics: 18

PostPosted: Fri Apr 10, 2009 12:20 pm    Post subject: Reply with quote

Kolusu,
Thank you for your quick turnaround on this.
Here is my array and redefined array definitions.

Code:
01  MTRX-ARRAY.                                         
    05 MTRX-ID            OCCURS 10 TIMES.         
       10 MTRX-ELEMENT        PIC X(26) VALUE SPACES.   
                                                           
01  MTRX-ARRAY-R  REDEFINES MTRX-ARRAY   PIC X(260).


This is how I declare cursor -
Code:
EXEC SQL                                       
  DECLARE MTRX_CSR CURSOR FOR               
      SELECT FIELD_1
           , FIELD_2
      FROM MTRX_TBL                       
      WHERE MTRX_ID IN (:MTRX-ARRAY-R)
END-EXEC.                 

Note that the MTRX_ID is defined as CHAR(26) in the database.
I picked up 3 values of MTRX_ID from the MTRX_TBL. Now I move these values just before I open the cursor

Code:
MOVE '20090323125220571772'   TO MTRX-ID(01)
MOVE '20090323125220583486'   TO MTRX-ID(02)
MOVE '20090323125220583617'   TO MTRX-ID(03)


Then I look at the MTRX-ARRAY-R when I am using debugging tool, these values are stored, but padded with spaces because they are not exactly 26 bytes.
When I fetch the cursor I get SQLCODE = 100 in first fetch.
Now I went in again to comment out last 2 statements so that it gets the cursor gets the result set using just 1 value, and this time SQLCODE=0 !
That drives me to this conclusion. Am I missing anything here?
_________________
Regards,
Mangsk
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12378
Topics: 75
Location: San Jose

PostPosted: Fri Apr 10, 2009 6:46 pm    Post subject: Reply with quote

mangsk,

I don't have a way to test it but can you try this and see if it works. Your look up field is 26 bytes and character type , so I am enclosing each host variable in quotes , so the length is increased to 28 bytes(opening and closing quote) and I padded spaces up to the 26th byte.

Code:


01  MTRX-ARRAY.                                     
    05 MTRX-ID            OCCURS 10 TIMES.           
       10 MTRX-ELEMENT    PIC X(28).
                                                     
01  MTRX-ARRAY-R  REDEFINES MTRX-ARRAY   PIC X(280).


MOVE SPACES TO MTRX-ARRAY-R                         

MOVE "'20090323125220571772      '"   TO MTRX-ID(01)
MOVE "'20090323125220583486      '"   TO MTRX-ID(02)
MOVE "'20090323125220583617      '"   TO MTRX-ID(03)


If it works then you can use a STRING statement to concatenate all the values into a single string.

Let me know if this approach works

Kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
mangsk
Beginner


Joined: 05 Jun 2004
Posts: 46
Topics: 18

PostPosted: Mon Apr 13, 2009 8:51 am    Post subject: Reply with quote

Kolusu,
Thanks for your help.
I tried this, but it does not work. Now when I comment out last 2 lines (as mentioned in earlier post), it still returns SQLCODE=100.
_________________
Regards,
Mangsk
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
dbzTHEdinosauer
Supermod


Joined: 20 Oct 2006
Posts: 1411
Topics: 26
Location: germany

PostPosted: Mon Apr 13, 2009 9:32 am    Post subject: Reply with quote

MATRIX_ID looks suspiciously like a timestamp.
please do a spufi of the table and select one of the MATRIX_ID's and cut&paste in your reply.

also, please provide the DDL definition of the column in the table. (again, please cut&paste).

what Kolusu has shown you will work, as long as everything is defined properly.
_________________
Dick Brenholtz
American living in Varel, Germany
Back to top
View user's profile Send private message
mangsk
Beginner


Joined: 05 Jun 2004
Posts: 46
Topics: 18

PostPosted: Mon Apr 13, 2009 11:05 am    Post subject: Reply with quote

dbzTHEdinosauer,
Thanks for the reply.
The MATRIX_ID's mentioned in above mentioned posts are directly taken from SPUFI's against the table.
The definition of MATRIX_ID is (actual copy and pasted from platinum screen)-
MATRIX_ID CHAR(26)
whereas other fields such as CREATE_TIMESTAMP who are of type 'TIMESTMP' show the datatype as 'TIMESTMP'.
You are right, it is a derived value from actual timestamp. This table is populated from a JAVA program which creates unique MATRIX_ID's to insert the row (with information user has entered on a screen) into the table and it derives this timestamp-look-alike MATRIX_ID from actual timestamp of creation.
_________________
Regards,
Mangsk
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
dbzTHEdinosauer
Supermod


Joined: 20 Oct 2006
Posts: 1411
Topics: 26
Location: germany

PostPosted: Mon Apr 13, 2009 12:56 pm    Post subject: Reply with quote

I apologize. The single-quote is incorrect.

return to the 26 char definition for your cobol internal item size.

you are getting a hit on one of the pseudo-timestamps.
try testing by making it the 2nd occurance in your cobol internal table.

either you have incorrect pseudo-timestamps in your IN List
or your columns are sometimes right justified
or your columns sometimes contain low-values.

the methodology works, something, I believe is wrong with your data.
_________________
Dick Brenholtz
American living in Varel, Germany
Back to top
View user's profile Send private message
mangsk
Beginner


Joined: 05 Jun 2004
Posts: 46
Topics: 18

PostPosted: Tue Apr 14, 2009 8:45 am    Post subject: Reply with quote

dbzTHEdinosauer,

Now I reverted back to kolusu's original solution of 26 bytes.
While I carry out my test, I am using an Intertest(debugging tool similar to Xpeditor). There I can see the values of variables. Here I looked at the value of MTRX-ARRAY-R and it has no low-values, all X'40' in hex padded everywhere.
Also, I commented out 1st and 3rd occurrence and executed just by populating 2nd occurrence, but a SQLCODE=100 this time.
One question though - In the IN clause, we specify values seperated by commas. So when we use redefines clause, there are no commas to seperate our 26 byte values. Now does DB2 know that it has to match the column value with 1st 26 bytes or next 26 bytes etc?
_________________
Regards,
Mangsk
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
dbzTHEdinosauer
Supermod


Joined: 20 Oct 2006
Posts: 1411
Topics: 26
Location: germany

PostPosted: Tue Apr 14, 2009 9:01 am    Post subject: Reply with quote

what I wanted was you to test with the 3 timestamps.
but switch the 1st with the 2nd.
earlier you tested with 3. sqlcode +100
then you removed the last 2, sqlcode 0
so, 1st is good, 2nd and 3rd are bad.
so, put the 1st in the 2nd position
and the 2nd in the 1st position.

no, don't need the commas when your IN List is a host variable array.
db2 knows the column size. it just looks at each 26 bytes.
when you use literals or separate host variables,
the comma in the sql is used by the pre-compiler to build an IN List table.

you could also test by having references to each item, and change your sql
to be a list of host variables, separated by commas. that will proved the validity of all your timestamps.

that is the first thing that you need to do. test each timestamp to insure that it will return a result table for the cursor.
_________________
Dick Brenholtz
American living in Varel, Germany
Back to top
View user's profile Send private message
jsharon1248
Intermediate


Joined: 08 Aug 2007
Posts: 291
Topics: 2
Location: Chicago

PostPosted: Tue Apr 14, 2009 9:58 am    Post subject: Reply with quote

I really hate to disagree with dbz and Kolusu, but I don't think you can use a host variable array in an IN clause of a SELECT. I know I've tried this, but I never got it to work. DB2 is going to interpret the host variable specified in the IN clause as a single character string. DB2 won't know that there's an OCCURS clause in the COBOL pgm when the variable is used in the context of a WHERE clause. To the best of my knowledge, host variable arrays can only be used for multiple-row FETCH and INSERT. I found this statement in the Using host variables and host variable arrays section in Chapter 9 Embedding SQL statements in host languages of the DB2 Application and Programming and SQL Guide:
Code:
You define host variable arrays for use with multiple-row FETCH and INSERT statements.


The only options I know to code an IN list are:
1) Hard code a series of host variables in the IN list. Populate the ones you need and set the others to a value that doesn't exist in the table (low-values, high-values, etc)
2) Use dynamic SQL and generate the IN list programmatically.
Back to top
View user's profile Send private message
dbzTHEdinosauer
Supermod


Joined: 20 Oct 2006
Posts: 1411
Topics: 26
Location: germany

PostPosted: Tue Apr 14, 2009 10:07 am    Post subject: Reply with quote

jsharon1248,

sorry, but you are wrong.

it could be that we need to pre-fill the array with high values,
that the IN List objects actually are in error - only one will gen a hit.

I have used these with alpha and numeric types, even substr(?) IN list

not having access to the code in question in this topic,
not being able to motivate the OP to test as I would.
Trying to inspire someone to experiment in the environment that seems to
prevail in the sweatshops in India is itself a daunting task.

But, you can build an host array for IN list and a LIKE list.

why would it work in dynamic SQL and not in imbedded?
_________________
Dick Brenholtz
American living in Varel, Germany
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Application Programming All times are GMT - 5 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


MVSFORUMS
Powered by phpBB © 2001, 2005 phpBB Group