-
Notifications
You must be signed in to change notification settings - Fork 1
/
supplement.xml
261 lines (255 loc) · 14.3 KB
/
supplement.xml
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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
<!DOCTYPE appendix>
<appendix xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="supplement" xml:lang="ru">
<info>
<title>Дополнительные статьи</title>
</info>
<section xml:id="valid" xml:lang="ru">
<info>
<title>Поле RDB$VALID_BLR</title>
</info>
<para> В системных таблицах RDB$PROCEDURES, RDB$FUNCTIONS и RDB$TRIGGERS присутствует поле
RDB$VALID_BLR. Оно предназначено для сигнализации о возможной недействительности модуля
PSQL (процедуры или триггера) после изменения доменов или столбцов таблиц, от которых он
зависит. При возникновении описанной выше ситуации поле RDB$VALID_BLR устанавливается в
0 для процедур или триггеров, код которых возможно является недействительным. </para>
<section xml:id="valid-how">
<title>Как работает инвалидация</title>
<para>В триггерах, процедурах и функциях (в том числе и в процедурах и функциях пакетов)
зависимости возникают от столбцов таблицы к которой они обращаются, а так же от
любого параметра или переменной которые определены в модуле с использованием
предложения TYPE OF.</para>
<para>После того, как ядро Firebird изменило любой домен, включая неявные домены,
создаваемые внутри при определении столбцов или параметров, Firebird производит
внутреннюю перекомпиляцию всех зависимостей.</para>
<note>
<para>Инвалидация происходит для процедур, функций, пакетов и триггеров, но не для
блоков DML операторов, которые выполняются при помощи EXECUTE BLOCK.</para>
</note>
<para>Любой модуль, который не удалось перекомпилировать из-за несовместимости,
возникающей из-за изменения домена, помечается как недействительный (поле
<database>RDB$VALID_BLR</database> устанавливается в 0 в записи соответствующей
системной таблице (<database>RDB$PROCEDURES</database> или
<database>RDB$TRIGGERS</database>).</para>
<para>Возобновление (установка <database>RDB$VALID_BLR</database> в 1) происходит когда
<orderedlist spacing="compact">
<listitem>
<para>домен изменён снова и его новое определение совместимо с ранее
недействительным определением модуля; или</para>
</listitem>
<listitem>
<para>ранее недействительный модуль изменён так, что соответствовать новому
определению домена.</para>
</listitem>
</orderedlist>
</para>
<para>Нижеприведённый запрос находит процедуры и триггеры, зависящие от определённого
домена (в примере это домен 'MYDOMAIN'), и выводит информацию о состоянии поля
RDB$VALID_BLR:</para>
<para>
<programlisting language="sql">
WITH VALID_PSQL (
PSQL_TYPE,
ROUTE_NAME,
VALID)
AS (SELECT
'Procedure',
RDB$PROCEDURE_NAME,
RDB$VALID_BLR
FROM
RDB$PROCEDURES
WHERE
RDB$PROCEDURES.RDB$PACKAGE_NAME IS NULL
UNION ALL
SELECT
'Function',
RDB$FUNCTION_NAME,
RDB$VALID_BLR
FROM
RDB$FUNCTIONS
WHERE
RDB$FUNCTIONS.RDB$PACKAGE_NAME IS NULL
UNION ALL
SELECT
'Package',
RDB$PACKAGE_NAME,
RDB$VALID_BODY_FLAG
FROM
RDB$PACKAGES
UNION ALL
SELECT
'Trigger',
RDB$TRIGGER_NAME,
RDB$VALID_BLR
FROM
RDB$TRIGGERS
WHERE
RDB$TRIGGERS.RDB$SYSTEM_FLAG = 0)
SELECT
PSQL_TYPE,
ROUTE_NAME,
VALID
FROM
VALID_PSQL
WHERE
EXISTS(SELECT
*
FROM
RDB$DEPENDENCIES
WHERE
RDB$DEPENDENT_NAME = VALID_PSQL.ROUTE_NAME
AND RDB$DEPENDED_ON_NAME = 'MYDOMAIN');
/*
Замените MYDOMAIN фактическим именем проверяемого
домена. Используйте заглавные буквы, если
домен создавался нечувствительным к регистру — в
противном случае используйте точное написание
имени домена с учётом регистра
*/
</programlisting>
</para>
<para>Следующий запрос находит процедуры и триггеры, зависящие от определённого столбца
таблицы (в примере это столбец 'MYCOLUMN' таблицы 'MYTABLE'), и выводит информацию о
состоянии поля RDB$VALID_BLR:</para>
<para>
<programlisting language="sql">
WITH VALID_PSQL (
PSQL_TYPE,
ROUTE_NAME,
VALID)
AS (SELECT
'Procedure',
RDB$PROCEDURE_NAME,
RDB$VALID_BLR
FROM
RDB$PROCEDURES
WHERE
RDB$PROCEDURES.RDB$PACKAGE_NAME IS NULL
UNION ALL
SELECT
'Function',
RDB$FUNCTION_NAME,
RDB$VALID_BLR
FROM
RDB$FUNCTIONS
WHERE
RDB$FUNCTIONS.RDB$PACKAGE_NAME IS NULL
UNION ALL
SELECT
'Package',
RDB$PACKAGE_NAME,
RDB$VALID_BODY_FLAG
FROM
RDB$PACKAGES
UNION ALL
SELECT
'Trigger',
RDB$TRIGGER_NAME,
RDB$VALID_BLR
FROM
RDB$TRIGGERS
WHERE
RDB$TRIGGERS.RDB$SYSTEM_FLAG = 0)
SELECT
PSQL_TYPE,
ROUTE_NAME,
VALID
FROM
VALID_PSQL
WHERE
EXISTS(SELECT
*
FROM
RDB$DEPENDENCIES D
WHERE
D.RDB$DEPENDENT_NAME = VALID_PSQL.ROUTE_NAME
AND D.RDB$DEPENDED_ON_NAME = 'MYTABLE'
AND D.RDB$FIELD_NAME = 'MYCOLUMN');
/*
Замените MYTABLE и MYCOLUMN фактическими именами
проверяемой таблицы и её столбца.
Используйте заглавные буквы, если таблица и её
столбец создавались нечувствительными к регистру —
в противном случае используйте точное написание
имени таблицы и её столбца с учётом регистра
*/
</programlisting>
</para>
<important>
<para>Все случаи возникновения недействительных модулей, вызванных изменениями
доменов/столбцов, отражаются в поле <database>RDB$VALID_BLR</database>. Тем не
менее, другие виды изменения, таких как изменения количества входных или
выходных параметров процедур и так далее, не влияют на поле проверки, даже если
потенциально они могут привести к недействительности модуля. Типичные сценарии
могут быть следующими: <orderedlist>
<listitem>
<para>Процедура (B) определена так, что она вызывает другую процедуру
(A) и считывает выходные параметры из неё. В этом случае зависимость
будет зарегистрирована в <database>RDB$DEPENDENCIES</database>. В
последствии вызываемая процедура (A) может быть изменена для
изменения или удаления одного и более выходных параметров. Оператор
ALTER PROCEDURE A приведёт к ошибки при выполнении фиксации
транзакции.</para>
</listitem>
<listitem>
<para>Процедура (B) вызывает процедуру (A), передавая ей значения в
качестве входных параметров. Никаких зависимостей не будет
зарегистрировано в <database>RDB$DEPENDENCIES</database>.
Последующие модификации входных параметров процедуры A будут
позволены. Отказ произойдет во время выполнения, когда В вызовет A с
несогласованным набором входных параметров.</para>
</listitem>
</orderedlist>
</para>
</important>
<note>
<title>Другие замечания</title>
<para><itemizedlist>
<listitem>
<para>Для модулей PSQL, наследованных от более ранних версий Firebird
(включая многие системные триггеры, даже если база данных
создавалась под версией Firebird 2.1 или выше), поле
<database>RDB$VALID_BLR</database> имеет значение NULL. Это не
означает, что их BLR является недействительным.</para>
</listitem>
<listitem>
<para>Команды утилиты командной строки <application>isql</application>
SHOW PROCEDURES, SHOW FUNCTIONS и SHOW TRIGGERS при выводе
информации отмечают звёздочкой модули, у которых поле
<database>RDB$VALID_BLR</database> равно 0. Команды SHOW
PROCEDURE <procname>, SHOW FUNCTION <funcname> и SHOW
TRIGGER <trigname>, выводящие на экран код PSQL модуля, не
сигнализируют пользователя о недопустимом BLR.</para>
</listitem>
</itemizedlist></para>
</note>
</section>
</section>
<section xml:id="appendix-supplement-equality">
<title>Замечание о равенстве</title>
<important>
<para>Это замечание об операторах равенства и неравенства применяется повсюду в СУБД
Firebird.</para>
</important>
<para>Оператор "=", который используется во многих условиях, сравнивает только значения со
значениями. В соответствии со стандартом SQL, NULL не является значением и,
следовательно, два значения NULL не равны и ни неравны друг с другом. Если необходимо,
чтобы значения NULL соответствовали друг другу при объединении, используйте оператор IS
NOT DISTINCT FROM. Этот оператор возвращает истину, если операнды имеют то же значение,
или, если оба они равны NULL.
<programlisting language="sql">
SELECT *
FROM A
JOIN B ON A.id IS NOT DISTINCT FROM B.code
</programlisting>
</para>
<para>Точно так же, если вы хотите чтобы значения NULL отличались от любого значения и два
значения NULL считались равными, используйте оператор IS DISTINCT FROM вместо оператора
"<>".
<programlisting language="sql">
SELECT *
FROM A
JOIN B ON A.id IS DISTINCT FROM B.code
</programlisting>
</para>
</section>
</appendix>