0

je suis en train d'exécuter cette fonction scalaire et j'ai essayé beaucoup d'approches pour y parvenir, mais je suis bloquécomment évaluer une expression arithmétique dans une fonction scalaire 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 

Lorsque je tente de l'exécuter

select dbo.CalculateElementFunc()

i obtenir cette erreur

Msg 557, Niveau 16, État 2, ligne 1 Seules les fonctions et ainsi Les procédures stockées étendues peuvent être exécutées depuis une fonction.

S'il vous plaît Advice

+0

Les fonctions dans T-SQL ne peuvent pas avoir d'effets secondaires. Par conséquent, vous ne pouvez pas insérer/mettre à jour ou appeler des procédures stockées. À moins que vous n'impliquiez vous-même l'analyseur d'expression (ce qui n'est certainement pas trivial), je ne pense pas que cela soit possible en TSQL pur. D'ailleurs, la performance serait horrible. Vous pourriez peut-être utiliser une fonction CLR pour le faire. –

+0

alors .. quelle est l'alternative pour évaluer une expression arithmétique dans une fonction scalaire SQL – Mariam

+0

Comme je l'ai dit (et d'autres ont également souligné) si l'expression est inconnue au moment du design, et vous avez besoin d'une fonction (pas une procédure stockée), votre seule option est les fonctions CLR (ou mieux encore: ne pas le faire en SQL) –

Répondre

0

Limitations des fonctions définies par l'utilisateur SQL:

  1. construction non déterministe dans les fonctions ne peuvent pas être utilisées dans les fonctions définies par l'utilisateur. par exemple. GETDATE() ou RAND().
  2. Le type de données XML n'est pas pris en charge.
  3. Les requêtes SQL dynamiques ne sont pas autorisées.
  4. Les fonctions définies par l'utilisateur ne prennent pas en charge les instructions DML (INSERT, UPDATE, DELETE), sauf si elles sont exécutées sur la variable de table.
  5. Nous ne pouvons pas appeler la procédure stockée. Seule la procédure stockée étendue peut être appelée depuis la fonction.
  6. Nous ne pouvons pas créer de tables temporaires dans les fonctions définies par l'utilisateur.
  7. Il ne prend pas en charge la gestion des erreurs à l'intérieur de la fonction UDF. Bien que, nous pouvons gérer les erreurs (RAISEERROR, TRY-CATCH) pour les instructions qui utilisent cette fonction.

Et il semble que vous utilisez/appelez une procédure stockée dans votre fonction définie par l'utilisateur. Ce n'est pas l'expression qui vous dérange, c'est cet appel de procédure stockée. Essayez de le remplacer par une logique pour obtenir la sortie désirée.

J'espère que cela vous sera utile. Si cela aide à résoudre votre problème, n'oubliez pas de le marquer comme une réponse.

+0

alors .. quelle est l'alternative pour évaluer une expression arithmétique dans une fonction scalaire SQL – Mariam

+0

@SachinA: Êtes-vous sûr de # 1? Les fonctions non-déterministes sont très bien dans UDF AFAIK. C'est juste qu'ils rendent l'UDF non déterministe aussi. –

+0

@ P.Kouvarakis: Oui, la fonction intégrée non déterministe fonctionnera correctement, mais chaque fois que vous exécutez votre fonction définie par l'utilisateur - la fonction de construction non déterministe vous donnera une sortie différente (à chaque fois). Et je ne pense pas que ce soit fiable à utiliser. –

1

Ceci est trop long pour un commentaire.

Ce que vous voulez faire n'est pas recommandé dans SQL Server. D'abord, c'est vraiment dur. Comme vous l'avez appris, une fonction SQL Server ne peut pas exécuter SQL dynamique.

Ceci est subtilement dans le documentation:

EXECUTE appelant des procédures stockées étendues.

exec et sp_executesql ne sont pas des procédures stockées étendues.

Que pouvez-vous faire? Voici quelques options:

  1. Une procédure stockée au lieu d'une fonction UDF est-elle possible? Les procédures stockées peuvent exécuter le SQL dynamique.
  2. Pouvez-vous contourner le problème de l'évaluation de l'expression? Peut-être que le SQL dynamique peut être utilisé d'un niveau dans votre code.
  3. pouvez exécuter une procédure stockée étendue qui démarre une autre transaction et exécute le SQL dynamique. Pensez: très mauvaise performance.
  4. Vous pouvez écrire une fonction étendue CLR.
+0

aucun moyen d'évaluer une expression arithmétique dans une fonction scalaire SQL? – Mariam

+0

@Mariam. . . Vous pouvez écrire une fonction CLR ou utiliser une procédure stockée étendue. Il n'y a pas de moyen facile. –