Who needs Internet Explorer when you can use it in Firefox?

I love Firefox and its addons, although I still habitually use Internet Explorer.  IE6 at work (which always provides some nice CSS challenges!) and IE7 at home.


I’m a bit slow off the mark with using firefox, but the latest addon that someone sent me yesterday may have tipped the balance.


The IE Tab addon actually uses the IE rendering engine to render in a new tab in Firefox.  It’s quite amusing when you right-click and get the IE context menu.


The really great thing about this is that you can then use the power of the other Firefox addons to develop for IE.  Here’s my list of ‘must haves’.



  • Firebug.  This is quite simply the best addon.  Hit F12 and you can instantly see (and manipulate) all sorts of things in the comfort of your own browser.
  • YSlow.  Great Javascript profiler
  • FireCookie. See and change your cookies (for development purposes of course! – Good to test the security of your apps)
  • Web Developer.  Bit of overlap with Firebug but some cool features.

The IE Developer Toolbar is still a pretty good tool, but Firebug just gives you more info when you’re debugging CSS (which is inevitable with IE).


 

Search SQL Server Stored Procedures for any text string


Here’s the SQL script I probably use most when I’m trying to work out dependencies and scope of development changes.  Query Analyzer allows you to search objects (hit F4 – it’s cool!) and find objects by ‘name’, but there’s no obvious way to search stored procs for a particular string.


SQL Server hides Stored Procedure code in the sysComments table (in each database), and so it’s possible to search.  This is another script I found from not sure where (so can’t really take credit).  It does a great job of scanning and even gives you line numbers.  It would be great to be able to just shove this into the master database, but you need to be in the context of the database you’re searching in (or it would have to be amended somewhat to run some more ‘dynamic’ SQL). 


I have previously front-ended this for development databases with an ASP.NET page that simply runs the query substituting a parameter for the search text and connecting to the correct database.  The results show nicely in a grid.


Here’s the code – just paste into a new query in your chosen database, change @SearchTerm and away you go…


 


SET NOCOUNT ON
GO

declare 
@dbname sysname
,@SearchTerm    varchar(100)
,@BlankSpaceAdded   
int
,@BasePos       int
,@CurrentPos    int
,@TextLength    int
,@LineId        int
,@AddOnLen      int
,@LFCR          int –lengths of line feed carriage return
,@DefinedLength int
,@obj_name    varchar(255)
,@prev_obj_name 
varchar(255)


/* NOTE: Length of @SyscomText is 4000 to replace the length of
** text column in syscomments.
** lengths on @Line, #CommentText Text column and
** value for @DefinedLength are all 255. These need to all have
** the same values. 255 was selected in order for the max length
** display using down level clients
*/
,@SyscomText    nvarchar(4000)
,@Line          
nvarchar(255)

set @SearchTerm ‘MyTable’
set @dbname db_name()


set @SearchTerm ‘%’ + @SearchTerm + ‘%’

Select @DefinedLength 255
SELECT @BlankSpaceAdded /*Keeps track of blank spaces at end of lines. Note Len function ignores
                             trailing blank spaces*/
CREATE TABLE #CommentText
(obj_name 
varchar(255)
 ,LineId    
int
 
,Text  nvarchar(255collate database_default)

/*
**  Make sure the @objname is local to the current database.
*/
if @dbname is not null and @dbname <> db_name()
        
begin
                raiserror
(15250,-1,-1)
        
end

    begin

        DECLARE 
ms_crs_syscom  CURSOR LOCAL
        FOR SELECT 
so.name, sc.text FROM syscomments sc
    
inner join sysobjects so
    
on so.id = sc.id
    where 
so.type ‘P’
    
AND sc.encrypted 0
                
ORDER BY number, colid

        
FOR READ ONLY
    
end

/*
**  Get the text.
*/
SELECT @LFCR 2
SELECT @LineId 1


OPEN ms_crs_syscom

FETCH NEXT FROM ms_crs_syscom into @obj_name, @SyscomText

WHILE @@fetch_status >0
BEGIN

    SELECT  
@BasePos    1
    
SELECT  @CurrentPos 1
    
SELECT  @TextLength = LEN(@SyscomText)

    
IF @prev_obj_name <> @obj_name
        
–start again
        
SELECT @LineId 1
    
    
WHILE @CurrentPos  !0
    
BEGIN
        
–Looking for end of line followed by carriage return
        
SELECT @CurrentPos =   CHARINDEX(char(13)+char(10), @SyscomText, @BasePos)

        
–If carriage return found
        
IF @CurrentPos !0
        
BEGIN
            
/*If new value for @Lines length will be > then the
            **set length then insert current contents of @line
            **and proceed.
            */
            
While (isnull(LEN(@Line),0) + @BlankSpaceAdded + @CurrentPos-@BasePos + @LFCR) > @DefinedLength
            
BEGIN
                SELECT 
@AddOnLen @DefinedLength-(isnull(LEN(@Line),0) + @BlankSpaceAdded)
                
INSERT #CommentText VALUES
                
( @obj_name,
          @LineId,
                  
isnull(@Line, N”) + isnull(SUBSTRING(@SyscomText, @BasePos, @AddOnLen), N”))
                
SELECT @Line = NULL, @LineId @LineId + 1,
                       @BasePos 
@BasePos + @AddOnLen, @BlankSpaceAdded 0
            
END
            SELECT 
@Line    = isnull(@Line, N”) + isnull(SUBSTRING(@SyscomText, @BasePos, @CurrentPos-@BasePos + @LFCR), N”)
            
SELECT @BasePos @CurrentPos+2
            
INSERT #CommentText VALUES( @obj_name, @LineId, @Line )
            
SELECT @LineId @LineId + 1
            
SELECT @Line = NULL
        END
        ELSE
        
–else carriage return not found
        
BEGIN
            IF 
@BasePos <@TextLength
            
BEGIN
                
/*If new value for @Lines length will be > then the
                **defined length
                */
                
While (isnull(LEN(@Line),0) + @BlankSpaceAdded + @TextLength-@BasePos+1 ) > @DefinedLength
                
BEGIN
                    SELECT 
@AddOnLen @DefinedLength – (isnull(LEN(@Line),0) + @BlankSpaceAdded)
                    
INSERT #CommentText VALUES
                    
( @obj_name,
              @LineId,
                      
isnull(@Line, N”) + isnull(SUBSTRING(@SyscomText, @BasePos, @AddOnLen), N”))
                    
SELECT @Line = NULL, @LineId @LineId + 1,
                        @BasePos 
@BasePos + @AddOnLen, @BlankSpaceAdded 0
                
END
                SELECT 
@Line = isnull(@Line, N”) + isnull(SUBSTRING(@SyscomText, @BasePos, @TextLength-@BasePos+1 ), N”)
                
if LEN(@Line) < @DefinedLength and charindex(‘ ‘, @SyscomText, @TextLength+1 ) > 0
                
BEGIN
                    SELECT 
@Line @Line + ‘ ‘, @BlankSpaceAdded 1
                
END
            END
        END
    END
    
–Save previous name
    
SET @prev_obj_name @obj_name
    
FETCH NEXT FROM ms_crs_syscom into @obj_name, @SyscomText
END

IF 
@Line is NOT NULL
    INSERT #
CommentText VALUES( @obj_name, @LineId, @Line )

select from #CommentText 
where  patindex(@SearchTerm, text) <> 0

CLOSE  ms_crs_syscom
DEALLOCATE     ms_crs_syscom

DROP TABLE     #CommentText




Colorized by: CarlosAg.CodeColorizer

Generate SQL Inserts from existing data

This is one from the archives that obviously got away.  I had need for this today so thought I’d post so I don’t have to look so hard next time!


It’s pretty much a case of create the SP in your chosen database and run with a tablename as the parameter.  I originally found this on one of the SQL sites (probably SQLServerCentral), and amended it slightly to add some basic filtering in the @where parameter.


There’s a few limitations from memory – with blob, image and text fields, but for your average tables this will probably do the trick just fine.


I’ve also used a different method that basically builds up a single INSERT with SELECT ‘literal values’ UNION SELECT ‘literal values’.  That works fine and is potentially easier to control transaction-wise as everthing’s in a single statement.  Anyway here’s the code….

if exists (select from dbo.sysobjects where id = object_id(N'[dbo].[usp_InsertGenerator]’and OBJECTPROPERTY(idN’IsProcedure’1)
drop procedure [dbo].[usp_InsertGenerator]
GO

CREATE PROC dbo.usp_InsertGenerator
(@tableName 
varchar(100), @where varchar(1000= NULLas
 
–Declare a cursor to retrieve column specific information for the specified table
DECLARE cursCol CURSOR FAST_FORWARD FOR 
SELECT 
column_name,data_type FROM information_schema.columns WHERE table_name @tableName
OPEN cursCol
DECLARE @string nvarchar(3000–for storing the first half of INSERT statement
DECLARE @stringData nvarchar(3000–for storing the data (VALUES) related statement
DECLARE @dataType nvarchar(1000–data types returned for respective columns
SET @string=‘INSERT ‘+@tableName+‘(‘
SET @stringData=
 
DECLARE @colName nvarchar(50)
 
FETCH NEXT FROM cursCol INTO @colName,@dataType
 
IF @@fetch_status<>0
 
begin
 print 
‘Table ‘+@tableName+‘ not found, processing skipped.’
 
close curscol
 
deallocate curscol
 
return
END
 
WHILE 
@@FETCH_STATUS=0
BEGIN
IF 
@dataType in (‘varchar’,‘char’,‘nchar’,‘nvarchar’)
BEGIN
 SET 
@stringData=@stringData+””+”’+isnull(””’+””’+’+@colName+‘+””’+””’,”NULL”)+”,”+’
END
ELSE
if 
@dataType in (‘text’,‘ntext’–if the datatype is text or something else 
BEGIN
 SET 
@stringData=@stringData+””””’+isnull(cast(‘+@colName+‘ as varchar(2000)),””)+”””,”+’
END
ELSE
IF 
@dataType ‘money’ –because money doesn’t get converted from varchar implicitly
BEGIN
 SET 
@stringData=@stringData+”’convert(money,”””+isnull(cast(‘+@colName+‘ as varchar(200)),”0.0000”)+”””),”+’
END
ELSE 
IF 
@dataType=‘datetime’
BEGIN
 SET 
@stringData=@stringData+”’convert(datetime,’+”’+isnull(””’+””’+convert(varchar(200),’+@colName+‘,121)+””’+””’,”NULL”)+”,121),”+’
END
ELSE 
IF 
@dataType=‘image’ 
BEGIN
 SET 
@stringData=@stringData+””””’+isnull(cast(convert(varbinary,’+@colName+‘) as varchar(6)),”0”)+”””,”+’
END
ELSE 
–presuming the data type is int,bit,numeric,decimal 
BEGIN
 SET 
@stringData=@stringData+””+”’+isnull(””’+””’+convert(varchar(200),’+@colName+‘)+””’+””’,”NULL”)+”,”+’
END
 
SET 
@string=@string+@colName+‘,’
 
FETCH NEXT FROM cursCol INTO @colName,@dataType
END
DECLARE 
@Query nvarchar(4000)
 
SET @query =‘SELECT ”’+substring(@string,0,len(@string)) + ‘) VALUES(”+ ‘ substring(@stringData,0,len(@stringData)-2)+”’+”)” FROM ‘+@tableName
IF @where IS NOT NULL
 SET 
@query @query + ‘ where ‘ + @where
 
exec sp_executesql @query
 
CLOSE cursCol
DEALLOCATE cursCol
GO


Colorized by: CarlosAg.CodeColorizer

Upgrading TortoiseSVN, Subversion 1.5 and AnkhSVN.

I thought I’d upgrade to v1.5 of TortoiseSVN this morning (leaving the server on V1.4.x) – of course completely forgetting that I use AnkhSVN in Visual Studio. 


New versions of TortoiseSVN and Subversion tend to upgrade the format for Working Copies.  This means AnkhSVN (1.02) was no longer compatible with my ‘new’ Working Copy and I got the following error…


This client is too old to work with Working copy ‘xxx’. Please get a newer Subversion client.


Thankfully AnkhSVN 2.0 is on the way and I downloaded a nightly build (2.0.4523.91) and installed (without uninstalling 1.0.2).  I usually do this to ‘test’ whether people write good installers.  Most people do the right thing with AutoUpgrade and 1.0.2 dutifully disappeared.


I loaded up Visual Studio with the same solution and – ‘Where’s my AnkhSVN menus gone?’.  As V2.0 is not even Alpha yet there’s not much in the way of obvious help on the Collabnet site.  The community area may have more, but I luckily didn’t need it.


I noticed in the application folder that there’s now an Ankh.Scc.dll.  Well blow me if they haven’t gone and made it a ‘standard’ Visual Studio SCC Provider!  Tools –> Options –> Source Control –> Plug-in Selection.  There it is.


Once you’ve got over that, then you might find a few little errors here and there, but the main difference is that instead of an ANKH menu on Tools and in the Solution Explorer context menu – you get a Subversion context menu. 


I’m liking it so far.  I think it’s probably stable enough to put your faith in and make the jump to SVN 1.5.


Update (08/07/2008) 
I submitted a bug report yesterday on an error I encountered (from the nice ‘send error details’ link) and got a reply saying ‘fixed in latest build’ the next day.  This bodes well!!!  Reasons to pay money for VisualSVN now disappearing fast…


Update (23/07/2008)


AnkhSVN v2.0 now officially out (that was a quick alpha/beta phase!)

Invalid Postback or Callback Argument – ASP.NET. One cause

Just been getting this error.  It’s quite common, especially if you’re using Ajax.  I got the error for an altogether more ‘schoolboy error’ reason.


I had a textbox control e.g. called ‘customerName’, and two radio buttons controlling whether to show the customer name.  These had a ‘GroupName’ of customerName, and this caused the error.  You need the GroupName to associate the radio buttons together, but the postback mechanism obviously sees that as the control identifier.  Silly boy. 


The naming was pretty bad in any case and actually prompted me to take more of a long hard look at the UI to tidy it up so no such conflict would arise.

ASP.NET – The name xxx does not exist in the current context

I recently converted a Web Site to a Web Application project, and as it had been a while I tripped up on a few things. 

First of all I made the mistake of creating a new Web Application and pasting all the web files in there (I was intending to split some of the site into another Class Library), and I wanted to port to another file structure.  I mistakenly thought it would be easier to do this ‘before’ changing to the WAP.

I then of course got a gazillion compiler errors (well – 1436 to be exact) on the new project.  The vast majority of which were ‘The name xxx does not exist in the current context’.  Yes it does! (I protested).  Well.  That showed mistake number 2.

If you want to convert then use the ‘Convert to Web Application’ option on the Web Site properties (or on the individual pages if necessary).  This does a number of things:

  1. Sorts out your project structure
  2. Changes ‘CodeFile’ to ‘CodeBehind’ and other directives
  3. Adds a designer file for pages and controls
  4. Other stuff that you shouldn’t bother yourself with etc…

The compiler errors were due to the fact that the WAP model expects pages to be structured in a certain way, and although the ‘code’ looks fine (and Resharper was green all the way) it won’t compile ‘cos the designer files are missing and hence so are the definitions the compiler’s looking for.

See Steven Smith’s post on some other tips for converting projects.