View previous topic :: View next topic |
Author |
Message |
Jamylady Beginner
Joined: 04 Nov 2004 Posts: 68 Topics: 22
|
Posted: Thu Jun 15, 2006 4:16 am Post subject: Is it possible to use an array as host variable ? |
|
|
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 |
|
 |
dz Beginner
Joined: 02 Apr 2006 Posts: 26 Topics: 0
|
Posted: Thu Jun 15, 2006 8:17 am Post subject: |
|
|
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 |
|
 |
kolusu Site Admin

Joined: 26 Nov 2002 Posts: 12378 Topics: 75 Location: San Jose
|
Posted: Thu Jun 15, 2006 8:27 am Post subject: |
|
|
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 |
|
 |
mangsk Beginner

Joined: 05 Jun 2004 Posts: 46 Topics: 18
|
Posted: Thu Apr 09, 2009 5:29 pm Post subject: |
|
|
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 |
|
 |
kolusu Site Admin

Joined: 26 Nov 2002 Posts: 12378 Topics: 75 Location: San Jose
|
Posted: Thu Apr 09, 2009 5:43 pm Post subject: |
|
|
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 |
|
 |
mangsk Beginner

Joined: 05 Jun 2004 Posts: 46 Topics: 18
|
Posted: Fri Apr 10, 2009 12:20 pm Post subject: |
|
|
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 |
|
 |
kolusu Site Admin

Joined: 26 Nov 2002 Posts: 12378 Topics: 75 Location: San Jose
|
Posted: Fri Apr 10, 2009 6:46 pm Post subject: |
|
|
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 |
|
 |
mangsk Beginner

Joined: 05 Jun 2004 Posts: 46 Topics: 18
|
Posted: Mon Apr 13, 2009 8:51 am Post subject: |
|
|
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 |
|
 |
dbzTHEdinosauer Supermod
Joined: 20 Oct 2006 Posts: 1411 Topics: 26 Location: germany
|
Posted: Mon Apr 13, 2009 9:32 am Post subject: |
|
|
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 |
|
 |
mangsk Beginner

Joined: 05 Jun 2004 Posts: 46 Topics: 18
|
Posted: Mon Apr 13, 2009 11:05 am Post subject: |
|
|
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 |
|
 |
dbzTHEdinosauer Supermod
Joined: 20 Oct 2006 Posts: 1411 Topics: 26 Location: germany
|
Posted: Mon Apr 13, 2009 12:56 pm Post subject: |
|
|
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 |
|
 |
mangsk Beginner

Joined: 05 Jun 2004 Posts: 46 Topics: 18
|
Posted: Tue Apr 14, 2009 8:45 am Post subject: |
|
|
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 |
|
 |
dbzTHEdinosauer Supermod
Joined: 20 Oct 2006 Posts: 1411 Topics: 26 Location: germany
|
Posted: Tue Apr 14, 2009 9:01 am Post subject: |
|
|
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 |
|
 |
jsharon1248 Intermediate
Joined: 08 Aug 2007 Posts: 291 Topics: 2 Location: Chicago
|
Posted: Tue Apr 14, 2009 9:58 am Post subject: |
|
|
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 |
|
 |
dbzTHEdinosauer Supermod
Joined: 20 Oct 2006 Posts: 1411 Topics: 26 Location: germany
|
Posted: Tue Apr 14, 2009 10:07 am Post subject: |
|
|
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 |
|
 |
|
|