Assigning book ids to certain students on registration of a new student
Instead of extracting all books and execute a separate sub-query on each FOR loop iteration - we can select only the books that don't have matches in studentbooks table for specified student (presented by id argument) by running PostgreSQL LEFT JOIN with specific WHERE clause.

Furthermore, to make it one-shot action - we can insert data from query using INSERT INTO SELECT statement.

The query for the whole task:

INSERT INTO
   studentbooks(bookid, studentid) 
   SELECT
      b.bookid, your_function_name.id 
   FROM
      books b 
      LEFT JOIN
         studentbooks sb 
         ON sb.bookid = b.bookid AND studentid = id 
   WHERE
      b.isdelete = false AND b.published = true
      AND sb.bookid is NULL;


replace your_function_name with your actual function name to refer the function's argument name.