diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml new file mode 100644 index 158d9d2..aee8264 *** a/doc/src/sgml/plpgsql.sgml --- b/doc/src/sgml/plpgsql.sgml *************** EXECUTE 'SELECT count(*) FROM ' *** 1222,1227 **** --- 1222,1234 ---- INTO c USING checked_user, checked_date; + A cleaner approach is to use format()'s %I + specification for table or column names: + + EXECUTE format('SELECT count(*) FROM %I WHERE inserted_by = $1 AND inserted <= $2', tabname) + INTO c + USING checked_user, checked_date; + Another restriction on parameter symbols is that they only work in SELECT, INSERT, UPDATE, and DELETE commands. In other statement *************** EXECUTE 'SELECT count(*) FROM ' *** 1297,1307 **** ! Dynamic values that are to be inserted into the constructed ! query require careful handling since they might themselves contain quote characters. ! An example (this assumes that you are using dollar quoting for the ! function as a whole, so the quote marks need not be doubled): EXECUTE 'UPDATE tbl SET ' || quote_ident(colname) --- 1304,1317 ---- ! Dynamic values require careful handling since they might contain quote characters. ! An example using format() (this assumes that you are ! dollar quoting the function body so quote marks need not be doubled): ! ! EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) USING newvalue, keyvalue; ! ! It is also possible to call the quoting functions directly: EXECUTE 'UPDATE tbl SET ' || quote_ident(colname) *************** EXECUTE 'UPDATE tbl SET ' *** 1393,1407 **** EXECUTE format('UPDATE tbl SET %I = %L WHERE key = %L', colname, newvalue, keyvalue); The format function can be used in conjunction with the USING clause: EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) USING newvalue, keyvalue; ! This form is more efficient, because the parameters ! newvalue and keyvalue are not ! converted to text. --- 1403,1419 ---- EXECUTE format('UPDATE tbl SET %I = %L WHERE key = %L', colname, newvalue, keyvalue); + %I is equivalent to quote_ident, and + %L is equivalent to quote_nullable. The format function can be used in conjunction with the USING clause: EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) USING newvalue, keyvalue; ! This form is better because the variables are handled in their native ! data type format, rather than unconditionally converting them to ! text and quoting them via %L. It is also more efficient. *************** BEGIN *** 2352,2361 **** -- Now "mviews" has one record from cs_materialized_views RAISE NOTICE 'Refreshing materialized view %s ...', quote_ident(mviews.mv_name); ! EXECUTE 'TRUNCATE TABLE ' || quote_ident(mviews.mv_name); ! EXECUTE 'INSERT INTO ' ! || quote_ident(mviews.mv_name) || ' ' ! || mviews.mv_query; END LOOP; RAISE NOTICE 'Done refreshing materialized views.'; --- 2364,2371 ---- -- Now "mviews" has one record from cs_materialized_views RAISE NOTICE 'Refreshing materialized view %s ...', quote_ident(mviews.mv_name); ! EXECUTE format('TRUNCATE TABLE %I', mviews.mv_name); ! EXECUTE format('INSERT INTO %I %s', mviews.mv_name, mviews.mv_query); END LOOP; RAISE NOTICE 'Done refreshing materialized views.'; *************** OPEN unbound_cursorvar), and it also means that variable substitution is not done on the command string. As with EXECUTE, parameter values ! can be inserted into the dynamic command via USING. The SCROLL and NO SCROLL options have the same meanings as for a bound cursor. --- 2978,2985 ---- from one run to the next (see ), and it also means that variable substitution is not done on the command string. As with EXECUTE, parameter values ! can be inserted into the dynamic command via ! format() and USING. The SCROLL and NO SCROLL options have the same meanings as for a bound cursor. *************** OPEN unbound_cursorvar An example: ! OPEN curs1 FOR EXECUTE 'SELECT * FROM ' || quote_ident(tabname) ! || ' WHERE col1 = $1' USING keyvalue; ! In this example, the table name is inserted into the query textually, ! so use of quote_ident() is recommended to guard against ! SQL injection. The comparison value for col1 is inserted ! via a USING parameter, so it needs no quoting. --- 2988,2999 ---- An example: ! OPEN curs1 FOR EXECUTE format('SELECT * FROM %I WHERE col1 = $1',tabname) USING keyvalue; ! In this example, the table name is inserted into the query via ! format(). The comparison value for col1 ! is inserted via a USING parameter, so it needs ! no quoting.