2013-08-20 18 views
6

Sto facendo comparativo su PostgreSQL rispetto a SQLServer per scopi di migrazione. Ora sto valutando T-SQL vs PL/pgSQL, il fatto è che in T-SQL è possibile utilizzare i loop o dichiarare le variabili, per esempio:PostgreSQL esegue il loop delle funzioni esterne. È possibile?

declare @counter int 
set @counter = 0 
while @counter < 10 
begin 
    set @counter = @counter + 1 
    print 'The counter is ' + cast(@counter as char) 
end 

Non c'è bisogno di metterlo all'interno di una funzione o procedura. Posso farlo in PostgreSQL?

Cercando sul web ho trovato un negative answer facendolo in MySQL ma non ho trovato tale risposta per Postgres.

risposta

15

È non puòDECLARE variabili (globali) (well, there are ways around this) né ciclo con SQL pianura - con l'eccezione di recursive CTEs as provided by @bma.

Tuttavia, c'è lo DO statement per tale codice procedurale ad-hoc. Introdotto con Postgres 9.0. Funziona come una funzione unica, ma non restituisce nulla. È possibile RAISE avvisi et al, così il vostro esempio sarebbe solo funzionare bene:

DO 
$do$ 
DECLARE 
    _counter int := 0; 
BEGIN 
    WHILE _counter < 10 
    LOOP 
     _counter := _counter + 1; 
     RAISE NOTICE 'The counter is %', _counter; -- coerced to text automatically 
    END LOOP; 
END 
$do$ 

Se non specificato altrimenti, il linguaggio del corpo è plpgsql. È tuttavia possibile utilizzare any registered procedural language, se lo si dichiara (come: LANGUAGE plpython).

Postgres offre anche generate_series() per generare set ad-hoc, il che può ovviare alla necessità di eseguire il ciclo in molti casi. Try a search here on SO for examples.

Inoltre, è possibile utilizzare la clausola WHERE in un data-modifying CTE in SQL pianura sborsare casi ed emulare IF .. THEN .. ELSE .. END ...

+0

Risposta impressionante! !! Grazie! – JGutierrezC

+1

Vale la pena ribadire con forza che ** se puoi ri-lanciare il tuo problema in termini di set anziché di loop, fallo ** - cioè, se puoi creare una query SQL che lavori sui risultati in una volta sola, è probabile che funzioni molto meglio del ricorso al codice procedurale. – IMSoP

3

È possibile interrogare in modo ricorsivo i set di risultati utilizzando WITH RECURSIVE, assumendo che si sia in Postgresql 8.4+. Documenti: http://www.postgresql.org/docs/current/static/queries-with.html

Ciò consentirebbe di eseguire il loop del set e elaborare i dati in vari modi.

+0

Grazie mille BMA. Ma posso usare la parola chiave Declare? perché a volte è necessario inserire, ad esempio, o in base a qualche contidizione se la condizione è vera, inserisci altro se ... aggiorna ... altrimenti cancella ... sono chiaro? Cordiali saluti. – JGutierrezC

+2

"Dichiara", no, ma utilizzando la clausola WITH, è possibile inviare un valore in una delle clausole più in alto e fare riferimento più volte nelle posizioni successive della query (noto anche come "concatenamento"). Ad esempio, nel link fornito, la sezione "region_sales" viene utilizzata come origine per la sezione successiva (denominata "top_regions"). Questo illustra il concatenamento di query che ho menzionato. In Postgresql 9.2+, è possibile utilizzare le clausole WITH (note come "Common Table Expressions" (CTE)) per fare "upsert" (che si definisce "insert inf true, else update, else delete") – bma

Problemi correlati