web-dev-qa-db-fra.com

Obtenir une erreur lors de l'exécution d'un SQL dynamique dans une fonction (SQL Server)?

Je crée une fonction pour exécuter du SQL dynamique et renvoyer une valeur. Je reçois "Seules les fonctions et certaines procédures stockées étendues peuvent être exécutées à partir d'une fonction." comme une erreur.

La fonction:

Create Function fn_GetPrePopValue(@paramterValue nvarchar(100))
returns int as
begin
declare @value nvarchar(500);

Set @SQLString  = 'Select Grant_Nr From Grant_Master where grant_id=' + @paramterValue

exec   sp_executesql
       @query = @SQLString,       
       @value = @value output

return @value   
end 

L'exécution:

Select dbo.fn_GetPrePopValue('10002618') from Questions Where QuestionID=114

et:

Select fn_GetPrePopValue('10002618') from Questions Where QuestionID=114

La fonction est-elle appelée correctement ou est-elle incorrecte?

15
Chaka

Vous ne pouvez pas utiliser le SQL dynamique à partir d'une fonction, ni appeler des procédures stockées

Create proc GetPrePopValue(@paramterValue nvarchar(100))
as
begin
declare @value nvarchar(500),
        @SQLString nvarchar(4000)

Set @SQLString = 'Select @value = Grant_Nr From Grant_Master where grant_id = @paramterValue'

exec sp_executesql @SQLString, N'@paramterValue nvarchar(100)', 
       @paramterValue, 
       @value = @value output

return @value   
end 
8

Les fonctions sont limitées dans ce qu'elles peuvent utiliser, de sorte que vous pouvez les utiliser dans une requête sans créer accidentellement quelque chose qui donnerait des performances horribles. L'utilisation de requêtes dynamiques est l'une de ces choses, car cela provoquerait une planification de requête pour chaque exécution et empêcherait également la fonction de faire partie d'un plan de requête.

Dans ce cas, vous n'avez pas du tout besoin de la requête dynamique, il vous suffit de renvoyer la valeur:

Create Function fn_GetPrePopValue(@paramterValue nvarchar(100))
returns int as
begin

return (select Grant_Nr From Grant_Master where grant_id = @paramterValue)

end 
1
Guffa

Je ne pense pas que vous puissiez utiliser le SQL dynamique à partir d'une fonction, et je ne pense pas que vous en ayez besoin dans votre cas. On dirait que vous voulez quelque chose de plus proche de ça:

Create Function dbo.fn_GetPrePopValue(@paramterValue nvarchar(100))
returns int as
begin
  declare @value int
  declare @SQLString varchar(MAX)

  Select @value=Grant_Nr From Grant_Master where grant_id=@paramterValue

  return @value
end 

Démo SQL Fiddle

Vérifiez également vos types de données pour vous assurer que les champs sont corrects. Semble étrange de passer un varchar pour l'identifiant et de renvoyer un int pour l'autre champ. Dans les deux cas, cela devrait vous aider à aller dans la bonne direction.

0
sgeddes