0

I have a number of UDF (user defined functions) in SQL2005 that are called from various stored procedures.

I did not realise quite how much these slow down retrieval of records, so I'd like to figure out a faster way to create strings. I've looked at CTEs / inline scalar functions but I can't see how I can put any logic in them based on the data I have.

I need to check for NULLs and change a string based on what data I have.

This one below builds the URL for each real estate listing in a nice standardised way that I can use in many procedures, so all pages are referenced exactly the same across the site.

I know I should do this on the web server, but before I go down that route I'd like to know how I could improve things in SQL.

URL STRING

CREATE FUNCTION NW_PROPERTY_URL
   (@ID int,
   @PType varchar(20),
   @Country varchar(30),
   @Region varchar(30),
   @County varchar(30),       
   @Location varchar(50),
   )

RETURNS nvarchar(500)

AS
BEGIN

DECLARE @URL nvarchar(500)

SET @URL = 'http://www.example.com/' + CONVERT(varchar,@ID) + '/'

IF @PType is not NULL

  BEGIN
    SET @URL = @URL + RTRIM(LTRIM(@PType)) + '-'
  END

IF @Country is not NULL

  BEGIN
    SET @URL = @URL + RTRIM(LTRIM(@Country)) + '-'
  END

IF @Region is not NULL

  BEGIN
    SET @URL = @URL + RTRIM(LTRIM(@Region)) + '-'
  END

IF @County is not NULL

  BEGIN
    SET @URL = @URL + RTRIM(LTRIM(@County)) + '-'
  END

IF @Location is not NULL

  BEGIN
    SET @URL = @URL + RTRIM(LTRIM(@Location)) + '-'
  END

/* check if last character is a space, and remove */


IF (RIGHT(@URL, 1) = '-')
   BEGIN
   SET @URL = LEFT(@URL, LEN(@URL) - 1)
   END

/* add trailing slash */

Set @URL = @URL + '/'


/* replace all spaces with hyphens */

Set @URL = Replace(@URL,' ','-')
Set @URL = Replace(@URL,'--','-')
Set @URL = Replace(@URL,'''','-')
Set @URL = Replace(@URL,',','')



RETURN @URL
END

EXAMPLE

The output would be something like:

www.example.com/34234/House-USA-Florida-Miami-Miami-Beach/

REAL ESTATE TITLE

I also have one that reads language translations from the database based on the input language chosen on the website to create a header title for each real estate listing, which is much more involved.

Is there anything I can do to either speed the function up, or move it within the procedure?

CREATE FUNCTION REALESTATE_TITLE
       (
       @ForceTitle varchar(200),
       @ForSaleOrRent varchar(10),
       @Bedrooms int,
       @PType varchar(30),
       @Location varchar(30),
       @Urbanisation varchar(150),
       @LandSQM int,
       @County varchar(30),
       @Country varchar(30),
       @Lang varchar(2)
       )

RETURNS nvarchar(300)

AS
BEGIN

/* START VARIABLES */
DECLARE @PropertyTitle nvarchar(300)
DECLARE @LandSQM2 nvarchar(30)

DECLARE @lang_BEDROOMS nvarchar(30)
DECLARE @lang_PType nvarchar(30)
DECLARE @lang_FORSALEORRENT nvarchar(30)
DECLARE @lang_LAND nvarchar(30)
DECLARE @lang_WITH nvarchar(30)

/* CHECK FOR TITLE */

IF @ForceTitle is not NULL
   BEGIN
      SET @PropertyTitle = @ForceTitle
   END
ELSE

   BEGIN
   /* GET TRANSLATION OF 'WITH' AND 'LAND' */
   SET @lang_WITH = N' ' + (SELECT LOWER(With2) FROM Langs WHERE Lang=@Lang)
   SET @lang_LAND = N' ' + (SELECT LOWER(Land) FROM Langs WHERE Lang=@Lang)


   /* FOR SALE OR RENT */

   IF @ForSaleOrRent = 'For Sale'
     SET @lang_FORSALEORRENT = N' ' + (SELECT LOWER(ForSale) FROM Langs WHERE Lang=@Lang)
   ELSE IF @ForSaleOrRent = 'Rental'
     SET @lang_FORSALEORRENT = N' ' + (SELECT LOWER(ForRent) FROM Langs WHERE Lang=@Lang)
   ELSE
     SET @lang_FORSALEORRENT = N''

   /* CHECK IF LOCATION IS SAME AS COUNTY */

   IF @Location = @County     
        SET @County = N''


   /* URBANISATION AND LOCATION */
   IF @Urbanisation is not NULL
     BEGIN
       SET @Urbanisation = N' in ' + @Urbanisation
       SET @Location = N', ' + @Location
       IF NOT @County = ''
          SET @County = N', ' + @County
     END
   ELSE
     BEGIN
       SET @Urbanisation = N''
       SET @Location = N' in ' + @Location
       IF NOT @County = ''
          SET @County = N', ' + @County       
     END


   IF @PType = N'Plot of land'      

     BEGIN

       IF @LandSQM is not null
          BEGIN
            SET @LandSQM2 = REPLACE(CONVERT(nvarchar, CAST(@LandSQM AS money), 1),'.00','') + N'm2 '
            SET @lang_PType = LOWER((SELECT TOP 1 Translation FROM Langs_PTypes WHERE PType = @PType AND Lang = @Lang))
          END
       ELSE
          BEGIN
           SET @LandSQM2 = N''
           SET @lang_PType = (SELECT TOP 1 Translation FROM Langs_PTypes WHERE PType = @PType AND Lang = @Lang)
          END

       SET @PropertyTitle = @LandSQM2 + @lang_PType + @lang_FORSALEORRENT + @Urbanisation + @Location + @County
     END

   ELSE

     BEGIN

       IF @LandSQM is not null
         SET @LandSQM2 = @lang_WITH + N' ' + REPLACE(CONVERT(nvarchar, CAST(@LandSQM AS money), 1),'.00','') + N'm2' + @lang_LAND
       ELSE
         SET @LandSQM2 = N''

       /* BEDROOMS */

       IF @Bedrooms is not NULL
          IF @Bedrooms = 0
             SET @lang_BEDROOMS = N''
          ELSE
             SET @lang_BEDROOMS = CONVERT(NVARCHAR,@Bedrooms) + N' ' + (SELECT LOWER(Bedroom) FROM Langs WHERE Lang=@Lang) + N' '

       ELSE
         SET @lang_BEDROOMS = N''

       /* REAL ESTATE TYPE */

       IF @PType is not NULL          
          SET @lang_PType = LOWER((SELECT TOP 1 Translation FROM Langs_PTypes WHERE PType = @PType AND Lang = @Lang))
       ELSE
         SET @lang_PType = N'property'

       SET @PropertyTitle = @lang_BEDROOMS + @lang_PType + @lang_FORSALEORRENT + @LandSQM2 + @Urbanisation + @Location + @County
       END
  END

RETURN @PropertyTitle
END

EXAMPLE

The output would be something like:

5 bedroom House with 1,000 m2 of land in Miami Beach, Miami

TVRV8S
  • 69
  • 10
  • You should be able to build this in your calling procedure/query by concatenating a bunch of CASE statements. – Tab Alleman Nov 13 '15 at 15:52
  • You could probably even turn that into an inline table valued function. If you do this do not get confused about table valued functions. It MUST be a single select statement or it becomes a multi statement table valued function which can actually perform even worse than your scalar functions. – Sean Lange Nov 13 '15 at 16:07
  • Do you have any examples of how I can turn the second example (for the title) into an inline function? Many thanks. – TVRV8S Nov 16 '15 at 10:26

0 Answers0