There are numerous ways of handling that a subquery returns more than one row. The issue to address is if the subquery returning multiple values is correct, or if it should only ever return one row. The equals operator against a subquery expects that only one row/record will be returned.
Also, MONTHS_BETWEEN returns the months between the two dates. If you want to see the number of days, use b.activity - SYSDATE > 30
, or vice versa if appropriate.
Assuming more than one row is valid -
IN clause
There's no need for the 2nd join in the subquery to the VERSION table:
UPDATE VERSION
SET isActive = 0
WHERE customerNo IN (SELECT c.customerno
FROM Activity b
WHERE b.VersionNo = VERSION.VersionNo
AND MONTHS_BETWEEN(SYSDATE, b.activity) > 30);
The VERSION table alias refers to the table being updated.
EXISTS clause
UPDATE VERSION
SET isActive = 0
WHERE EXISTS(SELECT NULL
FROM ACTIVITY a
WHERE VERSION.customerno = a.customerno
AND VERSION.versionno = a.versionno
AND MONTHS_BETWEEN(SYSDATE, b.activity) > 30);
There can be only one?
If only one row should be returned, the appropriate aggregate function (MIN, MAX) might be considered.