2009-05-06 26 views
1

Ich muss eine gespeicherte Prozedur schreiben, um eine aus einer Reihe ähnlicher Spalten zu aktualisieren. Die Spalten heißen 'UserField1', 'UserField2' usw. Ich hatte gehofft, einen Parameter an den SPROC zu übergeben, der die Spalte auf den neuesten Stand bringen würde. Allerdings kann ich den Code nicht korrekt finden. Hier ist ein vereinfachtes Beispiel, was ich versucht (was wird mir eine ‚falsche Syntax‘ message):TSQL parametrisierte SPROC Frage

create procedure UpdateUserField 
    (@UserFieldNumber int, @UserFieldNewValue int) 
as 
    update MyTable set 
     case @UserFieldNumber 
     when 1 then UserField1 
     when 2 then UserField2 
     end 
    = @UserFieldNewValue 
+0

wo es die „falsche Syntax“ in der auftritt, sagt Skript? –

+0

'in der Nähe des Schlüsselwortes' CASE '. – dsteele

Antwort

2

Wie wäre es mit einer Anzahl von IFs?

CREATE PROCEDURE UpdateUserField 
(
    @UserFieldNumber int, 
    @UserFieldNewValue int 
) AS 

IF @UserFieldNumber=1 
BEGIN 
    UPDATE MyTable SET UserField1 = @UserFieldNewValue 
END 

IF @UserFieldNumber=2 
BEGIN 
    UPDATE MyTable SET UserField2 = @UserFieldNewValue 
END 

Alternativ können Sie dynamische SQL in einem

exec bauen
CREATE PROCEDURE UpdateUserField 
(
    @UserFieldNumber int, 
    @UserFieldNewValue int 
) AS 

EXEC('UPDATE MyTable SET UserField' + CONVERT(varchar(10), @UserFieldNumber) + ' = ' + CONVERT(varchar(10), @UserFieldNewValue)) 

SQL Injection Vorsicht, wenn Sie dies jedoch tun, mit ints werden Sie kein Problem haben, alles andere müssen Sie Risiken berücksichtigen .

-1

Ich glaube nicht, Sie CASE-Anweisungen in Feldlisten in Anweisungen verwendet werden können. Ich bin fast überzeugt, dass Sie CASE-Anweisungen nur auf die Werte anwenden können, die Sie festlegen, zurückgeben oder testen.

In Ihrem Beispiel versuchen Sie, die Feldliste mit Hilfe von Case-Anweisungen zu ändern, und ich gehe davon aus, dass SQL Probleme damit hat, da die Feldliste erst nach dem Kompilieren und Ausführen der Anweisung ermittelt wird eine Hühner- und Eissituation.

0
if @UserFieldNumber=1 
BEGIN 
    update MyTable set [email protected] where... 
END 
ELSE if @UserFieldNumber=2 
BEGIN 
    update MyTable set [email protected] where... 
END 
ELSE if @UserFieldNumber=3 
BEGIN 
    update MyTable set [email protected] where... 
END 
+0

das ist eine schreckliche schreckliche Lösung :( was ist, wenn er 50 mögliche Felder hat ... Der Sproc wäre riesig –

+0

@Eoin Campbell, er hat bereits ein schreckliches Design, aber kann nicht über einen Syntaxfehler erhalten, er hat Viele Probleme, am wenigsten ist diese Lösung! –

+0

Hallo, danke :) Der Hintergrund hier ist, dass ich eine Tabelle im Microsoft Business Contact Manager Add-on für MS Outlook aus einem Inhouse-Programm aktualisieren muss. – dsteele

0

Der Befehl update akzeptiert keine dynamischen Feldnamen.

Statt dessen, was Sie tun können, ist eine Zeichenkette mit der Update-Anweisung erstellen, die Sie ausführen möchten, und dann ausführen, wie folgt aus:

DECLARE @strToExecute VARCHAR(1000) 
SET @strToExecute = 'UPDATE MyTable ' 
IF @UserFieldNumber = 1 
    SET @strToExecute = @strToExecute + ' SET UserField1 = ' 
IF @UserFieldNumber = 2 
    SET @strToExecute = @strToExecute + ' SET UserField2 = ' 

Und so auf der Schnur, zu bauen und dann ausführen es.

+0

Das zweite '=' in den Zeilen 4 und 6 sollte '+' sein –

+0

Ha! Du hast ja so recht. Behoben das - toller Fang. Habe es zu einem Community-Wiki gemacht, während ich dort war, damit andere mehr Tippfehler korrigieren können, hahaha. –

-1

AFAIK Sie können einen CASE WHEN nicht verwenden, um die Spalte anzugeben.

Sie könnten dies jedoch in einige dynamische SQL einpacken.

CREATE PROCEDURE UpdateUserField 
( 
    @UserFieldNumber int, 
    @UserFieldNewValue int 
) 
AS 

DECLARE @sql nvarchar(max) 
SET @sql = 'UPDATE MyTable SET UserField' + @UserFieldNumber + ' = ' + @UserFieldNewValue 
EXEC (@sql) 
+0

Ihr Code wird zu einem Fehler führen, Sie können ein int nicht auf eine Zeichenkette verketten und Nullen werden die gesamte Zeichenkette löschen –

2

Wenn Sie keine dynamische SQL oder mehrere IF und UPDATE Aussagen verwenden möchten, dann können Sie so etwas wie dieses stattdessen versuchen:

UPDATE MyTable 
SET UserField1 = CASE WHEN @UserFieldNumber = 1 
     THEN @UserFieldNewValue ELSE UserField1 END, 
    UserField2 = CASE WHEN @UserFieldNumber = 2 
     THEN @UserFieldNewValue ELSE UserField2 END