PROC CONTENTS in not a "function". It is a procedure.
If you want to use data to generate code there are many ways.
You can use CALL EXECUTE(). Basically generate a string (or series of strings) and use CALL EXECUTE() to have SAS stack them up to run when your current data step ends.
data _null_;
set products;
call execute(cats('proc contents data=',product_name,';run;'));
run;
You can use use normal SAS data statements to write a file that has the code you want to run and then use %INCLUDE statement to include that new file as source code. This is much easier to debug as you can review the file and make sure the code is being generate with the right syntax before running the %include. Plus you have access to all of the power of the PUT statement to generate the code.
filename code temp;
data _null_;
set products;
file code;
put 'proc contents data=' product_name ';run;';
run;
%include code / source2;
There is a newer (and in may ways still experimental) DOSUBL() function that works a lot like CALL EXECUTE() but it actually allows the generated code to run immediately in a sub-process. But usually this is not worth the effort.
If you have a really complicated series of steps you want to execute for every observation in your data then encapsulate them into a macro and in your code generation step simply generate a call to the macro as the code you are generating.
%macro mymacro(product_name);
proc contents data=&product_name;
run;
%mend mymacro;
filename code temp;
data _null_;
set products;
file code;
put '%mymacro(' product_name= ')';
run;
%include code / source2;
Resulting generated code:
%mymacro(product_name=dt1 )
%mymacro(product_name=dt2 )
%mymacro(product_name=dt3 )
%mymacro(product_name=dt4 )
%mymacro(product_name=dt5 )