1

I am trying to create a computed column using a udf. I keep hitting the cannot be persisted because the column does user or system data access, when i try creating a index for that column or even for trying to make the column persisted.

This is the udf func i am using :

CREATE FUNCTION x.bal(@ID NVARCHAR(128))
RETURNS DECIMAL WITH SCHEMABINDING
AS 
BEGIN
DECLARE @SUM DECIMAL ;
    WITH CTE AS (
    SELECT ROW_NUMBER() OVER (ORDER BY date ASC, type DESC) AS ROWNUMBER,[Id]
     T_id
    FROM x.entries
    )
    
    SELECT @SUM = (SELECT SUM(AMOUNT) FROM CTE L1
    WHERE L1.B_ID = L2.B_ID  AND L1.DATE <= L2.DATE AND L1.ROWNUMBER<L2.ROWNUMBER)
    FROM CTE L2
    WHERE L2.ID = @ID
    RETURN @SUM
END
GO 

to add the column :

ALTER TABLE x.Entries
ADD bal AS dbo.bal(id) 
CREATE INDEX IDX_bal ON x.Entries(bal)

I have also found that the error is only on 2017 local sql server where as for Azure sql ,I see the following : If I run the Column Property check before creating the index, it works but if missed, it fails.

1 Answer 1

1

A PERSISTED COMPUTED column can't use Window functions like ROW_NUMBER(). It's one of the limitations because ROW_NUMBER() is not a deterministic function and only deterministic functions can be used with PERSISTED COMPUTED columns.

Paul White does a great write up on how to properly use PERSISTED COMPUTED columns in his article here.

Specifically he mentions how PERSISTED was added only for deterministic columns:

Persisted computed columns were added to the product specifically to allow indexes to be built on deterministic but "imprecise" (floating point) columns

If you could add a few more details on what your end goal is, I could try to suggest an alternative solution to solve the problem (e.g. what is the purpose of your UDF)?

2
  • The UDF is just trying to a roll up sum of amount ( amount specific by a logic, eg for a customer ) . Since there is no row number in the existing table and there is a possibility that the date could be the same on one or more rows , i am having to use the rownumber() . I could essentially create a column with rownumber and try it that way . Even with that the udf shows up as not indexable = true. Although the isDeterminitistic property is still true in both cases
    – R.S
    Commented Dec 14, 2020 at 3:18
  • @R.S I'm still trying to understand what you're trying to accomplish and will get back to you if I can come up with an alternative solution but having your Table schema and actual column names would help clarify what your query is trying to do. If you can, please update your post with this information.
    – J.D.
    Commented Dec 14, 2020 at 15:48

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.