Je me demandais si une fonction donnant la longueur maximale d'une variable existe dans PLSQL.
Par exemple, si je déclare P>
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;
3 Réponses :
L'approche avec le type type code> Attribut Alex Poole suggérées est l'une des meilleures pratiques ... mais juste FYI, je fournis un exemple pour Varchar2 Variable:
set serveroutput on
declare
v1 varchar2(23331);
v2 varchar2(500);
v3 varchar2(10);
begin
dbms_output.put_line ( f_declared_length (v1));
dbms_output.put_line ( f_declared_length (v2));
dbms_output.put_line ( f_declared_length (v3));
end;
/
anonymous block completed
23331
500
10
C'est très cool ... j'ai essayé de faire le paramètre "dans la nocopie" et il n'y avait pas de différence apparente de fonction ni de performance.
Présentateur (clap) Idée vraiment cool
Juste pour le plaisir de regarder mon chemin)))
Intéressant .. mais comme vous le suggérez .. Seulement pour le plaisir .. pas pour le code réel, car je m'attends à ce que ce soit nettement plus lent, alors f_declared_length code>.
Dans votre cas d'utilisation spécifique, car vous le faites dans un type et non dans un bloc anonyme ou une procédure stockée, vous pouvez em> obtenir les informations à partir du puis en utilisant ce type donne: p> user_type_attrs code> Vue:
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;
/
C'est une sorte de condition étrange. La taille est juste là, pourquoi avez-vous besoin d'un appel de fonction pour cela?
Parce que si un jour, la taille change, il y a une autre partie du code qui n'a pas besoin d'être changé
Pouvez-vous déclarer la variable (et l'autre partie du code, que je suppose est une autre variable également) en fonction d'une colonne d'une table; par exemple.
Déclarer Varia Tab.col% Type Code>? Ensuite, toutes les références seraient modifiées si la définition de la table a changé. Dépend de la manière dont vous l'utilisez bien sûr - si vous avez besoin d'une valeur maximale pour un substrateur lors de la collecte, par exemple, vous seriez un peu coincé.
En outre, est-ce un bloc anonyme (comme il semble être), et comment allez-vous l'exécuter? S'il s'agit de SLQ * plus, vous pouvez peut-être utiliser une variable de substitution pour définir la taille et l'avoir toujours disponible pour une utilisation ultérieure également, dans le même script. Plus de fond nécessaire ...
Afaik il n'y a pas de capacité introspection dans PL / SQL. Il est i> la vue user_identifiers, mais dans mon expérience c'est a) non peuplé pour la plupart des codes, et b) ne contient pas d'informations nécessaires. Je suis d'accord avec le commentaire de @ Alexpoole sur l'utilisation du type de colonne de la colonne si possible. Une autre possibilité est de déclarer la variable comme Varchar2 (32767) (taille maximale possible), puis ne vous inquiétez pas pour cela.
@mlwacosmos: Pourriez-vous montrer un cas d'utilisation concrete pour cela?
@bob +1 pour la no introspection:% Type n'est pas nécessaire ici
@Mat je montre un exemple et modifie le post