Tudo de
ORGANIZATION
em diante está sendo visto como código PL/SQL, não como parte de sua instrução SQL dinâmica. Você está anexando o nome da tabela ao create table
mas não anexando o resto como parte dessa string de instrução. Você precisa fazer algo como:execute immediate 'create table ' || p_tab_name || '
( /* put column names and types here */ )
ORGANIZATION EXTERNAL
(
TYPE ORACLE_LOADER
DEFAULT DIRECTORY DE_DUBFILE
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE
CHARACTERSET US7ASCII
BADFILE UPLOAD:''' || p_tab_name || '.bad''
DISCARDFILE UPLOAD:''' || p_tab_name || '.dis''
LOGFILE UPLOAD:''' || p_tab_name || '.log''
FIELDS TERMINATED BY '',''
optionally enclosed by ''"''
MISSING FIELD VALUES ARE NULL
(
t1 ,t2,t3,t4,t5 date mask "YYYYMMDD" ,t6,t7,
t8 ,t9, t10,t11
)
LOCATION (''' || DATAFILE || ''')
)';
Na primeira linha, o ponto e vírgula final foi substituído pela concatenação de um novo literal de string. As referências às variáveis
p_tab_name
e DATAFILE
devem ser separados desse literal também, exigindo mais aspas simples e concatenação; e as aspas simples que realmente fazem parte da declaração precisam ser evitadas dobrando-as. Havia várias outras citações faltando também. O que é mostrado agora deve ser executado. Também alterei o nome da tabela usada apenas para
p_tab_name
, mas você precisa especificar os nomes das colunas e os tipos de dados explicitamente. Não faz sentido usar as select * ...
para uma mesa externa. Isso não é sintaxe legal, também antes de organization
ou depois do resto se a declaração atual. Suponho que você possa extrair essas informações de all_tab_columns
e construa essa parte dinamicamente também, mas se você está baseando-a em uma tabela fixa, você deve conhecê-las de qualquer maneira. Sua lógica para descartar/criar também está desativada - acho que você só quer:
if n>0 then
execute immediate 'drop table ' || p_tab_name;
end if;
execute immediate 'create table ' || p_tab_name || '
...
... para que você não precise repetir a instrução create em ambas as ramificações.
Também corrigi alguns outros erros;
PARAMETERS
em vez de PARAMETER
; FIELDS
em vez de FILEDS
; removido TRAILING NULLCOLS
. Tente executar o comando como SQL estático antes de convertê-lo em dinâmico. Ainda pode haver outros problemas. E eu removi as duas últimas colunas calculadas:
DETL_CLMNS_HASH "ORA_HASH( :t4||:t7 )",
KEY_CLMNS_HASH "ORA_HASH(:t1||:t2||:t5)")
O
ORACLE_LOADER
motorista
não permite manipulações assim; SQL*Loader faz, mas eles não são exatamente os mesmos. Você também não pode definir colunas virtuais em uma tabela externa. Se você estiver usando isso como uma tabela de teste para carregar dados em outra tabela (real), poderá calcular esses hashes durante a transferência; caso contrário, você pode criar uma visão sobre esta tabela externa que inclui as colunas calculadas.