是否有可能获得一个变量的最大可能长度 [英] Is it possible to get the maximum possible length of a variable
问题描述
我想知道plsql中是否存在给出变量最大长度的函数.
I was wondering if a function giving the maximum length of a variable exists in plsql.
例如,如果我声明
DECLARE
varia VARCHAR2(7)
BEGIN
call of a function that would return 7
END
即使varia为空,我也可以得到varchar的长度7.
even though varia is null, I could get the length 7 of the varchar.
---例子
create or replace
TYPE ENREG_320_03 UNDER ENREG_320_BASE(
date_creation VARCHAR2(8),
raison_sociale_emetteur VARCHAR2(35),
adresse_emetteur_1 VARCHAR2(35),
adresse_emetteur_2 VARCHAR2(35),
adresse_emetteur_3 VARCHAR2(35),
num_siret VARCHAR2(14),
ref_remise VARCHAR2(16),
code_bic_emetteur VARCHAR2(11),
type_ident_compte_debit VARCHAR2(1),
ident_compte_debit VARCHAR2(34),
code_devise_compte_debit VARCHAR2(3),
ident_client VARCHAR2(16),
type_ident_compte_frais VARCHAR2(1),
ident_compte_frais VARCHAR2(34),
code_devise_compte_frais VARCHAR2(3),
zone_reserve VARCHAR2(16),
indice_type_debit_remise VARCHAR2(1),
indice_type_remise VARCHAR2(1),
date_execution_souhait VARCHAR2(8),
devise_transfert VARCHAR2(3),
MEMBER FUNCTION get_date_creation RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.date_creation IS NULL THEN lpad(' ', 8, ' ') ELSE rpad(SELF.date_creation, 8, ' ') END;
END get_date_creation;
MEMBER FUNCTION get_raison_sociale_emetteur RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.raison_sociale_emetteur IS NULL THEN lpad(' ', 35, ' ') ELSE rpad(SELF.raison_sociale_emetteur, 35, ' ') END;
END get_raison_sociale_emetteur;
MEMBER FUNCTION get_adresse_emetteur_1 RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.adresse_emetteur_1 IS NULL THEN lpad(' ', 35, ' ') ELSE rpad(SELF.adresse_emetteur_1, 35, ' ') END;
END get_adresse_emetteur_1;
MEMBER FUNCTION get_adresse_emetteur_2 RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.adresse_emetteur_2 IS NULL THEN lpad(' ', 35, ' ') ELSE rpad(SELF.adresse_emetteur_2, 35, ' ') END;
END get_adresse_emetteur_2;
MEMBER FUNCTION get_adresse_emetteur_3 RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.adresse_emetteur_3 IS NULL THEN lpad(' ', 35, ' ') ELSE rpad(SELF.adresse_emetteur_3, 35, ' ') END;
END get_adresse_emetteur_3;
MEMBER FUNCTION get_num_siret RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.num_siret IS NULL THEN lpad(' ', 14, ' ') ELSE rpad(SELF.num_siret, 14, ' ') END;
END get_num_siret;
MEMBER FUNCTION get_ref_remise RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.ref_remise IS NULL THEN lpad(' ', 16, ' ') ELSE rpad(SELF.ref_remise, 16, ' ') END;
END get_ref_remise;
MEMBER FUNCTION get_code_bic_emetteur RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.code_bic_emetteur IS NULL THEN lpad(' ', 11, ' ') ELSE rpad(SELF.code_bic_emetteur, 11, ' ') END;
END get_code_bic_emetteur;
MEMBER FUNCTION get_type_ident_compte_debit RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.type_ident_compte_debit IS NULL THEN lpad(' ', 1, ' ') ELSE rpad(SELF.type_ident_compte_debit, 1, ' ') END;
END get_type_ident_compte_debit;
MEMBER FUNCTION get_ident_compte_debit RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.ident_compte_debit IS NULL THEN lpad(' ', 34, ' ') ELSE rpad(SELF.ident_compte_debit, 34, ' ') END;
END get_ident_compte_debit;
MEMBER FUNCTION get_code_devise_compte_debit RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.code_devise_compte_debit IS NULL THEN lpad(' ', 3, ' ') ELSE rpad(SELF.code_devise_compte_debit, 3, ' ') END;
END get_code_devise_compte_debit;
MEMBER FUNCTION get_ident_client RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.ident_client IS NULL THEN lpad(' ', 16, ' ') ELSE rpad(SELF.ident_client, 16, ' ') END;
END get_ident_client;
MEMBER FUNCTION get_type_ident_compte_frais RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.type_ident_compte_frais IS NULL THEN lpad(' ', 1, ' ') ELSE rpad(SELF.type_ident_compte_frais, 1, ' ') END;
END get_type_ident_compte_frais;
MEMBER FUNCTION get_ident_compte_frais RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.ident_compte_frais IS NULL THEN lpad(' ', 34, ' ') ELSE rpad(SELF.ident_compte_frais, 34, ' ') END;
END get_ident_compte_frais;
MEMBER FUNCTION get_code_devise_compte_frais RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.code_devise_compte_frais IS NULL THEN lpad(' ', 3, ' ') ELSE rpad(SELF.code_devise_compte_frais, 3, ' ') END;
END get_code_devise_compte_frais;
MEMBER FUNCTION get_zone_reserve RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.zone_reserve IS NULL THEN lpad(' ', 16, ' ') ELSE rpad(SELF.zone_reserve, 16, ' ') END;
END get_zone_reserve;
MEMBER FUNCTION get_indice_type_debit_remise RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.indice_type_debit_remise IS NULL THEN lpad(' ', 1, ' ') ELSE rpad(SELF.indice_type_debit_remise, 1, ' ') END;
END get_indice_type_debit_remise;
MEMBER FUNCTION get_indice_type_remise RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.indice_type_remise IS NULL THEN lpad(' ', 1, ' ') ELSE rpad(SELF.indice_type_remise, 1, ' ') END;
END get_indice_type_remise;
MEMBER FUNCTION get_date_execution_souhait RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.date_execution_souhait IS NULL THEN lpad(' ', 8, ' ') ELSE rpad(SELF.date_execution_souhait, 8, ' ') END;
END get_date_execution_souhait;
MEMBER FUNCTION get_devise_transfert RETURN VARCHAR2 AS
BEGIN
RETURN CASE WHEN SELF.devise_transfert IS NULL THEN lpad(' ', 3, ' ') ELSE rpad(SELF.devise_transfert, 3, ' ') END;
END get_devise_transfert;
所以我想知道是否存在一个简单的函数来获取字段的大小,所以我不必在getters中使用数字:如果更改了字段的大小,则无需更改getters,它可以算出varchar的大小
So I was wondering if a simple function existed to get the size of the field so I dont have to use numbers in the getters : if the size of the fields is changed, there would be no need to change the getters, it would work out whatever the size of the varchar
但是我知道这是不可能的
But I understand it is not possible
谢谢大家
推荐答案
在您的特定用例中,由于您是在类型中而不是在匿名块或存储过程中进行操作,因此可以从user_type_attrs
视图获取信息:
In your specific use case, since you're doing this within a type and not in an anonymous block or stored procedure, you could get the information from the user_type_attrs
view:
create or replace type t42 as object (
id number
) not final;
/
create or replace type t42_sub under t42 (
value varchar2(8),
constructor function t42_sub(p_value in varchar2) return self as result,
member function get_value return varchar2
);
/
create or replace type body t42_sub as
constructor function t42_sub(p_value in varchar2) return self as result is
begin
value := p_value;
return;
end t42_sub;
member function get_value return varchar2 is
l_attr_len number;
begin
select length into l_attr_len
from user_type_attrs
where type_name = 'T42_SUB'
and attr_name = 'VALUE';
return case when self.value is null then lpad(' ', l_attr_len, ' ')
else rpad(self.value, l_attr_len, ' ') end;
end get_value;
end;
/
然后使用该类型给出:
with t as (
select t42_sub('AA').get_value() as val from dual
union all select t42_sub(null).get_value() as val from dual
)
select val, '<'|| val ||'>', length(val)
from t;
VAL '<'||VAL||'>' LENGTH(VAL)
--------------- --------------- -----------
AA <AA > 8
< > 8
很显然,您可以编写一个函数来获取类型/属性名的长度,而不必在每个成员函数中重复执行选择.
Clearly you could write a function to get the length for the type/attr_name, rather than repeating the select in each member function.
我怀疑这将是相当昂贵的,除非您能提出一个缓存机制.如果对象是长寿命的,则可以在我认为的构造函数中进行查找:
I suspect it will be quite expensive though, unless you can come up with a caching mechanism. If the objects are long-lived you could do the look-up in the constructor I suppose:
create or replace type t42_sub under t42 (
value varchar2(8),
max_value_len number,
constructor function t42_sub(p_value in varchar2) return self as result,
member function get_value return varchar2
);
/
create or replace type body t42_sub as
constructor function t42_sub(p_value in varchar2) return self as result is
begin
value := p_value;
select length into max_value_len
from user_type_attrs
where type_name = 'T42_SUB'
and attr_name = 'VALUE';
return;
end t42_sub;
member function get_value return varchar2 is
begin
return case when self.value is null then lpad(' ', max_value_len, ' ')
else rpad(self.value, max_value_len, ' ') end;
end get_value;
end;
/
但是似乎仍然应该在源代码管理中而不是在运行时处理某些事情,可以在类型声明中显式设置max_value_len := 8
(在value
之后,因此希望您会注意到它们都需要更改) ),或使用使用替换变量的创建脚本.
But it still seems like something you should be handling in source control rather than at runtime, either explicitly setting max_value_len := 8
in the type declaration (next to the value
so you'll hopefully notice they both need to be changed), or with a creation script that uses substitution variables.
这篇关于是否有可能获得一个变量的最大可能长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!