Fluxul de control în T-SQL SP folosind IF..ELSE IF – există și alte modalități? (Programare, Sql, Server Sql, Tsql, Sql Server 2008)

abatishchev a intrebat.
a intrebat.

Am nevoie să îmi ramific fluxul de control al procedurii stocate T-SQL (MS SQL 2008) în mai multe direcții:

CREATE PROCEDURE [fooBar]
   @inputParam INT
AS
BEGIN
  IF @inputParam = 1
  BEGIN
    ...
  END
  ELSE IF @inputParam = 3
  BEGIN
    ...
  END
  ELSE IF @inputParam = 3
  BEGIN
    ...
  END
END

Există și alte modalități? De exemplu, în C# ar trebui să folosesc switch-case bloc.

Comentarii

  • BEGIN/END nu este necesar decât dacă faceți mai multe lucruri în cadrul acelei porțiuni a logicii de decizie. –  > Por OMG Ponei.
  • @rexem: Da, știu. Am scris în mod deliberat acest lucru pentru că fiecare bloc conține o mulțime de cod –  > Por abatishchev.
  • @rexem, ori de câte ori am omis începutul sfârșitului, am regretat-o mai târziu în întreținere când cineva a uitat să le adauge atunci când a adăugat un al doilea pas la ramura IF. Acum le folosesc întotdeauna. –  > Por HLGEM.
  • @HLGEM: Bună observație, nu am avut încă această plăcere 🙂 –  > Por OMG Ponei.
  • Stored procs, pentru a funcționa bine, ar trebui să facă doar o singură sarcină și să minimizeze acest tip de logică condiționată în T-SQL. Un design mai bun este de a face mai multe procs care fac fiecare o singură sarcină și de a decide în aplicație pe care să o apelați. Aceasta este o diferență fundamentală față de limbajele de programare complete. Planurile stocate în memoria cache reprezintă o problemă cu if/then, deși SQL 2008 a făcut unele progrese în ceea ce privește recompilarea la nivel de stadiu. –  > Por onupdatecascade.
6 răspunsuri
Philip Kelley

IF…ELSE… este cam ceea ce avem în T-SQL. Nu există nimic asemănător cu declarația CASE din programarea structurată. Dacă aveți un set extins de …ELSE IF…s cu care să vă ocupați, asigurați-vă că includeți BEGIN…END pentru fiecare bloc pentru a păstra lucrurile clare și amintiți-vă întotdeauna, indentarea consistentă este prietenul vostru!

Comentarii

    16

  • Întotdeauna îmi scriu if-urile și begin și end înainte de a scrie codul care va merge între begin și end, economisește o mulțime de depanare mai târziu pentru a pune în begin ends înainte de orice cod care merge între ele. –  > Por HLGEM.
  • există instrucțiuni case în T-SQL –  > Por shradha.
  • Instrucțiunile case din T-SQL sunt, cum se spune, folosite ca „clauze”, părți ale altor instrucțiuni – cel mai frecvent, instrucțiunile SELECT. Ele nu pot fi folosite pentru a controla fluxul programatic, așa cum se întâmplă în diverse limbaje .NET. –  > Por Philip Kelley.
  • În lumea noastră condusă de copy-paste, ar fi frumos ca acest răspuns să conțină un exemplu real 😉 –  > Por Lukas Eder.
  • Adevărat, dar, întrebarea originală conține un exemplu de if-else if cu begin/end și un alt exemplu ar fi fost redundant. –  > Por Philip Kelley.
JohnDavid

De asemenea, puteți încerca să vă formulați răspunsul sub forma unui SELECT CASE enunț. Ulterior, puteți crea mai târziu simple „if then” care să utilizeze rezultatele dvs. dacă este necesar, după ce ați restrâns posibilitățile.

SELECT @Result =   
CASE @inputParam   
WHEN 1 THEN 1   
WHEN 2 THEN 2   
WHEN 3 THEN 1   
ELSE 4   
END  

IF @Result = 1   
BEGIN  
...  
END  

IF @Result = 2   
BEGIN   
....  
END  

IF @Result = 4   
BEGIN   
//Error handling code   
END   

Stuart Ainsworth

Nu, dar ar trebui să fiți atenți când folosiți IF…ELSE…END IF în procesele stocate. Dacă blocurile de cod sunt radical diferite, este posibil să suferiți de performanțe slabe, deoarece planul procedurii va trebui să fie re-cachetat de fiecare dată. Dacă este vorba de un sistem de înaltă performanță, este posibil să doriți să compilați proceduri stocate separate pentru fiecare bloc de cod și să cereți aplicației să decidă ce procedură să apeleze la momentul potrivit.

Comentarii

  • Acest lucru este foarte adevărat. Dar dacă ramificarea poate avea loc numai în cadrul procedurii (spre deosebire de faptul că aplicația dvs. apelează una dintre mai multe proceduri), rămâneți blocat cu o serie de instrucțiuni IF. –  > Por Philip Kelley.
  • Numele procedurii mele [execOperation] a fost apelat din ASP.NET FormView cu parametru din lista derulantă care conține o listă de tipuri de operațiuni posibile… Deci, nu am posibilitatea de a avea un număr de procs separate, din păcate – –  > Por abatishchev.
Cade Roux
HLGEM

Nope IF este calea de urmat, care este problema pe care o aveți cu utilizarea acestuia?

BTW exemplul tău nu va ajunge niciodată la al treilea bloc de cod, deoarece acesta și al doilea bloc sunt exact la fel.

Pete Michaud
CASE expression
      WHEN value1 THEN result1
      WHEN value2 THEN result2
      ...
      WHEN valueN THEN resultN

      [
        ELSE elseResult
      ]
END

http://www.4guysfromrolla.com/webtech/102704-1.shtml Pentru mai multe informații.

Comentarii

  • Acest lucru se aplică numai pentru interogări. Trebuie să scriu orice în interiorul blocului, adică mai multe linii de cod cu diferite interogări și apeluri ale altor PS –  > Por abatishchev.
  • În T-SQL CASe este un EXPRESIE nu o ramură de control. Bestii foarte diferite. –  > Por Remus Rușanu.
  • Acest lucru este în afara contextului declarației SELECT. –  > Por hoggar.