You can use a cursor, for doing this. That way you dont have to worry about TOO_MANY_ROWS or NO_DATA_FOUND exception.
And also you will have the flexibility of each time you add a column to your query it automatically gets added to your variable of the same type
You have two options with the cursor: using just the first row returned or use all the rows.
Option #1
DECLARE
CURSOR C_DATA IS
SELECT
table.col1, -- Column 2 intentionally left out
table.col3,
table.col4,
table2.column --Column from joined table
FROM table
JOIN table2
On table.col6 = table2.col1;
myRow C_DATA%rowtype
BEGIN
OPEN C_DATA;
FETCH c_data INTO myRow;
CLOSE C_DATA;
-- USE ANYWHERE INSIDE THIS ESCOPE YOUR COLUMNS as myRow.col4.
END;
Option #2
DECLARE
CURSOR C_DATA IS
SELECT
table.col1, -- Column 2 intentionally left out
table.col3,
table.col4,
table2.column --Column from joined table
FROM table
JOIN table2
On table.col6 = table2.col1;
BEGIN
FOR myRow IN C_DATA LOOP
-- USE INSIDE HERE YOUR COLUMNS as myRow.col4.
END LOOP;
END;