【问题标题】:Delete using PL SQL使用 PL SQL 删除
【发布时间】:2014-12-11 08:46:55
【问题描述】:

如何通过提供输入文件使用 PL SQL 执行删除操作?我不想冒险直接从表中删除。是否可以通过将值作为输入来删除?如果有怎么办?

【问题讨论】:

  • 你的实际问题是什么!详细说明你的情况
  • 不直接从表中删除是什么意思。您还想在哪里删除?
  • 情况是从一个表中删除 10K 个条目。我将这些 id 保存在一个文件中,我只想从表中删除它们。那么如何通过输入文件来删除呢?
  • “不直接从表中删除”我的意思是我不想在 sn-p 中给出一个条件,例如“从条件 1 和条件 2 的 xxx 中删除”
  • 如果不使用delete,就无法从表中删除。那么你的问题到底是什么?

标签: oracle plsql


【解决方案1】:

您可以将文件加载为外部表

然后编写查询以使用外部表中的条目删除条目

例如。

delete from yourtable where id in (select id from extTable)

外部表的一些文档:

http://docs.oracle.com/cd/B19306_01/server.102/b14215/et_concepts.htm

另一种方法是使用 oracle/sql 之外的脚本(例如 excel)生成删除语句,然后执行您的删除语句

【讨论】:

    【解决方案2】:

    编辑 仅用于使用 plsql 提取数据。

    https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:68212348056

    其他方法

    1) 使用 shell 脚本(如 BASH)将数据从 FILE 传输到临时表中。

    2) 然后使用临时表从主表中删除数据。

    3) 在设置 Cron 作业后,您将获得额外的优势来再次执行相同的操作

    示例脚本文件

    #!/bin/ksh
    ORAENV_ASK=NO
    export ORAENV_ASK
    
    ORACLE_SID=newsp1
    inputFileBkUpDir=/usr/users/backup
    inputFileDir=/usr/users/file
    LogDir=/usr/users/log
    ORACLE_HOME=/u01/app/oracle/product/9.2.0.6
    
    export ORACLE_SID
    export ORACLE_HOME
    export inputFileBkUpDir
    export inputFileDir
    export LogDir
    
    PATH=$PATH:/usr/local/bin
    export PATH
    
    . oraenv
    
    # Log File
    LOGFILE=$LogDir/EDI_file_`date +%y%m%d`.log;
    
    
    # Create backup directory if its not created
    if ! [ -d $inputFileBkUpDir ]
    then
        mkdir $inputFileBkUpDir
    fi
    
    
    if ! [ -d $LogDir ] 
    then
      echo 'LogDir not exists'
        echo "Trying to create directory" 
        mkdir $LogDir 
        if [ $? -ne 0 ]
        then
            echo "Log Directory " $LogDir " creation problem\nCannot continue process" >> ${LOGFILE}
            exit
        fi
        echo 'after LogDir created'
    else
        chmod 777 $LogDir
        echo log permission changed of $LogDir
    fi
    
    
    
    #*********************************** FILE EXECUTION START ***********************************************
    
    echo "\n>>> ******Processing File - STARTED at `date '+%d-%m-%Y %T %Z'`******">> ${LOGFILE}
    
    sqlplus TEST_USER/PASS_USER << EOF
    set serveroutput on;
    spool /usr/users/spool.lst
    delete from new_t.data;
    commit;
    spool off
    exit
    EOF
    
    echo "\n>>> Check if EDI file has arrived - STARTED at `date '+%d-%m-%Y %T %Z'`">> ${LOGFILE}
    
    for entry in "$inputFileDir"/YOUR_FILE*.dat;
    do
      if [ -f "$entry" ];then
        echo "\n>>> Files present in input directory $inputFileDir">> ${LOGFILE}
        echo "\n>>> $entry" >> ${LOGFILE}
        echo "\n>>> Loading $entry file data for EDI DUMP\n" >>${LOGFILE}
    
        sqlldr TEST_USER/PASS_USER control=/usr/users/control.ctl data=$entry log=$LogDir/fileLoader.log
        echo 'Total number of Records Successfully Loaded         \t\t\t\c'>>$LOGFILE; grep 'Rows successfully loaded' $LogDir/fileLoader.log | awk '{print $1}'>>$LOGFILE
        echo 'Rows not loaded due to data error                   \t\t\t\c'>>$LOGFILE; grep 'Rows not loaded due to data errors' $LogDir/fileLoader.log | awk '{print $1}'>>$LOGFILE
        echo 'Rows not loaded because all WHEN clauses were failed\t\t\t\c'>>$LOGFILE; grep 'Rows not loaded because all WHEN clauses were failed' $LogDir/fileLoader.log | awk '{print $1}'>>$LOGFILE
        echo 'Rows not loaded because all fields were null        \t\t\t\c'>>$LOGFILE; grep 'Rows not loaded because all fields were null' $LogDir/fileLoader.log | awk '{print $1}'>>$LOGFILE
        echo "\n>>> Data loaded from $entry file" >>${LOGFILE}
    
        mv $entry $inputFileBkUpDir
        echo "\n>>> Moving $entry file to archive path $inputFileBkUpDir" >>${LOGFILE}
    
      else
        echo 'Files not present' >> ${LOGFILE}
      fi
    done
    
    echo "\n>>> ******Data Load Completed******" >>${LOGFILE}
    
    echo "\n>>> ******Processing Started FILE TO DELETE DATA******" >>${LOGFILE}
    
    sqlplus TEST_USER/PASS_USER << EOF
    set serveroutput on;
    spool /usr/users/spool.lst
    @/usr/users/Data_Processing.sql;
    spool off
    exit
    EOF
    echo "\n>>> ******Processing complete- Data DELETED******" >>${LOGFILE}
    echo "End of the script">> ${LOGFILE}
    

    设置如何从您的文件中读取 IDS 到临时表的示例控制文件

    LOAD DATA
            APPEND INTO TABLE COLSIMS.EDI_DATA_LOAD
            (
              S_NUMBER        POSITION(1:25),
              P_CODE          POSITION(26:50),
              P_NUMBER        POSITION(51:80),
              T_TIMESTAMP     POSITION(406:417) date "YYMMDDHH24MISS",
              L_TIMESTAMP     sysdate
             )
    

    【讨论】:

      【解决方案3】:

      假设这些 ID 值在文件中以每行一个 ID 的形式存储,并且 ID 值是数字,那么您应该可以开始以下操作:

      DECLARE
        fHandle        UTL_FILE.FILE_TYPE;
        strBuffer      VARCHAR2(32767);
        nRows_deleted  NUMBER := 0;
      BEGIN
        fHandle := UTL_FILE.FOPEN('some_directory', 'filename.dat', 'r');
      
        LOOP
          BEGIN
            UTL_FILE.GET_LINE(fHandle, strBuffer);
          EXCEPTION
            WHEN NO_DATA_FOUND THEN  -- end of file
              EXIT;                  -- exit the loop
          END;
      
          DELETE FROM SOME_TABLE
            WHERE ID = TO_NUMBER(strBuffer);
      
          nRows_deleted := nRows_deleted + SQL%ROWCOUNT;
        END LOOP;
      
        COMMIT;
      
        DBMS_OUTPUT.PUT_LINE('Changes committed');
      
        UTL_FILE.FCLOSE(fHandle);
      
        DBMS_OUTPUT.PUT_LINE('Completed successfully, ' || nRows_deleted || ' rows deleted');
      EXCEPTION
        WHEN OTHERS THEN
          DBMS_OUTPUT.PUT_LINE('Error: ' || SQLCODE  || ' - ' || SQLERRM);
          ROLLBACK;
          DBMS_OUTPUT.PUT_LINE('All changes ROLLED BACK');
          RAISE;
      END;
      

      编辑

      作为替代选项,您可以定义一个外部表以允许您的文件被视为只读表:

      CREATE TABLE DATA_FROM_FILE
        (ID     CHAR(10))
        ORGANIZATION EXTERNAL
          (TYPE ORACLE_LOADER
           DEFAULT DIRECTORY some_directory
           ACCESS PARAMETERS
             (RECORDS DELIMITED BY NEWLINE
              FIELDS (ID  CHAR(10))
             )
           LOCATION ('filename.dat'));
      

      这将允许你做类似的事情

      DELETE FROM SOME_TABLE
        WHERE ID IN DATA_FROM_FILE;
      

      分享和享受。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-13
        • 1970-01-01
        • 1970-01-01
        • 2021-02-04
        • 2023-03-30
        • 1970-01-01
        • 2021-09-06
        • 1970-01-01
        相关资源
        最近更新 更多