0

I'm new to tSQL functions and I'm trying to do the following:

I have a table like this called Projects:

+----------+--------------+
| Code     | Previous_Code|
+----------+--------------+
| 001      | NULL         |
| 002      | 001          |
| 003      | 002          |
| 004      | NULL         |
| 005      | NULL         |
+----------+--------------+

And I'd like to create an SQL function to produce the following query result:

+----------+--------------+
| Code     | Original_Code|
+----------+--------------+
| 001      | 001          |
| 002      | 001          |
| 003      | 001          |
| 004      | 004          |
| 005      | 005          |
+----------+--------------+

I've come up with the function below:

CREATE FUNCTION OriginalProjectCode (@Code VARCHAR(3))
RETURNS VARCHAR(3)
AS
BEGIN
DECLARE @Code2 AS VARCHAR(3);
WHILE @Code IS NOT NULL
    BEGIN
        SET @Code2 = @Code;
        SET @Code = ('SELECT [Previous_Code] FROM 
        Projects WHERE [Code] = ' + @Code);
        SET @Code2 = @Code;
    END;
RETURN @Code2;
END;

But it just seems to be in an infinite loop when it is run. Doe anyone one have any ideas or a better way of achieving the same result? Thanks in advance.

7
  • 1
    Can you clarify the requirements? From your second table it seems that you want to follow the chain of Previous_Code values until you reach a Code with a Previous_Code of NULL, is that right? So, 003 -> 002 -> 001 -> NULL, therefore "003" has an Original_Code of "001". I'm not clear though why "001" has an Original_Code of "001", when "004" and "005" both have Original_Codes of "NULL" Commented Aug 21, 2018 at 9:12
  • How does your code executed the SQL statement? I don't see any sp_execute command. Commented Aug 21, 2018 at 9:13
  • 1
    This is a really bad idea. Scalar functions in SQL Server can perform awfully, and introducing a WHILE loop into one is a double disaster. What is your actual goal here? You would be far far better off using an inline table-value function. Commented Aug 21, 2018 at 9:15
  • daveydavedave is right to point that out. The example is edited according now. Thanks. Commented Aug 21, 2018 at 9:15
  • 2
    Isn't this just a hierarchy? A recursive CTE should do it. There's plenty of examples on SO Commented Aug 21, 2018 at 9:21

2 Answers 2

1

It seems simple case expression would work :

select t.*, (case when Previous_Code is not null 
                  then coalesce(lag(Previous_Code, 1) over (order by code), Previous_Code) 
                  else code
             end) as Original_Code
from table t;
Sign up to request clarification or add additional context in comments.

1 Comment

This "works" for up to two levels but fails if, say, 004s Previous_Code is 003, which should presumably mean that that row gets assigned 001 as well, but this code assigns it 002. I think they're looking for something that works more generally
0

Hope this helps!!

    CREATE TABLE #Projects(Code VARCHAR(10),Previous_Code VARCHAR(10))

    INSERT INTO #Projects
    SELECT '001',NULL  Union ALL
    SELECT '002','001' Union ALL
    SELECT '003','002' Union ALL
    SELECT '004',NULL  Union ALL
    SELECT '005',NULL 

    DECLARE @id varchar(10)='003'

    ;with cte
    AS
    (
         select code,code as Original_Code,ISNULL(Previous_Code,code)Previous_Code
           from #Projects
           union all
          select c.Code,p.code as Original_Code, p.Previous_Code
           from #Projects p
             join cte c on c.Previous_Code = p.code  

    )

    SELECT code,Original_Code
    from cte 
    WHERE
        1= ( CASE WHEN Previous_Code IS NULL AND code !=Original_Code then 1
            WHEN code=Original_Code and Original_Code=Previous_Code then 1
            ELSE 0 END)
    order by code,Previous_Code


    DROP TABLE #Projects

1 Comment

Genius! I adapted that and got it to work. Thank you for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.