1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
<!DOCTYPE html>
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link href="../sqlite.css" rel="stylesheet">
<title>The pre-update hook.</title>
<!-- path=../ -->
</head>
<body>
<div class=nosearch>
<a href="../index.html">
<img class="logo" src="../images/sqlite370_banner.gif" alt="SQLite" border="0">
</a>
<div><!-- IE hack to prevent disappearing logo --></div>
<div class="tagline desktoponly">
Small. Fast. Reliable.<br>Choose any three.
</div>
<div class="menu mainmenu">
<ul>
<li><a href="../index.html">Home</a>
<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a>
<li class='wideonly'><a href='../about.html'>About</a>
<li class='desktoponly'><a href="../docs.html">Documentation</a>
<li class='desktoponly'><a href="../download.html">Download</a>
<li class='wideonly'><a href='../copyright.html'>License</a>
<li class='desktoponly'><a href="../support.html">Support</a>
<li class='desktoponly'><a href="../prosupport.html">Purchase</a>
<li class='search' id='search_menubutton'>
<a href="javascript:void(0)" onclick='toggle_search()'>Search</a>
</ul>
</div>
<div class="menu submenu" id="submenu">
<ul>
<li><a href='../about.html'>About</a>
<li><a href='../docs.html'>Documentation</a>
<li><a href='../download.html'>Download</a>
<li><a href='../support.html'>Support</a>
<li><a href='../prosupport.html'>Purchase</a>
</ul>
</div>
<div class="searchmenu" id="searchmenu">
<form method="GET" action="../search">
<select name="s" id="searchtype">
<option value="d">Search Documentation</option>
<option value="c">Search Changelog</option>
</select>
<input type="text" name="q" id="searchbox" value="">
<input type="submit" value="Go">
</form>
</div>
</div>
<script>
function toggle_div(nm) {
var w = document.getElementById(nm);
if( w.style.display=="block" ){
w.style.display = "none";
}else{
w.style.display = "block";
}
}
function toggle_search() {
var w = document.getElementById("searchmenu");
if( w.style.display=="block" ){
w.style.display = "none";
} else {
w.style.display = "block";
setTimeout(function(){
document.getElementById("searchbox").focus()
}, 30);
}
}
function div_off(nm){document.getElementById(nm).style.display="none";}
window.onbeforeunload = function(e){div_off("submenu");}
/* Disable the Search feature if we are not operating from CGI, since */
/* Search is accomplished using CGI and will not work without it. */
if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){
document.getElementById("search_menubutton").style.display = "none";
}
/* Used by the Hide/Show button beside syntax diagrams, to toggle the */
function hideorshow(btn,obj){
var x = document.getElementById(obj);
var b = document.getElementById(btn);
if( x.style.display!='none' ){
x.style.display = 'none';
b.innerHTML='show';
}else{
x.style.display = '';
b.innerHTML='hide';
}
return false;
}
var antiRobot = 0;
function antiRobotGo(){
if( antiRobot!=3 ) return;
antiRobot = 7;
var j = document.getElementById("mtimelink");
if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href");
}
function antiRobotDefense(){
document.body.onmousedown=function(){
antiRobot |= 2;
antiRobotGo();
document.body.onmousedown=null;
}
document.body.onmousemove=function(){
antiRobot |= 2;
antiRobotGo();
document.body.onmousemove=null;
}
setTimeout(function(){
antiRobot |= 1;
antiRobotGo();
}, 100)
antiRobotGo();
}
antiRobotDefense();
</script>
<!-- keywords: sqlite3_preupdate_blobwrite sqlite3_preupdate_count sqlite3_preupdate_depth sqlite3_preupdate_hook sqlite3_preupdate_new sqlite3_preupdate_old -->
<div class=nosearch>
<a href="intro.html"><h2>SQLite C Interface</h2></a>
<h2>The pre-update hook.</h2>
</div>
<blockquote><pre>
#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
void *sqlite3_preupdate_hook(
sqlite3 *db,
void(*xPreUpdate)(
void *pCtx, /* Copy of third arg to preupdate_hook() */
sqlite3 *db, /* Database handle */
int op, /* SQLITE_UPDATE, DELETE or INSERT */
char const *zDb, /* Database name */
char const *zName, /* Table name */
sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */
sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */
),
void*
);
int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
int sqlite3_preupdate_count(sqlite3 *);
int sqlite3_preupdate_depth(sqlite3 *);
int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
int sqlite3_preupdate_blobwrite(sqlite3 *);
#endif
</pre></blockquote>
<p>
These interfaces are only available if SQLite is compiled using the
<a href="../compile.html#enable_preupdate_hook">SQLITE_ENABLE_PREUPDATE_HOOK</a> compile-time option.</p>
<p>The <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_hook()</a> interface registers a callback function
that is invoked prior to each <a href="../lang_insert.html">INSERT</a>, <a href="../lang_update.html">UPDATE</a>, and <a href="../lang_delete.html">DELETE</a> operation
on a database table.
At most one preupdate hook may be registered at a time on a single
<a href="../c3ref/sqlite3.html">database connection</a>; each call to <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_hook()</a> overrides
the previous setting.
The preupdate hook is disabled by invoking <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_hook()</a>
with a NULL pointer as the second parameter.
The third parameter to <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_hook()</a> is passed through as
the first parameter to callbacks.</p>
<p>The preupdate hook only fires for changes to real database tables; the
preupdate hook is not invoked for changes to <a href="../vtab.html">virtual tables</a> or to
system tables like sqlite_sequence or sqlite_stat1.</p>
<p>The second parameter to the preupdate callback is a pointer to
the <a href="../c3ref/sqlite3.html">database connection</a> that registered the preupdate hook.
The third parameter to the preupdate callback is one of the constants
<a href="../c3ref/c_alter_table.html">SQLITE_INSERT</a>, <a href="../c3ref/c_alter_table.html">SQLITE_DELETE</a>, or <a href="../c3ref/c_alter_table.html">SQLITE_UPDATE</a> to identify the
kind of update operation that is about to occur.
The fourth parameter to the preupdate callback is the name of the
database within the database connection that is being modified. This
will be "main" for the main database or "temp" for TEMP tables or
the name given after the AS keyword in the <a href="../lang_attach.html">ATTACH</a> statement for attached
databases.
The fifth parameter to the preupdate callback is the name of the
table that is being modified.</p>
<p>For an UPDATE or DELETE operation on a <a href="../rowidtable.html">rowid table</a>, the sixth
parameter passed to the preupdate callback is the initial <a href="../lang_createtable.html#rowid">rowid</a> of the
row being modified or deleted. For an INSERT operation on a rowid table,
or any operation on a WITHOUT ROWID table, the value of the sixth
parameter is undefined. For an INSERT or UPDATE on a rowid table the
seventh parameter is the final rowid value of the row being inserted
or updated. The value of the seventh parameter passed to the callback
function is not defined for operations on WITHOUT ROWID tables, or for
DELETE operations on rowid tables.</p>
<p>The <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_old()</a>, <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_new()</a>,
<a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_count()</a>, and <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_depth()</a> interfaces
provide additional information about a preupdate event. These routines
may only be called from within a preupdate callback. Invoking any of
these routines from outside of a preupdate callback or with a
<a href="../c3ref/sqlite3.html">database connection</a> pointer that is different from the one supplied
to the preupdate callback results in undefined and probably undesirable
behavior.</p>
<p>The <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_count(D)</a> interface returns the number of columns
in the row that is being inserted, updated, or deleted.</p>
<p>The <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_old(D,N,P)</a> interface writes into P a pointer to
a <a href="../c3ref/value.html">protected sqlite3_value</a> that contains the value of the Nth column of
the table row before it is updated. The N parameter must be between 0
and one less than the number of columns or the behavior will be
undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE
preupdate callbacks; if it is used by an SQLITE_INSERT callback then the
behavior is undefined. The <a href="../c3ref/value.html">sqlite3_value</a> that P points to
will be destroyed when the preupdate callback returns.</p>
<p>The <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_new(D,N,P)</a> interface writes into P a pointer to
a <a href="../c3ref/value.html">protected sqlite3_value</a> that contains the value of the Nth column of
the table row after it is updated. The N parameter must be between 0
and one less than the number of columns or the behavior will be
undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE
preupdate callbacks; if it is used by an SQLITE_DELETE callback then the
behavior is undefined. The <a href="../c3ref/value.html">sqlite3_value</a> that P points to
will be destroyed when the preupdate callback returns.</p>
<p>The <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_depth(D)</a> interface returns 0 if the preupdate
callback was invoked as a result of a direct insert, update, or delete
operation; or 1 for inserts, updates, or deletes invoked by top-level
triggers; or 2 for changes resulting from triggers called by top-level
triggers; and so forth.</p>
<p>When the <a href="../c3ref/blob_write.html">sqlite3_blob_write()</a> API is used to update a blob column,
the pre-update hook is invoked with SQLITE_DELETE. This is because the
in this case the new values are not available. In this case, when a
callback made with op==SQLITE_DELETE is actuall a write using the
sqlite3_blob_write() API, the <a href="../c3ref/preupdate_blobwrite.html">sqlite3_preupdate_blobwrite()</a> returns
the index of the column being written. In other cases, where the
pre-update hook is being invoked for some other reason, including a
regular DELETE, sqlite3_preupdate_blobwrite() returns -1.</p>
<p>See also: <a href="../c3ref/update_hook.html">sqlite3_update_hook()</a>
</p><p>See also lists of
<a href="objlist.html">Objects</a>,
<a href="constlist.html">Constants</a>, and
<a href="funclist.html">Functions</a>.</p>
|