0

我試圖執行此標量函數內計算算術表達式,我嘗試了很多的方法來實現這一點,但我會被卡住如何在SQL標量函數

Create FUNCTION CalculateElementFunc() 
RETURNS int 
AS 
BEGIN 
    DECLARE @ResultVar numeric(18,6) 
    DECLARE @eq nvarchar(MAX) 
    set @eq = '7.5/100*1258.236'  

    declare @expression nvarchar(max) 
    set @expression = @eq 

    declare @result int 
    declare @SQLString nvarchar(max) 
    Set @SQLString = N'Select @result = @expression' 

    exec sp_executesql @SQLString, N'@expression nvarchar(100)', 
      @expression, 
      @result = @result output 

    select @ResultVar = @result 

    if(@ResultVar <> ROUND(@ResultVar, 2 ,1)) 
    set @ResultVar = cast(ROUND(@ResultVar, 2 ,1) + .01 as numeric(18,2)) 

    RETURN @ResultVar 
END 

當我嘗試執行它

選擇dbo.CalculateElementFunc()

我得到這個錯誤

消息557,級別16,狀態2,行1個 只有等功能我擴展存儲過程可以在一個函數內執行。

請建議

+0

T-SQL中的函數不能產生副作用。因此,您無法插入/更新或調用存儲過程。除非你自己實現表達式分析器(當然不是微不足道的),否則我認爲在純TSQL中這是不可能的。此外,表現會很糟糕。你也許可以使用CLR函數來做到這一點。 –

+0

然後..什麼是評估算術表達式的SQL標量函數 – Mariam

+0

正如我所說(也有人指出)如果表達式在設計時是未知的,並且您需要函數(而不是存儲過程),你唯一的選擇是CLR函數(或更好的是:不要在SQL中執行) –

回答

0

限制上SQL用戶定義函數:函數

  1. 非確定生成不能在用戶定義的函數被使用。例如GETDATE()或RAND()。
  2. XML數據類型不受支持。
  3. 不允許動態SQL查詢。
  4. 用戶定義的函數不支持任何DML語句(INSERT,UPDATE,DELETE),除非它在表變量上執行。
  5. 我們無法調用存儲過程。只能從函數調用擴展存儲過程。
  6. 我們不能在UDF中創建臨時表。
  7. 它不支持UDF內的錯誤處理。雖然,我們可以爲使用此函數的語句處理錯誤(RAISEERROR,TRY-CATCH)。

而且看起來您正在使用/調用您的用戶定義函數中的存儲過程。這不是表達你的問題,而是存儲過程調用。

嘗試用一些邏輯替換它以實現您想要的輸出。

希望這是有幫助的。如果它有助於解決您的問題,那麼不要忘記將其標記爲答案。

+0

然後..什麼是評估SQL標量函數內的算術表達式的替代方法 – Mariam

+0

@SachinA:你確定關於#1嗎? UDF AFAIK中的非確定性函數是完美無缺的。只是它們使得UDF也是非確定性的。 –

+0

@ P.Kouvarakis:是的,非確定性內置函數可以正常工作,但是每次執行用戶定義函數時 - 非確定性內置函數會爲您提供不同的輸出(每次)。我不認爲它是可靠的使用。 –

1

這是太長的評論。

SQL Server中不建議您要做什麼。首先,這確實很難。如你所知,一個SQL Server函數不能執行動態SQL。

這是巧妙地在documentation

執行語句調用擴展存儲過程。

execsp_executesql不是擴展存儲過程。

你能做什麼?這裏有一些選項:

  1. 存儲過程而不是UDF的可能性?存儲過程可以執行動態SQL。
  2. 你能解決表情評估問題嗎?也許動態SQL可以在你的代碼中使用一級。
  3. 可以執行擴展存儲過程,啓動另一個事務並執行動態SQL。認爲:真的糟糕的表現。
  4. 你可以編寫一個CLR擴展函數。
+0

無法評估SQL標量函數中的算術表達式? – Mariam

+0

@Mariam。 。 。您可以編寫CLR函數或使用執行擴展存儲過程。沒有簡單的方法。 –