Come inserisco una "clausola if" in una stringa SQL?


190

Quindi, ecco cosa voglio fare sul mio database MySQL .

Mi piacerebbe fare:

SELECT *
    FROM itemsOrdered
    WHERE purchaseOrder_ID = '@purchaseOrdered_ID'
        AND status = 'PENDING'

Se questo non sarebbe tornato alcuna riga, il che è possibile grazie if(dr.HasRows == false), vorrei ora creare un UPDATEnel purchaseOrderdatabase:

UPDATE purchaseOrder
    SET purchaseOrder_status = 'COMPLETED'
    WHERE purchaseOrder_ID = '@purchaseOrder_ID'

Come potrei rendere questo processo un po 'più breve?


4
Il database ordinato presenta un ID univoco chiamato itemsOrdered_IDe ha purchaseOrder_IDvalori ricorrenti
John Ernest Guadalupe,

1
il purchaseorderdatabase ha invece un ID univocopurchaseOrder_ID
John Ernest Guadalupe,

Risposte:


410

Per la tua query specifica, puoi fare:

UPDATE purchaseOrder
    SET purchaseOrder_status = 'COMPLETED'
    WHERE purchaseOrder_ID = '@purchaseOrder_ID' and
          not exists (SELECT *
                      FROM itemsOrdered WHERE purchaseOrder_ID = '@purchaseOrdered_ID' AND status = 'PENDING'
                     )

Tuttavia, potrei immaginare che stai eseguendo il loop ad un livello superiore. Per impostare tutti questi valori, prova questo:

UPDATE purchaseOrder
    SET purchaseOrder_status = 'COMPLETED'
    WHERE not exists (SELECT 1
                      FROM itemsOrdered
                      WHERE itemsOrdered.purchaseOrder_ID = purchaseOrder.purchaseOrdered_ID AND
                            status = 'PENDING'
                      limit 1
                     )

26
In realtà in MySQL, la sottoquery correlata dovrebbe essere tra gli approcci più efficienti, supponendo che ci sia un indice su itemsOrdered.purchaseOrder_ID.
Gordon Linoff il

8
@eggyal. . . Concordo sul fatto che senza un indice la versione correlata è forse meno performante del join (dipende da vari fattori, come la moltiplicazione delle righe). Con un indice, tuttavia, dovrebbe essere meglio di un join perché dovrebbe interrompere la scansione dell'indice alla prima corrispondenza. Controllare dev.mysql.com/doc/refman/5.5/en/… .
Gordon Linoff,

53

È possibile utilizzare la UPDATEsintassi di più tabelle per effettuare un ANTI-JOINtra purchaseOrdere itemsOrdered:

UPDATE purchaseOrder p LEFT JOIN itemsOrdered i
    ON p.purchaseOrder_ID = i.purchaseOrder_ID
   AND i.status = 'PENDING'
SET    p.purchaseOrder_status = 'COMPLETED'
WHERE  p.purchaseOrder_ID = '@purchaseOrder_ID'
   AND i.purchaseOrder_ID IS NULL

47

Poiché MySQL non supporta if exists(*Your condition*) (*Write your query*), è possibile ottenere una "clausola if" scrivendo in questo modo:

(*Write your insert or update query*) where not exists (*Your condition*)

27

È inoltre possibile utilizzare la seguente query per verificare l'esistenza del record e quindi aggiornarlo:

if not exists(select top 1 fromFROM itemsOrdered
    WHERE purchaseOrder_ID = '@purchaseOrdered_ID'
        AND status = 'PENDING' )
Begin

UPDATE purchaseOrder 
    SET purchaseOrder_status = 'COMPLETED'
    WHERE purchaseOrder_ID = '@purchaseOrder_ID

End

22
Select FROM t1
    WHERE s11 > ANY
        (SELECT col1,col2 FROM t2
            WHERE NOT EXISTS
                (SELECT * FROM t3
                    WHERE ROW(5*t2.s1,77)=
                        (SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM
                            (SELECT * FROM t5) AS t5)));

4
Faccio fatica a vedere come questo risponde alla domanda?
theMayer

1
@theMayer Anche a me ma è una bella risposta
Gabriel

2
Congratulazioni, il tuo codice è stato selezionato come codice offuscato.
Vishwanath Dalvi,

1
Credo che questo è un esempio di che cosa possiamo fare usandoSQL
Top-Master

13
if not exists(select top 1 fromFROM itemsOrdered
    WHERE purchaseOrder_ID = '@purchaseOrdered_ID'
        AND status = 'PENDING' )
Begin

UPDATE purchaseOrder 
    SET purchaseOrder_status = 'COMPLETED'
    WHERE purchaseOrder_ID = '@purchaseOrder_ID

End

7
sarà fantastico se spieghi anche la risposta, le risposte solo in codice non sono utili per i futuri utenti
Kumar Saurabh

8

dopo sql server 2008 provvedere Mergeall'inserimento, all'aggiornamento e all'eliminazione dell'operazione in base alla singola istruzione di corrispondenza, che consente anche di partecipare. esempio di seguito potrebbe essere di aiuto.

MERGE Target AS T
USING Source AS S
ON (T.EmployeeID = S.EmployeeID) 
WHEN NOT MATCHED BY TARGET AND S.EmployeeName LIKE 'S%' 
    THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName)
WHEN MATCHED 
    THEN UPDATE SET T.EmployeeName = S.EmployeeName
WHEN NOT MATCHED BY SOURCE AND T.EmployeeName LIKE 'S%'
    THEN DELETE 
OUTPUT $action, inserted.*, deleted.*;

in questo modo è possibile inserire, aggiornare ed eliminare in una sola istruzione.

e per ulteriori informazioni è possibile fare riferimento ai documenti ufficiali su https://technet.microsoft.com/en-us/library/bb522522(v=sql.105).aspx


7

Se la tabella contiene milioni di record, la seguente query funzionerà rapidamente.

UPDATE PO
SET PO.purchaseOrder_status = 'COMPLETED'
FROM purchaseOrder PO
LEFT OUTER JOIN itemsOrdered IOD ON IOD.purchaseOrder_ID = PO.purchaseOrdered_ID and IOD.status = 'PENDING'
WHERE IOD.purchaseOrder_ID IS NULL

1

È possibile dichiarare una variabile che contiene il numero di risultati restituiti nella query di selezione. È quindi possibile eseguire l'istruzione update se questa variabile è maggiore di 0

    Declare @ResultCount int
    SELECT @ResultCount = count(*) FROM itemsOrdered WHERE purchaseOrder_ID = '@purchaseOrdered_ID' AND status = 'PENDING'        
    If @ResultCount > 0
UPDATE purchaseOrder SET purchaseOrder_status = 'COMPLETED' WHERE purchaseOrder_ID = '@purchaseOrder_ID'        
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.