• something like this would get you started on a set based solution:

    with sp_lines(ObjectId, SPName, CRPos, [LineNo])

    as (

    select

    o.id

    ,o.name

    ,t.n as CRPos

    ,ROW_NUMBER() over (partition by o.name order by t.n) as [LineNo]

    from sys.syscomments c

    inner join sys.sysobjects o on c.id = o.id

    left join Tally t on substring(c.text, t.n, 1) = char(10)

    where c.text like '%varchar%'

    and o.xtype = 'P'

    )

    select

    current_line.SPName

    ,substring(c.text, isnull(previous_line.CRPos+1, 1), current_line.CRPos - isnull(previous_line.CRPos+1, 1)) as LineText

    --,isnull(previous_line.CRPos+1, 1) as LineStart

    --,current_line.CRPos - isnull(previous_line.CRPos+1, 1) as Length

    from sp_lines current_line

    left join sp_lines previous_line on current_line.ObjectId = previous_line.ObjectId

    and current_line.[LineNo] - 1 = previous_line.[LineNo]

    inner join sys.syscomments c on current_line.ObjectId = c.id

    where substring(c.text, isnull(previous_line.CRPos+1, 1), current_line.CRPos - isnull(previous_line.CRPos+1, 1)) like '%varchar%'