ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Using the IN operator with the WHERE clause of a SELECT.

Post new topic  Reply to topic
 Using the IN operator with the WHERE clause of a SELECT. « View previous topic :: View next topic » 
Author Message
philip.baker
PostPosted: Mon Oct 18, 2010 10:44 am    Post subject: Using the IN operator with the WHERE clause of a SELECT. Reply with quote

Voyager

Joined: 21 Mar 2002
Posts: 77
Location: Baker Systems Consulting, Inc. - Tampa

Greetings,

I'm back doing MB development.

I believe I'm having an issue understanding some implied activities related to how I would like to do the following processing. (Using MBv6.1.0.8 on WinXP SP3).

Sample input message:
<msg><field1>'1','3','5','A'</field1></msg>

Code fragment.....

DECLARE rField REFERENCE TO InputBody.msg.field1;

DECLARE AnswerB BOOLEAN;
DECLARE cValue CHAR 'A';

SET AnswerB = EXISTS(Select T.* from InputBody.msg[] AS T where cValue IN (rField));

IF AnswerB = TRUE THEN
SET OutputRoot.XMLNSC.msg.fieldvalue = 'Found';
ELSE
SET OutputRoot.XMLNSC.msg.fieldvalue = 'NOT Found';
END IF;

... End code fragment

If I hard-code the values IN ( '1','3','5','A'), AnswerB = TRUE, but it always evals FALSE if I try to use the rField reference.

Anyone know of a way to simpy make this work? (Without parsing the values and building the SELECT statement?)

Thanks,
Phil
_________________
Regards,
Phil
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger
mqjeff
PostPosted: Mon Oct 18, 2010 10:59 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

I'm not sure what you're trying to do with the field reference or the SELECT.

I'm not sure that the IN clause does what you want it to, either. I don't bleieve that XMLNSC will interpret the contents of field1 as a LIST, but will instead treat it as a single character string.

I would at least try
Code:
SET AnswerB = EXISTS(Select T.* from InputBody.msg[] AS T where cValue IN (T.field1));


But I'm not really sure that will do what you want either.
Back to top
View user's profile Send private message
philip.baker
PostPosted: Mon Oct 18, 2010 11:47 am    Post subject: Reply with quote

Voyager

Joined: 21 Mar 2002
Posts: 77
Location: Baker Systems Consulting, Inc. - Tampa

Hi mqjeff,

Thanks for the reply. Obviously the code fragment has been simplified for the purposes of getting an answer on using the dynamically-populated WHERE clause with the IN operator.
There are Loops witin Loops on this one in the real code, but basically the logic needs to validate that an incoming data value within a message exists compared to a queried value for the same data field. The whole solution is data-driven. The 'queried' value (the data in the IN part of the statement) starts out as a field in a database table that has already been selected into Environment.Variables.
The 'queried' value is allowed to be a list of values. (Instead of just having one value (for example - 'A'), the design allows the value to be a list. ('1','2','5','A')). If the incoming message field value does not match the 'queried' value, processing for this record is complete, and the code loops to the next value in the XML input message.

The sample code, as presented, works if I hard-code the list values.
I need to dynamically populate the list. I expected the reference to work and it did not despite the value of the reference looking correct when the debugger displays the rField reference.
I have not tried your exact code and will do so within the fortnight and get back with the results.

Regards,
Phil
_________________
Regards,
Phil
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger
mgk
PostPosted: Mon Oct 18, 2010 12:23 pm    Post subject: Reply with quote

Padawan

Joined: 31 Jul 2003
Posts: 1642

Hello Philip.

You can't do exactly what you are trying to do with the IN operator as the IN operator in 6.1.x requires that all items in the list are "known" in advance at compile time. This is why when you "hard code" the number of items it works. However, a couple of suggestions spring to mind.

Code:
 
   DECLARE X INT 42;

   --Example 1
   DECLARE A INT 39;
   DECLARE B INT 40;
   DECLARE C INT 41;
   DECLARE D INT 43;

   SET OutputRoot.XMLNSC.Top.Out1 = X IN( A , B , C , D);
   SET D = 42;
   SET OutputRoot.XMLNSC.Top.Out2 = X IN( A , B , C , D);

   --Example 2
   SET Environment.Variables.Tests.Test[1] = 39;
   SET Environment.Variables.Tests.Test[2] = 40;
   SET Environment.Variables.Tests.Test[3] = 41;
   SET Environment.Variables.Tests.Test[4] = 43;
   
   SET OutputRoot.XMLNSC.Top.Out3 = X IN( Environment.Variables.Tests.Test[] );
   SET Environment.Variables.Tests.Test[4] = 42;
   SET OutputRoot.XMLNSC.Top.Out4 = X IN( Environment.Variables.Tests.Test[] );



In 6.1.x and earlier, you would have to use the Example 1 technique, which is to have at compile time a list of the maximum number of necessary variables in the IN operator list which you change to the current values each time you execute your IN. If some of the variables are not needed for a particular interation you can set their values to NULL, in which case the IN operator will return NULL if there is no match.

In 7.0.0.1 the IN operator was extended to allow it to work on LISTS and FieldReferences. This allows you to use a section of the tree to store a dynamic list over which it will iterate each time you call it. For the examples above, the following output message is returned:

Code:
<Top><Out1>false</Out1><Out2>true</Out2><Out3>false</Out3><Out4>true</Out4></Top>


I hope this helps,


Kind Regards,
_________________
MGK
The postings I make on this site are my own and don't necessarily represent IBM's positions, strategies or opinions.
Back to top
View user's profile Send private message
philip.baker
PostPosted: Mon Oct 18, 2010 2:35 pm    Post subject: Reply with quote

Voyager

Joined: 21 Mar 2002
Posts: 77
Location: Baker Systems Consulting, Inc. - Tampa

Thanks, mgk.

I had a feeling I'd have to do it the 'old fashioned way', but I had to give it a shot on this forum. You never know.

I've coded a substring parser for the 'list' of values and built the MySQL character string for each processing loop. I hated to do it because most of the time there will only be a single data value. (But, I won't know that in advance until I parse the string value.)

Thanks for your input.

Regards,
p
_________________
Regards,
Phil
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger
mqjeff
PostPosted: Mon Oct 18, 2010 2:37 pm    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

Given what MGK has just said, it sounds like you are okay if you are at 7.0.0.1.

For 6.1.x and earlier, I might suggest flattening your list into a single string and then using CONTAINS. I do not otherwise comment on performance, merely that it may be successful.
Back to top
View user's profile Send private message
philip.baker
PostPosted: Mon Oct 18, 2010 3:02 pm    Post subject: Reply with quote

Voyager

Joined: 21 Mar 2002
Posts: 77
Location: Baker Systems Consulting, Inc. - Tampa

Hi mqjeff,

I'd love to go to v7.x, but I'm stuck using what the customer has. I'm just a lowly developer on this particular project. I couldn't influence this customer one way or the other.

I like the flattening list suggestion and have used something similiar in the past where I concatenated multiple fields into one before testing, but that won't work so good in this situation. For the sample data I put forward earlier, ( '1','3','5','A'), I'd get 135A. Additionally, I'd still have to parse to get the 135A. I don't want a match on '135', '13', or '35' , etc.

I've got the code working now; I just don't like it.
_________________
Regards,
Phil
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger
mqjeff
PostPosted: Tue Oct 19, 2010 3:37 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

you'll only get "135A" if you flatten the list that way. You could, for example, get "1,3,5,a" instead. And that would never allow a match on "13", only on "1,3".

But that's more effort. Dunno if that effort is better or worse than your current code.
Back to top
View user's profile Send private message
philip.baker
PostPosted: Tue Oct 19, 2010 1:57 pm    Post subject: Reply with quote

Voyager

Joined: 21 Mar 2002
Posts: 77
Location: Baker Systems Consulting, Inc. - Tampa

Hi mqjeff,

I'm finally getting back to try out the method in your last reply, and I like it. I've transmuted your suggestion a bit and I think it might perform better than my 'substring' approach. I've included the generic code and test cases below proving it out. Thanks. (BTW, you'll notice in the tests that I choose to have the input message as a constant for the tests and changed the code. A bit unconventional, but it proves the case none the less.)

Test 1 Input message:

<msg><field1>1|3|5|A|</field1></msg>

Test 1 source code deployed:

CREATE COMPUTE MODULE SelectSubField_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL CopyMessageHeaders();
DECLARE sInput REFERENCE TO InputBody.msg.field1;
DECLARE AnswerB BOOLEAN;
DECLARE cValue CHAR 'A|';

SET AnswerB = CONTAINS(sInput,cValue);
IF AnswerB = TRUE THEN
SET OutputRoot.XMLNSC.msg.fieldvalue = 'Found';
ELSE
SET OutputRoot.XMLNSC.msg.fieldvalue = 'NOT Found';
END IF;
RETURN TRUE;
END;

Test 1 Output message:

<msg><fieldvalue>Found</fieldvalue></msg>


Test 2 Input message:
<msg><field1>1|3|5|A|</field1></msg>

Test 2 source code deployed:

CREATE COMPUTE MODULE SelectSubField_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL CopyMessageHeaders();
DECLARE sInput REFERENCE TO InputBody.msg.field1;
DECLARE AnswerB BOOLEAN;
DECLARE cValue CHAR 'B|';

SET AnswerB = CONTAINS(sInput,cValue);
IF AnswerB = TRUE THEN
SET OutputRoot.XMLNSC.msg.fieldvalue = 'Found';
ELSE
SET OutputRoot.XMLNSC.msg.fieldvalue = 'NOT Found';
END IF;
RETURN TRUE;
END;

Test 2 Output message:

<msg><fieldvalue>NOT Found</fieldvalue></msg>
_________________
Regards,
Phil
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Using the IN operator with the WHERE clause of a SELECT.
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
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.