35.7. ���ƽṹ

���ƽṹ������ PL/pgSQL �������õģ��Լ�����Ҫ���IJ����ˡ� ���� PL/pgSQL �Ŀ��ƽṹ�� ������Էdz�������ǿ��ķ������� PostgreSQL �����ݡ�

35.7.1. �Ӻ�������

������������������Ӻ����з������ݣ�RETURN �� RETURN NEXT��

35.7.1.1. RETURN

RETURN expression;

�����ʽ�� RETURN ��������ֹ����, Ȼ�� expression ��ֵ���ظ������ߡ�

������ر������ͣ���ô����ʹ���κα��ʽ�����ʽ�����ͽ����Զ�ת���ɺ����ķ������ͣ� ���������ڸ�ֵ�������������� Ҫ����һ�����ϣ��У���ֵ�������дһ����¼�����б����� expression��

һ�������ķ���ֵ������δ���塣������Ƶ����˺��������Ŀ��û������һ�� RETURN ��䣬 ��ô���ͻᷢ��һ������

��ע������������˸ú������� void����ô��Ȼ�������� RETURN ��䣻���ǣ����� RETURN ����ı��ʽ�ǿ�ѡ�ģ��������κ�����¶��ᱻ���ԡ�

35.7.1.2. RETURN NEXT

RETURN NEXT expression;

���һ�� PL/pgSQL ��������Ϊ���� SETOF sometype�� ��ô��ѭ�Ĺ��������в�ͬ������������£�Ҫ���صĶ����������� RETURN NEXT �����������ģ�Ȼ�������һ������������ RETURN �������ڸ���������������Ѿ����ִ���ˡ� RETURN NEXT �������ڱ����͸����������ͣ����ں��ߣ�������һ�������Ľ��"��"��

ʹ�� RETURN NEXT �ĺ���Ӧ�ð�������ķ����ã�

SELECT * FROM some_func();

Ҳ����˵���������������FROM�Ӿ������һ��������Դ�ġ�

RETURN NEXT ʵ���ϲ����Ӻ����з��أ� ��ֻ�Ǽ򵥵ذѱ��ʽ��ֵ���������� Ȼ��ִ�м���ִ�� PL/pgSQL ���������һ����䡣 ���ź�̵� RETURN NEXT �����ִ�У� ������ͽ��������ˡ�����һ������Ҫ������ RETURN�� ���¿����˳��ú�����

ע��: Ŀǰ�� PL/pgSQL �� RETURN NEXT ʵ���ڴӺ�������֮ǰ������������������������������������������� ����ζ�����һ�� PL/pgSQL ��������һ���dz���Ľ������ ���ܿ��ܻ�ܲ���ݽ���д���������Ա����ڴ�ľ��� ���Ǻ�����������������������֮ǰ�����˳��������� PL/pgSQL �汾���ܻ������û�����û���������Ƶķ��ؼ��ϵĺ����� Ŀǰ�����ݿ�ʼ�������д��ʱ���������ñ��� work_mem ���Ƶġ� ӵ���㹻�ڴ�Ĺ���Ա��������ڴ���洢����Ľ������ ����Կ��ǰ������������һЩ��

35.7.2. ����

IF ���������Ը���ij������ִ����� PL/pgSQL��������ʽ��IF��

35.7.2.1. IF-THEN

IF boolean-expression THEN
    statements
END IF;

IF-THEN�����IF�������ʽ���������Ϊ�棬 ��THEN��END IF֮�����佫��ִ�С� ���򣬽��������ǡ�

���ӣ�

IF v_user_id <> 0 THEN
    UPDATE users SET email = v_email WHERE user_id = v_user_id;
END IF;

35.7.2.2. IF-THEN-ELSE

IF boolean-expression THEN
    statements
ELSE
    statements
END IF;

IF-THEN-ELSE���������IF-THEN�ķ�֧�� �����������������������Ϊ�ٵ�ʱ��ִ�е���䡣

���ӣ�

IF parentid IS NULL OR parentid = ''
THEN 
    RETURN fullname;
ELSE
    RETURN hp_true_filename(parentid) || '/' || fullname;
END IF;

IF v_count > 0 THEN 
    INSERT INTO users_count(count) VALUES(v_count);
    RETURN 't';
ELSE 
    RETURN 'f';
END IF;

35.7.2.3. IF-THEN-ELSE IF

IF������Ƕ�ײ���������������У�

IF demo_row.sex = 'm' THEN
  pretty_sex := 'man';
ELSE
  IF demo_row.sex = 'f' THEN
    pretty_sex := 'woman';
  END IF;
END IF;

�����ʹ��������ʽ����ô��ʵ���Ͼ���������һ��IF����ELSE ����Ƕ����һ��IF��䣮�������Ҫһ��END IF��� ��ÿ��Ƕ�׵�IF�����⻹Ҫһ������IF-ELSE�ã� ��ô���ǿ��Եģ��������������̫���ѡ����Ҫ��飬��ô�ͻ��úܷ�ζ�� ������������ʽ��

35.7.2.4. IF-THEN-ELSIF-ELSE

IF boolean-expression THEN
    statements
[ ELSIF boolean-expression THEN
    statements
[ ELSIF boolean-expression THEN
    statements
    ...]]
[ ELSE
    statements ]
END IF;

IF-THEN-ELSIF-ELSE�ṩ��һ�ָ�����ķ���������һ������м������ѡ������ ��ʽ������Ƕ�׵�IF-THEN-ELSE-IF-THEN������ͬ�� ����ֻ��Ҫһ��END IF��

������һ�����ӣ�

IF number = 0 THEN
    result := 'zero';
ELSIF number > 0 THEN
    result := 'positive';
ELSIF number < 0 THEN
    result := 'negative';
ELSE
    -- ����һ��Ψһ�Ŀ��������ǿ�ֵ
    result := 'NULL';
END IF;

35.7.2.5. IF-THEN-ELSEIF-ELSE

ELSEIF �� ELSIF �ı�����

35.7.3. ��ѭ��

ʹ��LOOP��WHILE��FOR �� EXIT ��䣬����Կ������ PL/pgSQL �����ظ�һϵ�����

35.7.3.1. LOOP

[<<label>>]
LOOP
    statements
END LOOP;

LOOP ����һ����������ѭ��������ѭ����ֱ����EXIT����RETURN�����ֹ�� ��ѡ�ı�ǩ������EXIT���ʹ�ã�������Ƕ��ѭ��������Ӧ�ý�����һ��ѭ����

35.7.3.2. EXIT

EXIT [ label ] [ WHEN expression ];

���û�и��� label�� ��ô�˳����ڲ��ѭ����Ȼ��ִ�и���END LOOP�������䡣 ������� label�� ��ô�������ǵ�ǰ���߸��߲��Ƕ��ѭ������߿�ı�ǩ�� Ȼ������������ѭ���ͻ���ֹ���������䵽��Ӧѭ��/��� END �����������ϡ�

���������WHEN��ѭ���˳�ֻ����������������Ϊ���ʱ�� ������ƻ��䵽EXIT���������ϡ�

EXIT �������������е�ѭ����������ǰ�˳��� ��������������������ѭ����ʹ�á�

���ӣ�

LOOP
    -- һЩ����
    IF count > 0 THEN
        EXIT;  -- exit loop
    END IF;
END LOOP;

LOOP
    -- һЩ����
    EXIT WHEN count > 0;
END LOOP;

BEGIN
    -- һЩ����
    IF stocks > 100000 THEN
        EXIT;  -- ���´� BEGIN �����˳�
    END IF;
END;

35.7.3.3. WHILE

[<<label>>]
WHILE expression LOOP
    statements
END LOOP;

ֻҪ�������ʽΪ�棬WHILE���ͻ᲻ͣ��һϵ������Ͻ���ѭ��. ��������ÿ�ν���ѭ�����ʱ�����.

����:

WHILE amount_owed > 0 AND gift_certificate_balance > 0 LOOP
    -- ����������������
END LOOP;

WHILE NOT BOOLEAN_expression LOOP
    -- ����������������
END LOOP;

35.7.3.4. FOR ���������֣�

[<<label>>]
FOR name IN [ REVERSE ] expression .. expression LOOP
    statements
END LOOP;

������ʽ��FOR��һ����Χ��������ֵ���е�����ѭ���� ����name ���Զ�����Ϊinteger���Ͳ���ֻ��ѭ������ڡ� ������Χ���½���������ʽ�ڽ���ѭ����ʱ�����һ�Ρ� ��������ֵ����Ϊ 1�������������REVERSE���� -1��

һЩ����FORѭ�������ӡ�

FOR i IN 1..10 LOOP
  -- ������Է�һЩ���ʽ
    RAISE NOTICE 'i IS %', i;
END LOOP;

FOR i IN REVERSE 10..1 LOOP
    -- ������Է�һЩ���ʽ
END LOOP;

����½�����Ͻ磨�������� REVERSE �������С�ڣ�����ôѭ���彫��ȫ����ִ�С� ���Ҳ����׳��κδ���

35.7.4. ����������

ʹ�ò�ͬ���͵�FORѭ��������Ա���һ������Ľ��������Ӧ�IJ�����Щ���ݡ��﷨�ǣ�

[<<label>>]
FOR record_or_row IN query LOOP
    statements
END LOOP;

����ļ�¼�����б�������̱�������������query��������һ�� SELECT ������У� ����ѭ���彫Ϊÿ��ִ��һ�Ρ�������һ�����ӣ�

CREATE FUNCTION cs_refresh_mviews() RETURNS integer AS $$
DECLARE
     mviews RECORD;

BEGIN
     PERFORM cs_log('Refreshing materialized views...');

     FOR mviews IN SELECT * FROM cs_materialized_views ORDER BY sort_key LOOP

         -- ���� "mviews" ������һ������ cs_materialized_views �ļ�¼

        PERFORM cs_log('Refreshing materialized view ' || quote_ident(mviews.mv_name) || ' ...');
        EXECUTE 'TRUNCATE TABLE ' || quote_ident(mviews.mv_name);
        EXECUTE 'INSERT INTO  ' ||  quote_ident(mview.mv_name) || ' ' || mview.mv_query;
     END LOOP;

     PERFORM cs_log('Done refreshing materialized views.');
     RETURN 1;
END;
$$ LANGUAGE plpgsql;

���ѭ������һ��EXIT�����ֹ�ģ���ô��ѭ��֮������Ȼ���Է������ֵ���С�

FOR-IN-EXECUTE����DZ��������е�����һ�ַ�����

[<<label>>]
FOR record_or_row IN EXECUTE text_expression LOOP
    statements
END LOOP;

�����������ǰ�����ʽ��ֻ����ԴSELECT�������Ϊ��һ���ִ����ʽ�� ��������ÿ�ν���FORѭ����ʱ�򶼻����¼��������ִ�мƻ��� �������������Ա��һ��Ԥ�ȹ滮���˵���������õ��ٶȣ���һ����̬��������õ�����ԣ�����һ���򵥵�EXECUTE���������֮�����ѡ��

ע��: PL/pgSQL ������Ŀǰ�����������͵�FORѭ�����������߷��ؼ�¼�ģ��� �����Ǽ���Ƿ����κ� .. ������ IN �� LOOP ֮���Բ����֮�⡣ ���û�п��� ..����ô���ѭ���������������ϵ�ѭ���� ��������� .. �ͺܿ��ܻᵼ�������������Ĵ�����Ϣ�� "loop variable of loop over rows must be a record or row variable"�� ������������Ϊ�ῴ���ļ򵥵��﷨����

35.7.5. �������

ȱʡʱ��һ���� PL/pgSQL �����﷢���Ĵ����˳�������ִ�У� ����ʵ����������Χ������Ҳ���˳��������ʹ��һ������ EXCEPTION �Ӿ�� BEGIN �鲶������Ҵ��лָ��� ���﷨�������� BEGIN ���﷨��һ����չ��

[ <<label>> ]
[ DECLARE
    declarations ]
BEGIN
    statements
EXCEPTION
    WHEN condition [ OR condition ... ] THEN
        handler_statements
    [ WHEN condition [ OR condition ... ] THEN
          handler_statements
      ... ]
END;

���û�з�������������ʽ�Ŀ�ֻ�Ǽ򵥵�ִ������ statements�� ��������� statements �﷢����һ������ ��� statements �Ľ�һ������������ ���ƴ��ݵ��� EXCEPTION �б� ϵͳ��������б�Ѱ��ƥ�䷢���Ĵ���ĵ�һ��Ԫ�ء�����ҵ�ƥ�䣬 ��ִ�ж�Ӧ�� handler_statements��Ȼ����ƴ��ݵ� END ֮�����һ����䡣 ���û���ҵ�ƥ�䣬�ô���ͻ�㲥��ȥ���ͺ������û�� EXCEPTION �Ӿ�һ���� �ô�����Ա�һ����Χ���� EXCEPTION �������û�а�Χ�飬���˳������Ĵ���

condition ���ֿ����� Appendix A ����ʾ���κ����֡� һ��������ƥ������÷�����Ĵ�������������� OTHERS ƥ����� QUERY_CANCELED ֮������д������͡� �����ǿ��������ֲ��� QUERY_CANCELED������ͨ���Dz����ǵġ����������Ǵ�Сд�޹صġ�

�����ѡ�е� handler_statements �﷢�����´��� ��ô�����ܱ���� EXCEPTION �Ӿ䲶�񣬶��Ǵ�����ȥ�� һ������ EXCEPTION �Ӿ���Բ�������

���һ������ EXCEPTION ����PL/pgSQL �����ľֲ��������ִ�������ʱ���ԭֵ�� �������иÿ�����̻������ݿ��е�״̬���ع�����Ϊһ�����ӣ������ǿ�������Ƭ�ϣ�

    INSERT INTO mytab(firstname, lastname) VALUES('Tom', 'Jones');
    BEGIN
        UPDATE mytab SET firstname = 'Joe' WHERE lastname = 'Jones';
        x := x + 1;
        y := x / 0;
    EXCEPTION
        WHEN division_by_zero THEN
            RAISE NOTICE 'caught division_by_zero';
            RETURN x;
    END;

�����Ƶ���� y ��ֵ�ĵط���ʱ���������һ�� division_by_zero ����ʧ�ܡ� ������󽫱� EXCEPTION �Ӿ䲶�񡣶��� RETURN ����ﷵ�ص���ֵ���� x ������ֵ�� ���ǣ��ڸÿ�֮ǰ�� INSERT ������ع���������յĽ�������ݿ���� Tom Jones �� ���� Joe Jones��

��ʾ: ������˳�һ������ EXCEPTION �Ӿ�Ŀ�Ҫ�Ȳ������Ŀ鿪����Ķࡣ ��ˣ�����Ҫ��ʱ��Ҫʹ�� EXCEPTION��