So here is the problem.
I have a dataset and for each record, depending on a criteria, I want to load a different hash. I do not know the exact hash structure for each hash I will be loading during runtime. So I want to be able to execute the definedata
statement conditionally. But since I do not know the hash structure, I thought of passing the parameter to the definedata
statement via a variable, but it does not work. How can I accomplish this? Here is what I have so far:
/* Hashes have the same key field */
data hash1;
key = '1'; a = 10; b = 20; output;
key = '2'; a = 30; b = 40; output;
run;
/* Hash objects can have different data members and types */
data hash2;
key = '1'; x = 'AAA'; y = 'BBB'; output;
key = '2'; x = 'CCC'; y = 'DDD'; output;
run;
/* This the dataset I want to process */
/* hid specifies which hash I should lookup */
/* key contains the key value to use for the lookup */
/* def is the hash data definition piece of the hash.
In practice I will use another hash to retrieve this definition
But for simplicity we can assume that is part of the have dataset itself */
data have;
hid = '1'; key = '2'; def = "'a', 'b'"; output;
hid = '2'; key = '1'; def = "'x', 'y'"; output;
run;
/* This is what I want */
data want;
set have;
/* Though I don't know the structure of each hash, I can get a list of all hashes at the onset via some macro processing. So this statement is doable */
if _N_ = 0 then set hash1 hash2;
/* This part is OK. The hash declaration is able to accept a variable for the dataset name */
hashname = "hash" || hid;
declare hash hh(dataset: dsname);
hh.definekey('key');
/* The following line is the problematic piece */
hh.definedata(def);
hh.definedone();
rc = hh.find();
/* Do something with the values */
/* Finally delete the object so that it can be redefined again on the next record */
hh.delete();
run;
The error I get is: ERROR: Undeclared data symbol 'a', 'b' for hash object. I think the issue here is that the definedata method parses the variables one by one and ends up treating the entire string 'a', 'b'
as one variable.
If I were to define the hash to be a superset of all possible variables, then it complains when I load a dataset that contains a subset of those variables. Also I cannot have the hashes defined to contain a superset of all variables (i.e. I cannot create all hashes to contain a, b, x and y and leave the extraneous elements missing).
So my question is how can I accomplish what I am trying to do here? Is it possible to do macro %do like iterations just using datastep constructs to provide each variable one by one? Or are there other ways to do it?
Constraints
- I cannot rely on macro processing since I only know which hash I am going to use during runtime.
- I cannot load all the definitions ahead of time for memory reasons.
Any help will be appreciated.
Your program can be made to work but I think performance will be poor.
Notice I changed the value of DEF so it would be easier to SCAN.