Como faço para colocar uma 'cláusula if' em uma string SQL?

190

Então, aqui está o que eu quero fazer no meu banco de dados MySQL .

Eu gostaria de fazer:

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

Se isso não retornasse nenhuma linha, o que é possível if(dr.HasRows == false), agora criaria um UPDATEno purchaseOrderbanco de dados:

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

Como eu seria capaz de tornar esse processo um pouco mais curto?

John Ernest Guadalupe
fonte
4
o banco de dados itemsOrdered tem um ID exclusivo chamado itemsOrdered_IDe possui purchaseOrder_IDvalores recorrentes
John Ernest Guadalupe
1
o purchaseorderbanco de dados, por outro lado, tem o ID exclusivopurchaseOrder_ID
John Ernest Guadalupe

Respostas:

410

Para sua consulta específica, você pode:

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'
                     )

No entanto, acho que você está fazendo um loop em um nível superior. Para definir todos esses valores, tente o seguinte:

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
                     )
Gordon Linoff
fonte
26
Atualmente, no MySQL, a subconsulta correlacionada deve estar entre as abordagens mais eficientes, assumindo que exista um índice em itemsOrdered.purchaseOrder_ID.
Gordon Linoff
8
@eggyal. . . Concordo que, sem um índice, a versão correlacionada talvez tenha menos desempenho que a junção (depende de vários fatores, como multiplicação de linhas). No entanto, com um índice, ele deve ser melhor que uma associação, pois deve interromper a verificação do índice na primeira correspondência. Verifique dev.mysql.com/doc/refman/5.5/en/… .
Gordon Linoff
53

Você pode usar a UPDATEsintaxe de várias tabelas para efetuar um ANTI-JOINentre 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
eggyal
fonte
47

Como o MySQL não suporta if exists(*Your condition*) (*Write your query*), você pode obter uma 'cláusula if' escrevendo assim:

(*Write your insert or update query*) where not exists (*Your condition*)
Ranjit Singh
fonte
27

Você também pode usar a seguinte consulta para verificar se o registro existe e depois atualizá-lo:

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
Santosh Shirkar
fonte
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)));
sikandar bakht syed
fonte
4
Estou lutando para ver como isso responde à pergunta?
theMayer 3/03/16
1
@theMayer Eu também, mas é uma resposta bastante agradável
Gabriel
2
Parabéns, seu código foi selecionado como um código ofuscado.
Vishwanath Dalvi
1
Eu acho que este é um exemplo do que mais podemos fazer 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
CH Hamza Ahmad
fonte
7
vai ser ótimo se u explicar a resposta também, código únicas respostas não são úteis para os futuros usuários
Kumar Saurabh
9

após o sql server 2008 fornecer Mergepara inserir, atualizar e excluir a operação com base na instrução de correspondência única, também que permite que você participe. exemplo abaixo pode ser de ajuda.

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.*;

assim você pode inserir, atualizar e excluir em uma instrução.

e para obter mais informações, consulte documentos oficiais em https://technet.microsoft.com/en-us/library/bb522522(v=sql.105).aspx

Lalji Dhameliya
fonte
7

Se a tabela contiver milhões de registros, a consulta a seguir funcionará 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
Amit Prajapati
fonte
1

Você pode declarar uma variável que contém o número de resultados retornados na consulta selecionada. Você pode executar a instrução update se essa variável for maior que 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'        
Alireza
fonte