Postgresql script doesn't work as I expect
Where did you find such syntax in the documentation?
You need declare variables in the same block.
DO $$
DECLARE companyNrs text[] = ARRAY[1,2,3];
        companyNr text;
        v_sql text;
BEGIN
  FOREACH companyNr IN ARRAY companyNrs
  LOOP
    v_sql := format('foo bar %L', companyNr);
    raise notice 'notice message %', v_sql;
  END LOOP;
END; $$;

Or it is possible to declare another sub-block:
DO $$
DECLARE companyNrs text[] = ARRAY[1,2,3];
        companyNr text;
BEGIN
  FOREACH companyNr IN ARRAY companyNrs
  LOOP
    --
    -- Create a subblock
    --
    DECLARE
        v_sql text;
    BEGIN
        v_sql := format('foo bar %L', companyNr);
        raise notice 'notice message %', v_sql;
    END;
  END LOOP;
END; $$;

Subblocks with EXCEPTION clause are implicit savepoints and have a performance impact. Not sure about subblocks without EXCEPTION clause. They may not be cheap syntactic sugar either.