2009-07-30 13 views
30

Questo sembra una domanda T-SQL noob ma voglio passare come logica in una procedura memorizzata e stavo pensando che usare un CASE sarebbe stato il modo di farlo con qualcosa comeutilizzando Switch come logica in T-SQL

SELECT CASE @Type 
     WHEN 1 THEN 
      INSERT INTO dbo.Credit (
       CompanyName, 
       PhoneNumber, 
       City, 
       State 
      ) VALUES ( 
       @CompanyName, 
       @PhoneNumber, 
       @City, 
       @State) 
     WHEN 2 THEN 
      INSERT INTO dbo.Debit (
       CompanyName, 
       PhoneNumber, 
       City, 
       State 
      ) VALUES ( 
       @CompanyName, 
       @PhoneNumber, 
       @City, 
       @State) 
     WHEN 3 THEN 
      --ETC 
    END  

ma continuo a ricevere errori, c'è solo un errore di systax o è quello che sto facendo fuori a pranzo?

risposta

48

è necessario utilizzare if/else Se la struttura, in questo modo:

If @Type = 1 
    Begin 
     INSERT INTO dbo.Credit (
       CompanyName, 
       PhoneNumber, 
       City, 
       State 
     ) VALUES ( 
       @CompanyName, 
       @PhoneNumber, 
       @City, 
       @State) 
    End 
Else If @Type = 2 
    Begin 
     INSERT INTO dbo.Debit (
       CompanyName, 
       PhoneNumber, 
       City, 
       State 
     ) VALUES ( 
       @CompanyName, 
       @PhoneNumber, 
       @City, 
       @State) 
    End 
Else If @Type = 3 
    Begin 
     --ETC 
    END 
5

Il CASE statement can only be certain clauses, non per controllare il flusso. Puoi usarlo in un SET o in un'istruzione UPDATE, ma nessuno di questi aiuta quando aggiorni tabelle diverse. Senza alterare il tuo database (ad esempio creando una vista o qualcosa del genere), non penso che CASE sia la soluzione giusta qui.

+4

in T-SQL penso a CASE come operatore/expresion Non una dichiarazione. –

11

Sebbene non vi sia nulla di sbagliato nella risposta di G Mastros, può causare problemi del piano di esecuzione poiché il percorso di esecuzione cambia ogni volta che viene eseguita la procedura. Un'alternativa è quella di utilizzare il SELECT ... WHERE nell'istruzione INSERT:

INSERT INTO dbo.Credit (
       CompanyName, 
       PhoneNumber, 
       City, 
       State ) 
SELECT 
       @CompanyName, 
       @PhoneNumber, 
       @City, 
       @State 
WHERE 
       @Type = 1 

INSERT INTO dbo.Debit (
       CompanyName, 
       PhoneNumber, 
       City, 
       State ) 
SELECT 
       @CompanyName, 
       @PhoneNumber, 
       @City, 
       @State 
WHERE 
       @Type = 2 

In questo modo tutto il codice viene sempre eseguito, ma solo quello in cui il @type partite si 'fuoco'

+1

Preferisco questa soluzione perché sembra più pulita e mantiene il piano di esecuzione lo stesso. –

12

È può fare qualcosa di simile a questi:

SET @SQL = CASE @Type 
      WHEN 1 THEN 
        @SQL1 
      WHEN 2 THEN 
        @SQL2 
      ELSE 
        @SQL3 
    END 

EXEC(@SQL) 

UPDATE 9/18/2016

NOTA: Questa è una soluzione facile e veloce, ma mantenere in mente questa non è una soluzione a lungo termine da implementare negli ambienti di produzione. Sono d'accordo con @Jon Galloway: "Non penso che lo CASE sia quello giusto."

Un'altra implementazione più professionale sarà quello di creare 3 diverse stored procedure che fanno il loro lavoro (Responsabilità unico principio), qualcosa di simile:

If @Type = 1 
    EXEC InsertCredit @CompanyName, @PhoneNumber, @City, @State 
Else If @Type = 2 
    EXEC InsertDebit @CompanyName, @PhoneNumber, @City, @State 
Else If @Type = 3 
    EXEC OtherInsert @CompanyName, @PhoneNumber, @City, @State