3
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
4
<title>36.5.ļæ½Database Access from PL/Tcl</title>
5
<link rel="stylesheet" href="stylesheet.css" type="text/css">
6
<link rev="made" href="pgsql-docs@postgresql.org">
7
<meta name="generator" content="DocBook XSL Stylesheets V1.64.1">
8
<link rel="home" href="index.html" title="PostgreSQL 8.0.0beta5 Documentation">
9
<link rel="up" href="pltcl.html" title="Chapterļæ½36.ļæ½PL/Tcl - Tcl Procedural Language">
10
<link rel="previous" href="pltcl-global.html" title="36.4.ļæ½Global Data in PL/Tcl">
11
<link rel="next" href="pltcl-trigger.html" title="36.6.ļæ½Trigger Procedures in PL/Tcl">
13
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="sect1" lang="en">
14
<div class="titlepage">
15
<div><div><h2 class="title" style="clear: both">
16
<a name="pltcl-dbaccess"></a>36.5.ļæ½Database Access from PL/Tcl</h2></div></div>
19
<p> The following commands are available to access the database from
20
the body of a PL/Tcl function:
23
<div class="variablelist"><dl>
24
<dt><span class="term"><tt class="literal"><tt class="function">spi_exec</tt>
25
?<span class="optional">-count <i class="replaceable"><tt>n</tt></i></span>?
27
?<span class="optional">-array <i class="replaceable"><tt>name</tt></i></span>?
28
<i class="replaceable"><tt>command</tt></i>
29
?<span class="optional"><i class="replaceable"><tt>loop-body</tt></i></span>?
32
<p> Executes an SQL command given as a string. An error in the command
33
causes an error to be raised. Otherwise, the return value of <tt class="function">spi_exec</tt>
34
is the number of rows processed (selected, inserted, updated, or
35
deleted) by the command, or zero if the command is a utility
36
statement. In addition, if the command is a <tt class="command">SELECT</tt> statement, the
37
values of the selected columns are placed in Tcl variables as
40
<p> The optional <tt class="literal">-count</tt> value tells
41
<tt class="function">spi_exec</tt> the maximum number of rows
42
to process in the command. The effect of this is comparable to
43
setting up a query as a cursor and then saying <tt class="literal">FETCH <i class="replaceable"><tt>n</tt></i></tt>.
45
<p> If the command is a <tt class="command">SELECT</tt> statement, the values of the
46
result columns are placed into Tcl variables named after the columns.
47
If the <tt class="literal">-array</tt> option is given, the column values are
48
instead stored into the named associative array, with the
49
column names used as array indexes.
51
<p> If the command is a <tt class="command">SELECT</tt> statement and no <i class="replaceable"><tt>loop-body</tt></i>
52
script is given, then only the first row of results are stored into
53
Tcl variables; remaining rows, if any, are ignored. No storing occurs
55
query returns no rows. (This case can be detected by checking the
56
result of <tt class="function">spi_exec</tt>.) For example,
59
<pre class="programlisting">spi_exec "SELECT count(*) AS cnt FROM pg_proc"</pre>
62
will set the Tcl variable <tt class="literal">$cnt</tt> to the number of rows in
63
the <tt class="structname">pg_proc</tt> system catalog.
65
<p> If the optional <i class="replaceable"><tt>loop-body</tt></i> argument is given, it is
66
a piece of Tcl script that is executed once for each row in the
67
query result. (<i class="replaceable"><tt>loop-body</tt></i> is ignored if the given
68
command is not a <tt class="command">SELECT</tt>.) The values of the current row's columns
69
are stored into Tcl variables before each iteration. For example,
72
<pre class="programlisting">spi_exec -array C "SELECT * FROM pg_class" {
73
elog DEBUG "have table $C(relname)"
77
will print a log message for every row of <tt class="literal">pg_class</tt>. This
78
feature works similarly to other Tcl looping constructs; in
79
particular <tt class="literal">continue</tt> and <tt class="literal">break</tt> work in the
80
usual way inside the loop body.
82
<p> If a column of a query result is null, the target
83
variable for it is “<span class="quote">unset</span>” rather than being set.
86
<dt><span class="term"><tt class="function">spi_prepare</tt> <i class="replaceable"><tt>query</tt></i> <i class="replaceable"><tt>typelist</tt></i></span></dt>
88
<p> Prepares and saves a query plan for later execution. The
89
saved plan will be retained for the life of the current
90
session.<a name="id2651635"></a>
92
<p> The query may use parameters, that is, placeholders for
93
values to be supplied whenever the plan is actually executed.
94
In the query string, refer to parameters
95
by the symbols <tt class="literal">$1</tt> ... <tt class="literal">$<i class="replaceable"><tt>n</tt></i></tt>.
96
If the query uses parameters, the names of the parameter types
97
must be given as a Tcl list. (Write an empty list for
98
<i class="replaceable"><tt>typelist</tt></i> if no parameters are used.)
99
Presently, the parameter types must be identified by the internal
100
type names shown in the system table <tt class="literal">pg_type</tt>; for example <tt class="literal">int4</tt> not
101
<tt class="literal">integer</tt>.
103
<p> The return value from <tt class="function">spi_prepare</tt> is a query ID
104
to be used in subsequent calls to <tt class="function">spi_execp</tt>. See
105
<tt class="function">spi_execp</tt> for an example.
108
<dt><span class="term"><tt class="literal"><tt class="function">spi_execp</tt>
109
?<span class="optional">-count <i class="replaceable"><tt>n</tt></i></span>?
111
?<span class="optional">-array <i class="replaceable"><tt>name</tt></i></span>?
113
?<span class="optional">-nulls <i class="replaceable"><tt>string</tt></i></span>?
114
<i class="replaceable"><tt>queryid</tt></i>
115
?<span class="optional"><i class="replaceable"><tt>value-list</tt></i></span>?
117
?<span class="optional"><i class="replaceable"><tt>loop-body</tt></i></span>?
120
<p> Executes a query previously prepared with <tt class="function">spi_prepare</tt>.
121
<i class="replaceable"><tt>queryid</tt></i> is the ID returned by
122
<tt class="function">spi_prepare</tt>. If the query references parameters,
123
a <i class="replaceable"><tt>value-list</tt></i> must be supplied. This
124
is a Tcl list of actual values for the parameters. The list must be
125
the same length as the parameter type list previously given to
126
<tt class="function">spi_prepare</tt>. Omit <i class="replaceable"><tt>value-list</tt></i>
127
if the query has no parameters.
129
<p> The optional value for <tt class="literal">-nulls</tt> is a string of spaces and
130
<tt class="literal">'n'</tt> characters telling <tt class="function">spi_execp</tt>
131
which of the parameters are null values. If given, it must have exactly the
132
same length as the <i class="replaceable"><tt>value-list</tt></i>. If it
133
is not given, all the parameter values are nonnull.
135
<p> Except for the way in which the query and its parameters are specified,
136
<tt class="function">spi_execp</tt> works just like <tt class="function">spi_exec</tt>.
137
The <tt class="literal">-count</tt>, <tt class="literal">-array</tt>, and
138
<i class="replaceable"><tt>loop-body</tt></i> options are the same,
139
and so is the result value.
141
<p> Here's an example of a PL/Tcl function using a prepared plan:
144
<pre class="programlisting">CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$
145
if {![ info exists GD(plan) ]} {
146
# prepare the saved plan on the first call
147
set GD(plan) [ spi_prepare \
148
"SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \
151
spi_execp -count 1 $GD(plan) [ list $1 $2 ]
153
$$ LANGUAGE pltcl;</pre>
156
We need backslashes inside the query string given to
157
<tt class="function">spi_prepare</tt> to ensure that the
158
<tt class="literal">$<i class="replaceable"><tt>n</tt></i></tt> markers will be passed
159
through to <tt class="function">spi_prepare</tt> as-is, and not replaced by Tcl
160
variable substitution.
164
<dt><span class="term"><tt class="function">spi_lastoid</tt></span></dt>
165
<dd><p> Returns the OID of the row inserted by the last
166
<tt class="function">spi_exec</tt> or <tt class="function">spi_execp</tt>,
167
if the command was a single-row <tt class="command">INSERT</tt>. (If not, you get zero.)
169
<dt><span class="term"><tt class="function">quote</tt> <i class="replaceable"><tt>string</tt></i></span></dt>
171
<p> Doubles all occurrences of single quote and backslash characters
172
in the given string. This may be used to safely quote strings
173
that are to be inserted into SQL commands given
174
to <tt class="function">spi_exec</tt> or
175
<tt class="function">spi_prepare</tt>.
176
For example, think about an SQL command string like
179
<pre class="programlisting">"SELECT '$val' AS ret"</pre>
182
where the Tcl variable <tt class="literal">val</tt> actually contains
183
<tt class="literal">doesn't</tt>. This would result
184
in the final command string
187
<pre class="programlisting">SELECT 'doesn't' AS ret</pre>
190
which would cause a parse error during
191
<tt class="function">spi_exec</tt> or
192
<tt class="function">spi_prepare</tt>.
193
To work properly, the submitted command should contain
196
<pre class="programlisting">SELECT 'doesn''t' AS ret</pre>
199
which can be formed in PL/Tcl using
202
<pre class="programlisting">"SELECT '[ quote $val ]' AS ret"</pre>
205
One advantage of <tt class="function">spi_execp</tt> is that you don't
206
have to quote parameter values like this, since the parameters are never
207
parsed as part of an SQL command string.
210
<dt><span class="term"><tt class="function">elog</tt> <i class="replaceable"><tt>level</tt></i> <i class="replaceable"><tt>msg</tt></i></span></dt>
211
<dd><p> Emits a log or error message. Possible levels are
212
<tt class="literal">DEBUG</tt>, <tt class="literal">LOG</tt>, <tt class="literal">INFO</tt>,
213
<tt class="literal">NOTICE</tt>, <tt class="literal">WARNING</tt>, <tt class="literal">ERROR</tt>, and
214
<tt class="literal">FATAL</tt>. Most simply emit the given message just like
215
the <tt class="literal">elog</tt> C function. <tt class="literal">ERROR</tt>
216
raises an error condition; if this is not trapped by the surrounding
217
Tcl code, the error propagates out to the calling query, causing
218
the current transaction or subtransaction to be aborted. This
219
is effectively the same as the Tcl <tt class="literal">error</tt> command.
220
<tt class="literal">FATAL</tt> aborts the transaction and causes the current
221
session to shut down. (There is probably no good reason to use
222
this error level in PL/Tcl functions, but it's provided for