如果存在则删除并创建 table 如果不存在则在 oracle 过程中创建

Drop and Create table if exist if not then Create in oracle Procedure

我有一个查询需要数据的开始和结束年份,它还需要 table 的名称作为过程参数..

然后查询将创建一个 table 如果它不存在或者如果存在它将删除并重新创建它

    CREATE OR REPLACE Procedure USE_RAWDATA
   ( START_RP IN NUMBER, END_RP IN NUMBER,TABLE_NAME varchar)
IS
v_listStr CLOB;
DAT VARCHAR(500):=to_char(to_date(SYSDATE), 'yyyymmdd');
cnt NUMBER;
BEGIN 
 BEGIN
   SELECT COUNT(*) INTO cnt FROM user_tables WHERE table_name = TABLE_NAME||'_'||DAT;
   dbms_output.put_line(TABLE_NAME||'_'||DAT);
   dbms_output.put_line(cnt);
 IF (cnt) = 1 THEN
    EXECUTE IMMEDIATE 'DROP TABLE '||TABLE_NAME||'_'||DAT;
   dbms_output.put_line('DROP TABLE '||TABLE_NAME||'_'||DAT);
END IF;
END;
    select rtrim(xmlagg(xmlelement(e,column_name,', ').extract('//text()') order by column_id).getclobval(),', ') x INTO v_listStr from RAW_DATA_METADATA WHERE (START_ROUND<= END_RP and END_ROUND is NULL) or (START_ROUND >= START_RP and END_ROUND <= END_RP );
    EXECUTE IMMEDIATE 'CREATE TABLE '||TABLE_NAME||'_'||DAT||' AS SELECT '||v_listStr ||' FROM RAW_DATA WHERE ROUND_ID BETWEEN '||START_RP ||' AND '||END_RP;
END;
/

我的问题是 cnt 总是给我 0 即使 table 存在然后程序将以错误结束 table 已经存在... 我不知道为什么 .. 因为当我尝试它作为 PL\SQL 查询时它给了我一个正确的结果 cnt =1 if exist

declare
v_listStr CLOB;
DAT VARCHAR(500):=to_char(to_date(SYSDATE), 'yyyymmdd');
cnt NUMBER;
BEGIN 
 BEGIN
   SELECT COUNT(*) INTO cnt FROM user_tables WHERE :TABLE_NAME = :TABLE_NAME||'_'||DAT;
   dbms_output.put_line(:TABLE_NAME||'_'||DAT);
   dbms_output.put_line(cnt);
 IF (cnt) = 1 THEN
    EXECUTE IMMEDIATE 'DROP TABLE '||:TABLE_NAME||'_'||DAT;
   dbms_output.put_line('DROP TABLE '||:TABLE_NAME||'_'||DAT);
END IF;
END;
    select rtrim(xmlagg(xmlelement(e,column_name,', ').extract('//text()') order by column_id).getclobval(),', ') x INTO v_listStr from RAW_DATA_METADATA WHERE (START_ROUND<= :END_RP and END_ROUND is NULL) or (START_ROUND >= :START_RP and END_ROUND <= :END_RP );
    EXECUTE IMMEDIATE 'CREATE TABLE '||:TABLE_NAME||'_'||DAT||' AS SELECT '||v_listStr ||' FROM RAW_DATA WHERE ROUND_ID BETWEEN '||:START_RP ||' AND '||:END_RP;
END;
/

你能帮我弄清楚为什么它总是 cnt 给出 0 即使 table 存在

此查询只能 return 0:

select count(*) into cnt
from   user_tables
where  table_name = table_name || '_' || dat;

您需要在 table_name 前添加过程名称

select count(*) into cnt
from   user_tables
where  table_name = use_rawdata.table_name || '_' || dat;

或者以不同的方式命名您的参数(tableNamep_table_name 等)。

我还建议删除第一个 beginend,因为它们什么都不做,并调整缩进以更准确地反映代码结构。

我做的是这样的:

create or replace procedure use_rawdata
    ( start_rp   in number
    , end_rp     in number
    , table_name varchar2 )
is
    v_liststr clob;
    dat  varchar2(8) := to_char(sysdate, 'yyyymmdd');
    cnt  number;
begin
    select count(*) into cnt
    from   user_tables
    where  table_name = upper(use_rawdata.table_name) || '_' || dat;

    dbms_output.put_line(table_name || '_' || dat);
    dbms_output.put_line(cnt);

    if cnt = 1 then
        execute immediate 'DROP TABLE ' || table_name || '_' || dat;
        dbms_output.put_line('DROP TABLE ' || table_name || '_' || dat);
    end if;

    select rtrim(xmlagg(xmlelement(e, column_name, ', ').extract('//text()') order by column_id).getclobval(), ', ') x
    into   v_liststr
    from   raw_data_metadata
    where  (start_round <= end_rp and end_round is null)
    or     (start_round >= start_rp and end_round <= end_rp);

    execute immediate 'create table ' || table_name || '_' || dat || ' as select ' || v_liststr || ' from raw_data where round_id between ' || start_rp || ' and ' || end_rp;
end;