Even though this is a one-time query, this is a really bad idea. Oracle has the 1,000 "in list" limitation for really good reasons. Even a single in-list with 1,000 items takes a while just to compile. If you contrast this with a simple join, the compilation time is next to nothing, and the execution time is no more than it would be with your in list.
This is also a much more courteous approach to others on the database, as you are not hogging the shared pool with thousands of literals.
Even if this is a one-time thing, I'd recommend you create a table (or a GTT), load your values and do this as a simple join:
create table temporary_values (
in_list_string varchar2(1000) not null,
constraint temporary_values_pk primary key (in_list_string)
);
Use a tool like SQL*Loader to load your values, or do it the old-fashioned way. Then run your query as this:
select A.colA, A.colB
from
tableA A
join temporary_values t on
A.colA = t.in_list_string
where
A.colB in ('catA', 'catB');
If the primary key is a pain, you can always drop it and do your query as a semi-join to avoid duplicates:
select A.colA, A.colB
from
tableA A
where
A.colB in ('catA', 'catB') and
exists (
select null
from temporary_values t
where A.colA = t.in_list_string
);
And if your and ever becomes an or you can resolve that by using a left join:
select A.colA, A.colB
from
tableA A
left join temporary_values t on
A.colA = t.in_list_string
where
t.in_list_string is not null or
A.colB in ('catA', 'catB');
If there are any compilation or execution errors, they will be a lot easier to find than searching for a missing comma or misplaced quote in thousands of literals.