Question

Code

create table ExampleTable
(
    Name varchar(500)
    CultureCode(5)
)

insert into ExampleTable values('Dit is een test', 'nl-NL')
insert into ExampleTable values('This is a test', 'en-GB')
insert into ExampleTable values('Ceci est un test', 'fr-FR')
insert into ExampleTable values('Dies ist ein Test', 'de-DE')

create procedure GetNameByCultures
(
@CultureCodes varchar(250)
)
as 
begin
//Get ExampleTable items according to the culture codes stated in @CultureCodes
end

-Example:

CREATE TYPE StringListType AS TABLE
(
    [str] varchar(5) NULL
)

I am using MS SQL 2012 V11.0.2100.60

Situation

I'm trying to find the best way (Performance wise) to extract the labels. Methods I have thought of, but not yet tested are:

  • Creating a user defined table type as shown in the above.

Upside: I know it has almost no performance on the database.

Downside: I have to add another parameter to the stored procedure.

  • Creating a function which splits a string by the char: ','

Downside: I know using "Right", "Left", "Like" and other varchar converting / editing properties are slow in SQL

UpSide: I can keep the processing in the database.

In the current situation i'm only sending one culturecode inside a user defined table type. So it's impossible to add the culturecode in this UDTT as you can't add a UDTT to a UDTT. My only option would be to add another parameter to the stored procedure which shouldn't be to much of a issue... but we like to keep it to only one.

Does anyone happen to know another (better?) method or should I go with one of these?

Was it helpful?

Solution

Table valued parameters are the best way as you're using 2008 onwards. (See MSDN).

I would thoroughly recommend you read SQL Server MVP Erland Sommarskog's very comprehensive articles on the different methods available, with analysis and performance details.

OTHER TIPS

I would still pass the list of cultures as comma separated string, define a function which returns a table and then join this table to your example table. As long as the string contains a small number of elements, you will not notice any performance drop.

If you can live with the limitation of passing a maximum of N culture codes, you could try something like this

create procedure GetNameByCulture 
  @CultureInfo varchar(5),
  @CultureInfo1 varchar(5) = null,
  @CultureInfo2 varchar(5) = null
as
 select e.* 
   from ExampleTable e 
        join (
          select @CultureInfo as CultureInfo union
          select @CultureInfo1 union
          select @CultureInfo2
          ) x 
          on e.CultureInfo = x.CultureInfo

This would be a bit faster than the string version, I guess. But as I mentioned, it won't be a big deal anyway.

what about using replace and cast for xml instead left/right to split string?

    declare @ExampleTable table
    (
        Name varchar(500),
        CultureCode varchar(5)
    )

    insert into @ExampleTable values('Dit is een test', 'nl-NL')
    insert into @ExampleTable values('This is a test', 'en-GB')
    insert into @ExampleTable values('Ceci est un test', 'fr-FR')
    insert into @ExampleTable values('Dies ist ein Test', 'de-DE')


    declare @CultureCodes varchar(250)
    set @CultureCodes = 'nl-NL,en-GB,fr-FR'

    declare @xml xml
    set @xml = cast('<culturecodes><culture>'+REPLACE(@CultureCodes,',','</culture><culture>')+'</culture></culturecodes>' as xml)

    select 
           C.element.value('.','varchar(max)') as CultureCode_splited
          ,E.CultureCode 
          ,E.name
    from @xml.nodes('/culturecodes/culture')C(element)
    inner join @ExampleTable E
    on E.CultureCode = C.element.value('.','varchar(max)')

resultset seems like this...

    CultureCode_splited     CultureCode name
    nl-NL                   nl-NL       Dit is een test
    en-GB                   en-GB       This is a test
    fr-FR                   fr-FR       Ceci est un test
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top