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

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.

主站蜘蛛池模板: 顺昌县| 文成县| 汪清县| 自贡市| 威远县| 资源县| 禄丰县| 通城县| 沈丘县| 土默特右旗| 龙井市| 肃南| 安龙县| 藁城市| 肇庆市| 宁国市| 罗甸县| 团风县| 广西| 茶陵县| 噶尔县| 宁安市| 登封市| 新平| 遂川县| 郧西县| 安仁县| 策勒县| 榆林市| 昆山市| 巴南区| 大荔县| 航空| 河南省| 仙居县| 湖南省| 沙洋县| 大足县| 会东县| 万宁市| 巨野县|