web-dev-qa-db-fra.com

Solution de contournement pour ORA-00997: utilisation illégale du type de données LONG

Je souhaite enregistrer certaines données d'une table système user_tab_cols dans une table temporaire afin de pouvoir en extraire un cliché.

Il y a 100 000 lignes, j’ai sélectionné dans user_tab_cols environ 1 000 enregistrements et les ai sauvegardés dans une table temporaire avec cette requête:

create table temp table as 
select * from user_tab_cols where condition...

J'avais l'erreur 'utilisation illégale de longtype', à cause de la colonne DATA_DEFAULT qui contient un type de long.

Existe-t-il un moyen alternatif de stocker un type long dans une autre table?

8
Moudiz

ORA-00997: utilisation illégale du type de données LONG

Il s'agit d'une restriction sur l'utilisation du type de données LONG. Vous ne pouvez pas créer un type d'objet avec un attribut LONG.

SQL> CREATE TABLE t AS SELECT data_default FROM user_tab_cols;
CREATE TABLE t AS SELECT data_default FROM user_tab_cols
                         *
ERROR at line 1:
ORA-00997: illegal use of LONG datatype


SQL>

Vous pouvez également utiliser TO_LOB comme solution de contournement. Ce qui le convertirait en type de données CLOB.

Par exemple,

SQL> CREATE TABLE t AS SELECT TO_LOB(data_default) data_default FROM user_tab_cols;

Table created.

SQL> desc t;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 DATA_DEFAULT                                       CLOB

SQL>

Voir plus d'exemples de solutions de contournement ici .

11
Lalit Kumar B

Vous devrez créer votre table cible explicitement, pas à partir de select *:

create table demo_copy
( table_name varchar2(30)
, column_name varchar2(30)
, data_type varchar2(106)
, data_type_mod varchar2(3)
, data_type_owner varchar2(30)
, data_length number
, data_precision number
, data_scale number
, nullable varchar2(1)
, column_id number
, default_length number
, data_default clob
, num_distinct number
, low_value raw(32)
, high_value raw(32)
, density number
, num_nulls number
, num_buckets number
, last_analyzed date
, sample_size number
, character_set_name varchar2(44)
, char_col_decl_length number
, global_stats varchar2(3)
, user_stats varchar2(3)
, avg_col_len number
, char_length number
, char_used varchar2(1)
, v80_fmt_image varchar2(3)
, data_upgraded varchar2(3)
, hidden_column varchar2(3)
, virtual_column varchar2(3)
, segment_column_id number
, internal_column_id number
, histogram varchar2(15)
, qualified_col_name varchar2(4000) );

(J'ai fait data_default une clob pour une interrogation plus pratique.)

Ensuite, vous pouvez insérer des lignes dans une boucle PL/SQL:

begin
    for r in (
        select * from user_tab_cols c
        where  rownum <= 2  -- your filter condition here
    )
    loop
        insert into demo_copy values r;
    end loop;
end;

Cette approche présente quelques limitations de principe, car une colonne long peut contenir plus que la varchar2(32760) que PL/SQL utilisera dans la boucle. Cependant, je pense que 32 Ko suffiront pour la plupart des expressions par défaut de colonnes.

2
William Robertson