Opérateur à effet latéral d'utilisation incorrecte Insérer dans une fonction

J'ai le code suivant dans ma fonction sql:

if @max_chi > -999 begin INSERT INTO CH_TABLE(X1, X2, VALUE) VALUES(cur_out.sessionnumber, maxpos, max_chi) commit end 

Ce qui suit est une requête SQL Server 2008 et il me donne une erreur:

Utilisation invalide d'un opérateur à effet latéral 'INSERT' dans une fonction.

Pourquoi n'ai-je pas le droit de faire ça? Que puis-je faire pour résoudre ce problème?

Vous ne pouvez pas utiliser une fonction pour insert des données dans une table de base . Les fonctions renvoient des données. Ceci est répertorié comme la toute première limitation dans la documentation :

Les fonctions définies par l'user ne peuvent pas être utilisées pour effectuer des actions qui modifient l'état de la database.

"Modifier l'état de la database" inclut la modification des données dans la database (bien qu'une variable de table soit une exception évidente que l'OP n'aurait pas pris en count il y a 3 ans environ). les tables sous-jacentes de quelque façon que ce soit).

Vous devriez utiliser une procédure stockée, pas une fonction.

Les fonctions ne peuvent pas être utilisées pour modifier les informations de la table de base, utilisez une procédure stockée.

J'ai trouvé une façon de faire une insertion ou une mise à jour, il suffit donc de replace le code dans la variable @sql .

 CREATE FUNCTION [dbo].[_tmp_func](@orderID NVARCHAR(50)) RETURNS INT AS BEGIN DECLARE @sql varchar(4000), @cmd varchar(4000) SELECT @sql = 'INSERT INTO _ord (ord_Code) VALUES (''' + @orderID + ''') ' SELECT @cmd = 'sqlcmd -S ' + @@servername + ' -d ' + db_name() + ' -Q "' + @sql + '"' EXEC master..xp_cmdshell @cmd, 'no_output' RETURN 1 END 

Il existe une exception (j'utilise SQL 2014) lorsque vous utilisez uniquement Insert / Update / Delete sur Declared-Tables. Ces instructions Insert / Update / Delete ne peuvent pas contenir d'instruction OUTPUT. L'autre ressortingction est que vous n'êtes pas autorisé à faire un MERGE, même dans une table déclarée. J'ai interrompu mes instructions de fusion, cela ne fonctionnait pas, dans les instructions Insert / Update / Delete qui fonctionnaient.

La raison pour laquelle je ne l'ai pas convertie en procédure stockée est que la fonction table était plus rapide (même sans MERGE) que la procédure stockée. C'est malgré la procédure stockée qui me permet d'utiliser des tables temporaires qui ont des statistics. J'avais besoin que la fonction table soit très rapide, puisqu'elle s'appelle 20-K fois / jour. Cette fonction de table ne met jamais à jour la database.

J'ai également remarqué que les fonctions SQL NewId () et RAND () ne sont pas autorisées dans une fonction.