官术网_书友最值得收藏!

The FOUND Global Variable

When the top-level code block begins, PL/pgSQL declares a global variable named FOUND, which allows for a quick check of the status of the last SQL statement executed. The FOUND variable is of Boolean type and is set to true if the last statement succeeds, or, in other words, if at least one row was processed by the statement. As an example, Listing 38 shows a very simple check to see if the files table is empty or not. The table is read via PERFORM and, if at least one row is found, the FOUND Boolean variable is implicitly set to true:

testdb=> DO $code$
BEGIN
PERFORM pk FROM files;
IF FOUND THEN
RAISE DEBUG 'The files tables contain some data';

END IF;
END $code$;

DEBUG: The files tables contain some data
Listing 38:  A simple use of FOUND

The FOUND variable is defined with a false value and is turned to true only when:

  • SELECT INTO is assigned a row value
  • PERFORM throws away at least one tuple
  • INSERT, UPDATE, or DELETE affects at least one tuple
  • FOR or FOREACH has iterated at least once
  • A cursor has found a next tuple.

Please note that the FOUND variable is set after any of these statements have been executed. Listing 39 shows a possible work-flow to better explain the possible values. As you can see, FOUND begins with a false value. Entering the FOR iteration does not change its value, even if one or more tuples have been extracted from the iteration query. The FOUND value will be changed at the end of the statement, which, in this case, is the FOR loop itself. Within the FOR loop, one PERFORM is fails and one succeeds, making the values of FOUND change after each statement. The last PERFORM executed in the loop fails, giving FOUND a false value. Once the FOR loop completes, however, the value is changed to true, because FOR has iterated at least once:

testdb=> DO $code$
DECLARE
current_record record;
BEGIN
RAISE DEBUG 'In the beginning FOUND = %', FOUND;
FOR current_record IN SELECT * FROM files LIMIT 3 LOOP
RAISE DEBUG 'While iterating FOUND = %', FOUND;
IF current_record.pk % 2 = 0 THEN
-- this statement will fail
PERFORM pk FROM files
WHERE f_hash = 'FAIL' || current_record.f_hash;
RAISE DEBUG 'After a failing statement FOUND = %', FOUND;
ELSE
-- this statement will succeed
PERFORM pk FROM files
WHERE f_hash = current_record.f_hash;
RAISE DEBUG 'After a succeeding statement FOUND = %', FOUND;
END IF;
END LOOP;
RAISE DEBUG 'Outside the loop FOUND = %', FOUND;
END $code$;

DEBUG: In the beginning FOUND = f
DEBUG: While iterating FOUND = f
DEBUG: After a failing statement FOUND = f
DEBUG: While iterating FOUND = f
DEBUG: After a succeeding statement FOUND = t
DEBUG: While iterating FOUND = t
DEBUG: After a failing statement FOUND = f
DEBUG: Outside the loop FOUND = t
Listing 39: FOUND values changes

The FOUND variable is global across nested code blocks. This means a nested block will not redefine FOUND with a false value, but will instead keep the outer block value. As you can imagine, FOUND can be masked by an explicit declaration of a variable of the same name, but this will throw away the capability to test the result of an SQL statement that has just been executed.

主站蜘蛛池模板: 桃园市| 通山县| 同心县| 赣榆县| 定襄县| 阿拉善右旗| 阿拉尔市| 涞源县| 苗栗县| 平武县| 社旗县| 锡林郭勒盟| 东乡| 精河县| 丽江市| 鲁山县| 陈巴尔虎旗| 乌鲁木齐县| 吕梁市| 蒙阴县| 怀来县| 建昌县| 烟台市| 太和县| 崇礼县| 江阴市| 个旧市| 西城区| 嫩江县| 谷城县| 新晃| 开化县| 台前县| 新兴县| 岳普湖县| 深泽县| 克山县| 万安县| 拜城县| 临安市| 张北县|