如何用DBMS_OUTPUT.PUT_LINE打印出当前时间?

问题描述 投票:0回答:4

我使用以下代码来执行导出数据泵。

set serveroutput on;
DECLARE
  ind NUMBER;              -- Loop index
  h1 NUMBER;               -- Data Pump job handle
  percent_done NUMBER;     -- Percentage of job complete
  job_state VARCHAR2(30);  -- To keep track of job state
  le ku$_LogEntry;         -- For WIP and error messages
  js ku$_JobStatus;        -- The job status from get_status
  jd ku$_JobDesc;          -- The job description from get_status
  sts ku$_Status;          -- The status object returned by get_status
  >>>>>>>>>>>>>>v_systimestamp TIMESTAMP := SYSTIMESTAMP;<<<<<<<<<<<<<<

BEGIN

  h1 := DBMS_DATAPUMP.OPEN('EXPORT','SCHEMA',NULL,'EXAMPLE3','LATEST');

  DBMS_DATAPUMP.ADD_FILE(h1, 'dumpfile.dmp', 'EXPORT_DIRECTORY', NULL, DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE, 1);

  DBMS_DATAPUMP.METADATA_FILTER(h1,'SCHEMA_EXPR','IN (''SchemaName'')');

  DBMS_DATAPUMP.START_JOB(h1);



  percent_done := 0;
  job_state := 'UNDEFINED';
  while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop
             DBMS_OUTPUT.PUT_LINE(v_systimestamp);
    dbms_datapump.get_status(h1,
           dbms_datapump.ku$_status_job_error +

           dbms_datapump.ku$_status_job_status +
           dbms_datapump.ku$_status_wip,-1,job_state,sts);
    js := sts.job_status;

-- If the percentage done changed, display the new value.

    if js.percent_done != percent_done
    then

      dbms_output.put_line('*** Job percent done = ' ||
                           to_char(js.percent_done));
      percent_done := js.percent_done;
    end if;

-- If any work-in-progress (WIP) or error messages were received for the job,
-- display them.

   if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0)
    then

      le := sts.wip;
    else
      if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0)
      then
        le := sts.error;
      else
        le := null;
      end if;
    end if;
    if le is not null
    then
      ind := le.FIRST;
      while ind is not null loop
        >>>>>>>>>>>>>>DBMS_OUTPUT.PUT_LINE(v_systimestamp);<<<<<<<<<<<<<<
        dbms_output.put_line(le(ind).LogText);
        ind := le.NEXT(ind);
      end loop;
    end if;
  end loop;

-- Indicate that the job finished and detach from it.

  dbms_output.put_line('Job has completed');
  dbms_output.put_line('Final job state = ' || job_state);
  dbms_datapump.detach(h1);
END;

问题是导出时间太长。使用此 SQL 代码需要 25 分钟。架构的大小为 1.8 GB。

我想知道各个步骤需要多少时间。这就是为什么我想在每个流程步骤之后插入一个时间戳。然后我可以看到各个步骤需要多长时间。

我已用 (>>>> <<<<) in the code.

标记了时间戳的代码

时间戳不更新时间。我需要每个过程后的当前时间。你能帮我吗?

database oracle plsql timestamp oracle-sqldeveloper
4个回答
15
投票

在您的代码中,您在脚本开头设置 v_systimestamp 的值 - 这在整个脚本运行过程中不会改变。您可以在登录之前重置该值,如下所示:

v_systimestamp TIMESTAMP := SYSTIMESTAMP
DBMS_OUTPUT.PUT_LINE(v_systimestamp)

或在要监视的每个部分之前和之后执行类似以下操作(不需要变量):

DBMS_OUTPUT.PUT_LINE('Time Started: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS'));

DBMS_OUTPUT.PUT_LINE('Time Ended: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS'));

1
投票

这里是“CURRENT_TIMESTAMP”示例

curDateTime  TIMESTAMP := CURRENT_TIMESTAMP ;
DBMS_OUTPUT.PUT_LINE('CUR TIME '|| curDateTime);

1
投票

如果您运行的程序需要很长时间,

DBMS_OUTPUT.PUT_LINE
不会有太大帮助。好吧,它会显示一些内容,但是 - 当您使用循环时,根据迭代次数,
DBMS_OUTPUT
可能会耗尽缓冲区大小或超过 SQL*Plus 中的可见行数(如果您使用它),并且您会丢失部分输出。

此外,在该过程完成之前,您不会看到 DBMS_OUTPUT.PUT_LINE 中的任何

字母

因此,我建议您使用另一种方法 - 简单的日志记录,需要一个表、一个序列和一个(自主事务)过程。这是脚本:

CREATE TABLE a1_log
(
   id      NUMBER,
   datum   DATE,
   descr   VARCHAR2 (500)
);

CREATE SEQUENCE seqlognap START WITH 1 INCREMENT BY 1;

CREATE OR REPLACE PROCEDURE a1_p_log (par_descr IN VARCHAR2)
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   INSERT INTO a1_log
      SELECT seqlognap.NEXTVAL, SYSDATE, par_descr FROM DUAL;

   COMMIT;
END a1_p_log;

然后将A1_P_LOG调用放入你自己的程序中;类似的东西

begin
  a1_p_log('selecting from a large table');
  select ... into ... from ...;

  a1_p_log('entering the loop');
  while ... loop
    a1_p_log('doing something');
  end loop;

  a1_p_log('the end');
end;

这就是自治事务的重要性 - 它会将插入提交到日志表中(不影响主事务),因此您可以(当然,在另一个会话中)跟踪执行情况,只需重复发出

  SELECT *
    FROM a1_log
ORDER BY id;

它将显示(想象的例子):

1   22.05.2018 18:13:00    selecting from a large table
2   22.05.2018 18:20:07    entering the loop
3   22.05.2018 18:20:07    doing something
4   22.05.2018 18:20:08    doing something
5   22.05.2018 18:20:09    doing something
6   22.05.2018 18:20:10    the end

您会看到步骤 1 需要 7 分钟才能执行,所以 - 这就是您需要调查的内容。这意味着您不必等待主要过程完成 - 取消它并开始解决瓶颈。一旦你修复它,再次运行一切。


0
投票

声明

“一个”数字:= 5;

“A”数字:= 6;

开始

dbms_output.put_line('a='||a);

dbms_output.put_line('A='||A);

dbms_output.put_line(a);

结束;

为什么输出返回为

a=6

A =6

© www.soinside.com 2019 - 2024. All rights reserved.