text: --recreate functions - make sure owner name is specified!
  
  declare @name sysname,
  		@id int,
  		@id_last int,
  		@last sysname,
  		@owner sysname,
  		@test_text nvarchar(4000),
  		@pos_create_fn int,
  		@pos_comment_start int,
  		@pos_comment_end int,
  		@offset int,
  		@pos_function_name int,
  		@pos_object_name int,
  		@c cursor,
  		@sql_segment nvarchar(4000),
  		@text_ptr binary(16)
  
  set 	@id_last =0
  
  set			@C = cursor for
  select 		o.name as functionName, 
  			o.id,
  			sc.text,
  			u.name
  from		sysobjects o
  join		syscomments sc
  on			o.id = sc.id
  join		sysusers u
  on			u.uid = o.uid
  where 		objectproperty(o.id,'IsTableFunction') =1
  and			objectproperty(o.id,'IsMSShipped')=0 
  order by	o.id, 
  			sc.colid  
  
  open @C
  fetch next from @C into @name, @id, @sql_segment, @owner
  while @@Fetch_Status=0
  begin
  	if @id<>@id_last
  	begin
  
  		--add a row for our data
  		insert into #sql (sql) values ('')
  		
  		--get a text pointer
  		SELECT @text_ptr = TEXTPTR(sql) FROM #sql where id = (select max(id) from #sql)
  
  		set @id_last =@id
  
  		-- now look at the create function part of the sql, make sure that the owner
  		-- name is specified
  
  		set @pos_create_fn = patindex('%create%function%', @sql_segment)
  		set @pos_comment_start = patindex('%/*%', @sql_segment)
  		set @offset = 1
  		set @test_text = @sql_segment
  		-- it is possible that there are create function statments in comments at the
  		-- start of the sql so look for the one that actually creates the function
  
  		while @pos_comment_start <@pos_create_fn and @pos_comment_start<>0
  		begin
  			set @pos_comment_end = patindex('%*/%', @test_text)
  			set @offset = @offset+@pos_comment_end+1
  			set @test_text = substring(@sql_segment, @offset, len(@sql_segment) - @offset)
  			set @pos_create_fn = patindex('%create%function%', @test_text collate latin1_general_ci_ai)
  			set @pos_comment_start = patindex('%/*%', @test_text)
  		end
  
  		-- now look to see if the owner name is specified, there should be a
  		-- . before the function name so inspect the text between the word function and the actual
  		-- function name
  
  		set @pos_function_name = charindex('function' collate latin1_general_ci_ai, @sql_segment collate latin1_general_ci_ai, @pos_create_fn-1+@offset)
  		if @pos_function_name>0
  			set @pos_function_name=@pos_function_name+8  --number of characters in the word function
  		
  		set @pos_object_name = charindex(@name collate latin1_general_ci_ai, @sql_segment collate latin1_general_ci_ai, @pos_function_name)
  		
  		set @test_text= substring(@sql_segment,@pos_function_name,@pos_object_name-@pos_function_name)
  		
  		if charindex('.',@test_text,1)=0
  		begin
  			-- the owner name is missing, add it
  			declare @Tempsql nvarchar(4000)
  			set @Tempsql = left(@sql_segment, @pos_function_name) + '['+@owner+'].'
  			UPDATETEXT #sql.sql @text_ptr NULL 0 @Tempsql
  			
  			set @sql_segment = substring(@sql_segment, @pos_object_name,len(@sql_segment) -@pos_object_name +1)
  			
  		end
  
  	end
  	
  	UPDATETEXT #sql.sql @text_ptr NULL 0 @sql_segment
  
  	fetch next from @C into @name, @id, @sql_segment, @owner
  end
  Close @C
  deallocate @C
  
  
  -- now the permissions on the functions that have been recreated
  insert into #sql (sql)
  select 	case p.protecttype 
  		when 206 then 'DENY ' 
  		else 'GRANT ' end + 
  	case p.action 
  		when 193 then 'SELECT'
  		when 26 then 'REFERENCES'
  		end+
  	' on ['+user_name(o.uid)+'].['+o.name+'] to ['+user_name(p.uid)+']' +
  	case when p.protecttype = 204 then ' WITH GRANT OPTION' else '' end
  from 	sysprotects p 
  join 	sysobjects o
  on	p.id = o.id
  where	objectproperty(o.id,'IsTableFunction') =1
  and		objectproperty(o.id,'IsMSShipped')=0 