如果 Oracle 包/程序/函式中的常量被定義為(隱式),是否有任何正面或負面(性能)影響not null?例如
// Varchar2
C_LF_V1 constant varchar2(1) := chr(10);
C_LF_V2 constant varchar2(1) not null := chr(10);
// PLS number
C_MAX_PLS_STR_LENB_V1 constant pls_integer := 32767;
C_MAX_PLS_STR_LENB_V2 constant pls_integer not null := 32767;
C_MAX_PLS_STR_LENB_V3 constant positiven := 32767;
C_MAX_PLS_STR_LENB_V4 constant simple_integer := 32767;
// Date
C_MAX_DATE_V1 constant date := date '9999-12-31'
C_MAX_DATE_V2 constant date not null := date '9999-12-31'
// ...
該檔案根本不針對這些細節,因為(不幸的是)太頻繁了 - 從 11 到 19 進行了檢查(如果它實際上是特定于版本的,那么從 19 開始的實作會很有趣)。
當然,運行一些測驗是可能的/容易的,但這只會提供平臺/版本/機器特定的結果,而低級實作/概念邏輯更有趣,即
- 將(隱式)
not null編譯為已知的非NULL,還是會導致每次訪問都進行NULL檢查?
更新(澄清):
- 我的問題與已知的常量有關
NOT NULL(因此與NULL處理無關) - 我根本不在“想要的”納秒調整之后——我想知道幕后實際發生了什么;例如,
simple_integer檔案說它可以使繁重的計算更有效,這意味著在編譯時它“知道”這樣的變數永遠不可能NULL-> 那么這個含義是否也適用于例如date定義為NOT NULL?- 或者更棘手的varchar2?(NOT NULL允許定義子型別,但由于忽略可空屬性而沒有意義)
uj5u.com熱心網友回復:
我不知道。
只是大聲思考。
這編譯:
SQL> create or replace package pkg_test as
2 c_v1 constant varchar2(1) := null;
3 end;
4 /
Package created.
指定常量NOT NULL并分配NULL給它不起作用:
SQL> create or replace package pkg_test as
2 c_v1 constant varchar2(1) not null := null;
3 end;
4 /
Warning: Package created with compilation errors.
SQL> show err
Errors for PACKAGE PKG_TEST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
2/8 PL/SQL: Declaration ignored
2/41 PLS-00382: expression is of wrong type
盡管空字串被視為NULLs,但這不會引發任何錯誤:
SQL> create or replace package pkg_test as
2 c_v1 constant varchar2(1) not null := '';
3 end;
4 /
Package created.
SQL>
是否有意義?一個常數,其值為NULL? 也許,也許不是,我不記得我用過它。
作為一個包體:讓我們重用最后的代碼并添加一個程序:
SQL> create or replace package pkg_test as
2 c_v1 constant varchar2(1) not null := '';
3
4 procedure p_test;
5 end;
6 /
Package created.
SQL> create or replace package body pkg_test is
2 procedure p_test is
3 begin
4 c_v1 := 'x';
5 end;
6 end;
7 /
Warning: Package Body created with compilation errors.
SQL> show err
Errors for PACKAGE BODY PKG_TEST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/5 PL/SQL: Statement ignored
4/5 PLS-00363: expression 'C_V1' cannot be used as an assignment
target
SQL>
對; 它甚至沒有意義——它是一個常量,你不應該修改它的值。
檔案說:
- “宣告變數”中的資訊也適用于常量宣告,但常量宣告還有兩個要求:關鍵字 CONSTANT 和常量的初始值。
- (...)
- 在變數宣告中,初始值是可選的,除非您指定 NOT NULL 約束。在常量宣告中,初始值是必需的。
It looks like Oracle treats variable and constant declarations almost the same, with some differences. As if constants "inherited" NOT NULL constraint from variables. Does it make sense? Can't tell.
More from the same document:
- If the declaration is in a package specification, the initial value is assigned to the variable or constant for each session (whether the variable or constant is public or private).
So: it is assigned once for the session. It is a constant, after all ...
因此,從我的角度來看,我不希望對是否對NOT NULL常量施加約束會產生任何性能影響。我想說還有其他需要擔心的事情,例如在包體內調整查詢;如果寫得不好,它們將對性能產生重大影響。常數是NULL或NOT NULL將是你最不擔心的。
uj5u.com熱心網友回復:
可以使用一些小的編譯時優化,但它們不太可能有任何顯著的好處,例如,如果你做類似的事情
create or replace
package PKG is
x constant int not null := 0;
procedure p;
end;
/
create or replace
package body PKG is
procedure p is
y int;
begin
for i in 1 .. 1000000
loop
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
if x is not null then
y := i;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end loop;
end;
end;
/
set timing on
exec pkg.p;
您會看到在常量定義中洗掉 CONSTANT 會產生更快的結果,但我們仍在談論每次呼叫的微/納秒收益。同樣,如果它不是常量但具有 NOT NULL,您將獲得相同的好處。
此類宣告的主要目的只是另一種形式的代碼和資料正確性,而不是性能。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/408374.html
標籤:
上一篇:即使滿足條件,存盤程序也不更新列
