Ungültige Verwendung eines Nebeneffektoperators 'Insert' in einer Funktion - Mehrere Einfügungen in der Funktion

dba.stackexchange https://dba.stackexchange.com/questions/12585

  •  16-10-2019
  •  | 
  •  

Frage

Wenn dies nicht das richtige Forum ist, lassen Sie es mich bitte wissen und es für mich bewegen.

Ich habe gerade eine Reihe von Einsätzen wie diesen gegen Ende meiner Skalarfunktion:

   INSERT INTO [Raptor].[dbo].[UserRole]
           ([RoleId]
           ,[UserId])
     VALUES
           (3
           ,@NewUserID)

    INSERT INTO [Raptor].[dbo].[UserRole]
               ([RoleId]
               ,[UserId])
         VALUES
               (5
               ,@NewUserID)
War es hilfreich?

Lösung

In T-SQL können Sie keine Daten in einer Funktion ändern. Es gibt keinen einfachen Weg. Es gibt einige obskure Hacks, aber ich würde sie nicht benutzen. Verwenden Sie ein gespeichertes Verfahren.

Der Hack, der von Erland Sommarskog zitiert:

CREATE FUNCTION loophole(@i int) RETURNS varchar(20) AS
  BEGIN
     DECLARE @sql varchar(MAX),
             @cmd varchar(4000)
     SELECT @sql = ' UPDATE rsci ' +
                   ' SET b = CASE ' + ltrim(str(@i + 1)) +
                   ' WHEN 1 THEN ''Ett'' WHEN 2 THEN ''Två''' +
                   ' WHEN 3 THEN ''Tre'' WHEN 4 THEN ''Fyra''' +
                   ' WHEN 5 THEN ''Fem'' WHEN 6 THEN ''Sex''' +
                   ' WHEN 7 THEN ''Sju'' WHEN 8 THEN ''Åtta''' +
                   ' WHEN 9 THEN ''Nio'' WHEN 10 THEN ''Tio'' END' +
                   ' WHERE a = ' + ltrim(str(@i + 1))
     SELECT @cmd = 'sqlcmd -S ' + @@servername + ' -d ' + db_name() +
                   ' -Q "' + @sql + '"'
     EXEC master..xp_cmdshell @cmd, 'no_output'
     RETURN (SELECT b FROM rsci WHERE a = @i)
  END

Andere Tipps

Es gibt eine Ausnahme (ich verwende SQL 2014), wenn Sie nur in deklarierten Tabellen Insert/Update/Löschen verwenden. Diese Anweisungen einfügen/aktualisieren/löschen können keine Ausgabeanweisung enthalten. Die andere Einschränkung ist, dass Sie keine Verschmelzung durchführen dürfen, selbst in einen deklarierten Tisch. Ich habe meine Zusammenführungsanweisungen, die nicht funktionierten, in Einfügen/Aktualisierung/Löschen von Anweisungen, die funktioniert haben, aufgelöst.

Der Grund, warum ich es nicht in eine gespeicherte Ausgabe umgewandelt habe, ist, dass die Tischfunktion schneller war (auch ohne die Zusammenführung) als die gespeicherte Verarbeitung. Dies trotz der gespeicherten Verarbeitung, die es mir ermöglicht, Temperaturtabellen mit Statistiken zu verwenden. Ich brauchte die Tischfunktion, um sehr schnell zu sein, da sie 20-k-Zeiten/Tag genannt wird. Diese Tabellenfunktion aktualisiert niemals die Datenbank.

Mir ist auch aufgefallen, dass die Funktionen von Newid () und Rand () in einer Funktion nicht zulässig sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top