Another approach would be to use functions instead of a procedure in the trigger. For example:
create table Books (
-- The function processes a new BookCode during insertion
create function fnBookProcess (
-- Do something useful with each BookCode.
-- Just return a message
return('Function is processing... ' + @BookCode)
-- trigger runs a select calling the fnBookProcess for each inserted row on the Books table
create trigger tr1 on Books after insert as
print 'Trigger is calling fnBookProcess'
select dbo.fnBookProcess(BookCode) from Inserted
-- insert books for testing
select 'A','Book desc 1' union all
select 'B','Book desc 2' union all
select 'C','Book desc 3'
Here the fnBookProcess function is called for each line of the Inserted virtual table and it avoids the 8000 varchar limit. The only draw back is that now the insert statement returns a recordset from the trigger's select statement. I don't know how to avoid that.