Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8954533
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T14:20:05+00:00 2026-06-15T14:20:05+00:00

I have a SQL CLR UDF which queries a web service. Since this can

  • 0

I have a SQL CLR UDF which queries a web service. Since this can be costly, especially within the function is part of a query on multiple rows, I would like to avoid calling the web service whenever possible. In every case, the same input will yield the same output (e.g., if my input is ‘abc’ I will always get ‘xyz’ and nothing different, likewise ‘def’ will always yield ‘tuv’, etc).

I have done some tests, and it seems that SQL does not do any sort of caching on its end, so the web service will always be invoked.

Example Case: I have a table MyTable with a field MyField1. While MyTable has 500 rows, MyField1 will always only have one of 3 possible values. Example query:

SELECT MyFunction(MyField1) FROM MyTable

What happens is that the web service will be called 500 times, once for each row in the table. What I would prefer is that the web service is only called 3 times (once for each distinct value), and read from some cache for the duplicate values.

Example Code:

[SqlFunction]
public static SqlString MyFunction(SqlString input)
{
    if (input.IsNull) return SqlString.Null;

    using (var webService = new MyWebService())
    {
        string result = webService.Call(input.Value);

        return new SqlString(result);
    }
}

What I would really prefer is to keep this in a cache that is specific to the context. That is, the cache would only exist to cache results within the call of a single stored procedure, or within a single query window, etc. Is there any available mechanism to accomplish what I’m after?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T14:20:06+00:00Added an answer on June 15, 2026 at 2:20 pm

    EDIT
    NOTE The updated version towards the end

    Although this answer doesn’t use caching, it should minimise the number of calls to your function. using a number of CTEs to find the distinct values of myField1, then lookup the distinct values in the webservice using your function, then join these back to MyTable. The example below probably makes it clearer:

    SQL Fiddle

    MS SQL Server 2008 Schema Setup:

    CREATE TABLE MyTable
    (
        ID int PRIMARY KEY IDENTITY,
        MyField1 VARCHAR(1)
    );
    
    
    CREATE FUNCTION MyFunction
    (
        @input As VARCHAR(1)
    )
    RETURNS VARCHAR(10)
    AS
    BEGIN
        -- This could be a CLR Function
        -- Return the result of the function
        RETURN  CASE @input WHEN 'A' THEN 'aaaaaaaaaa' WHEN 'B' THEN 'bbbbbbbbbb' ELSE 'ccccccccc' END
    
    END;
    
    -- DATA SET UP
    DECLARE @i INT = 0
    DECLARE @Field VARCHAR(1)
    WHILE @i < 1000
    BEGIN
        SELECT @Field = CASE @i % 3 WHEN 1 THEN 'A' WHEN 2 THEN 'B' ELSE 'C' END
        INSERT INTO MyTable (MyField1) VALUES  (@Field)
        SET @i = @i + 1
    END
    

    Query 1:

    ;WITH DistinctMyField1CTE
    AS
    (
        SELECT DISTINCT MyField1
        FROM MyTable
    ),
    LookupValuesCTE
    AS
    (
        SELECT MyField1, dbo.MyFunction(MyField1) As MyOutputField
        FROM DistinctMyField1CTE
    )
    SELECT TOP 20 T1.Id, T1.MyField1, T2.MyOutputField
    FROM MyTable T1
    INNER JOIN LookupValuesCTE T2
        ON T1.MyField1 = T2.MyField1
    ORDER BY T1.ID
    

    Results:

    | ID | MYFIELD1 | MYOUTPUTFIELD |
    ---------------------------------
    |  1 |        C |     ccccccccc |
    |  2 |        A |    aaaaaaaaaa |
    |  3 |        B |    bbbbbbbbbb |
    |  4 |        C |     ccccccccc |
    |  5 |        A |    aaaaaaaaaa |
    |  6 |        B |    bbbbbbbbbb |
    |  7 |        C |     ccccccccc |
    |  8 |        A |    aaaaaaaaaa |
    |  9 |        B |    bbbbbbbbbb |
    | 10 |        C |     ccccccccc |
    | 11 |        A |    aaaaaaaaaa |
    | 12 |        B |    bbbbbbbbbb |
    | 13 |        C |     ccccccccc |
    | 14 |        A |    aaaaaaaaaa |
    | 15 |        B |    bbbbbbbbbb |
    | 16 |        C |     ccccccccc |
    | 17 |        A |    aaaaaaaaaa |
    | 18 |        B |    bbbbbbbbbb |
    | 19 |        C |     ccccccccc |
    | 20 |        A |    aaaaaaaaaa |
    

    EDIT:
    Note when I check a SQL Profiler trace of the aboce, I see a 1000 calls to the UDF, in other words the query analyser is generating a plan which expands out the CTE’s and calls the UDF once for each row.

    The following uses a table variable to ensure that the UDF is only called 3 times. I have traced this in SQL Profiler and it is much more efficient. This uses the same table and functions as above. Need SQLFiddle Attached

    SQL Fiddle

    MS SQL Server 2008 Schema Setup:

    CREATE TABLE MyTable
    (
        ID int PRIMARY KEY IDENTITY,
        MyField1 VARCHAR(1)
    );
    
    
    CREATE FUNCTION MyFunction
    (
        @input As VARCHAR(1)
    )
    RETURNS VARCHAR(10)
    AS
    BEGIN
        -- This could be a CLR Function
        -- Return the result of the function
        RETURN  CASE @input WHEN 'A' THEN 'aaaaaaaaaa' WHEN 'B' THEN 'bbbbbbbbbb' ELSE 'ccccccccc' END
    
    END;
    
    -- DATA SET UP
    DECLARE @i INT = 0
    DECLARE @Field VARCHAR(1)
    WHILE @i < 1000
    BEGIN
        SELECT @Field = CASE @i % 3 WHEN 1 THEN 'A' WHEN 2 THEN 'B' ELSE 'C' END
        INSERT INTO MyTable (MyField1) VALUES  (@Field)
        SET @i = @i + 1
    END
    

    Query 1:

    DECLARE @TempTable TABLE
    (
        MyField1 VARCHAR(1) PRIMARY KEY,
        MyOutputField VARCHAR(10) NULL
    )
    
    INSERT INTO @TempTable (MyField1)
    SELECT DISTINCT MyField1
    FROM MyTable
    
    
    -- UPDATE Separately otherwise the function gets called
    -- for every row in MyTable
    UPDATE @TempTable
        SET MyOutputField = dbo.MyFunction(MyField1)
    
    SELECT TOP 20 T1.ID, T1.MyField1, T2.MyOutputField
    FROM MyTable T1
    INNER JOIN @TempTable T2
        ON T1.MyField1 = T2.MyField1
    

    Results:

    | ID | MYFIELD1 | MYOUTPUTFIELD |
    ---------------------------------
    |  2 |        A |    aaaaaaaaaa |
    |  5 |        A |    aaaaaaaaaa |
    |  8 |        A |    aaaaaaaaaa |
    | 11 |        A |    aaaaaaaaaa |
    | 14 |        A |    aaaaaaaaaa |
    | 17 |        A |    aaaaaaaaaa |
    | 20 |        A |    aaaaaaaaaa |
    | 23 |        A |    aaaaaaaaaa |
    | 26 |        A |    aaaaaaaaaa |
    | 29 |        A |    aaaaaaaaaa |
    | 32 |        A |    aaaaaaaaaa |
    | 35 |        A |    aaaaaaaaaa |
    | 38 |        A |    aaaaaaaaaa |
    | 41 |        A |    aaaaaaaaaa |
    | 44 |        A |    aaaaaaaaaa |
    | 47 |        A |    aaaaaaaaaa |
    | 50 |        A |    aaaaaaaaaa |
    | 53 |        A |    aaaaaaaaaa |
    | 56 |        A |    aaaaaaaaaa |
    | 59 |        A |    aaaaaaaaaa |
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a SQL CLR function which at the moment returns a string seperated
I have an interface in CLR between SQL Server and the Exchange Web Services
I have a SQL CLR function that receives a SQLString, and I am converting
I have a CLR SQL Trigger, that tries to communicate with a WCF service
I have an existing C# CLR runtime function that I am using with SQL
I have SQL Server 2008 with a table called ProductCategories designed like this: Id
I have SQL Ce db in my app, which is included in my app
I have SQL Server Express and Visual Studio Web Developer Express running on my
I'm working with some SQL 2005 CLR code written in C#. We have recently
We have C# entity classes which map to some of our SQL Server database

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.