【问题标题】:Export table to csv file by using procedure (csv name with timestamp)使用过程将表导出到 csv 文件(带时间戳的 csv 名称)
【发布时间】:2015-06-06 14:21:36
【问题描述】:

我想将一个表导出到每个 csv 文件,并用时间戳命名 csv 文件。比如我有一张表t1,导出后会生成一个csv文件名t1.YYYYMMDDHHMISS.csv。这是我的代码:

create or replace procedure 
T_to_CSV(Tname varchar2,Directory varchar2)

BEGIN

set colsep ,     -- separate columns with a comma
set pagesize 0   -- No header rows
set trimspool on -- remove trailing blanks
set headsep off  -- this may or may not be useful...depends on your 

spool timestamp.csv --don't know how to write in directory

select *
  from Tname

end

这是我的问题:

(1)我不知道怎么把csv文件输出到需要的目录,请问如何修复spool code?​​p>

我应该使用 spool D:\path\filename.csv 吗?

(2) 在spool line中,如何使用timestamp now() 更改csv文件的名称?

【问题讨论】:

  • Spool 用于 sqlplus,只能写入计算机或映射驱动器上的文件。目录用于将文件写入数据库所在的服务器或 UNC 路径。假脱机在过程中不起作用,但您可以使用 DBMS_OUTPUT,假脱机命令将获取其输出。
  • 也许这会有所帮助:How to create a oracle sql scrpt spool file
  • 感谢思考,非常有帮助。请问您知道如何运行链接中的脚本吗?
  • 不,抱歉。但问题看起来与您的问题非常相似 - (目录、时间戳)。

标签: sql oracle stored-procedures


【解决方案1】:

有几个步骤:

  • 使用 `CREATE DIRECTORY my_dir as 'C:\dir' 创建 directory
  • 确保 Oracle 已读取、写入计算机上的文件夹(最好在 Oracle 安装文件夹中创建它)
  • 授予执行过程GRANT read,write on DIRECTORY my_dir to the_user;的用户
  • 下载编译方便程序here

我用过这个,效果很好。

用法

data_dump ( 'Select emp_name from emp',
             CURRENT_TIMESTAMP||'filename.csv',
             my_dir);

(大大简化的示例!)

创建目录后,运行以下命令验证您的工作:

  • 从 ALL_DIRECTORIES 中选择 *;
  • 您应该会看到您的目录
  • 登录数据库所在机器,确认文件夹路径存在,oracle用户有权限。仅当运行 oracle 服务的用户对该文件夹具有权限时,才可以使用网络驱动器

【讨论】:

  • 哇,感谢凯文的链接。 sql代码太复杂了。也许我只需要一个简单的版本来实现我的简单目标。我可以稍微修改一下我的代码吗?
  • 嗨,凯文。我试过你的方法。请问在 my_dir 中输入什么?我使用 D: 或 D:/,但返回错误。谢谢。
  • 你需要使用你在我回答的第一步中创建的目录的名称
  • @postgresnewbie 对于 Linux 中的文件路径没有区别,必须授予 oracle 进程权限,以便将目标文件夹放在安装文件夹中,或者您可以将其放在其他位置并镜像 oracle 进程具有的权限在它自己的文件夹中
  • @postgresnewbie 字符转换很棘手,请将此作为新问题提出,并提供更多详细信息
【解决方案2】:

感谢 kevin 分享程序,这对我很有用。我已经自定义了代码:

  1. 在输出 csv 文件中添加列名,这在以前不起作用。
  2. 当我将分隔符作为参数传递时,它会在已更正的每一行 (,1,2,3) 的开头添加逗号。

我还分享了可能对其他人有所帮助的定制代码。自定义代码可以下载here

  1. 添加列名的自定义代码
 FOR i IN t_describe.FIRST .. t_describe.LAST LOOP    
               IF i <> t_describe.LAST THEN          put('UTL_FILE.PUT(v_fh,'''||t_describe(i).col_name||'''||'''||v_delimiter||''');');
       ELSE    
          put('            UTL_FILE.PUT(v_fh,'''||t_describe(i).col_name||''');');    
       END IF;    
       END LOOP;    
       put('            UTL_FILE.NEW_LINE(v_fh);');
  1. 自定义分隔符代码

    如果我 t_describe.LAST THEN
    put(' UTL_FILE.PUT(v_fh,"'||t_describe(i).col_name||'"(i) ||'''||v_delimiter||''');');
    其他
    put('UTL_FILE.PUT(v_fh,"'||t_describe(i).col_name||'"(i));');
    如果结束;

而调用过程的正确方法是将变量与值绑定

data_dump(query_in => 'Select 1 from dual',file_in => 'file.csv',directory_in => 'MY_DIR', delimiter_in => '|' );

谢谢

纳温

【讨论】:

【解决方案3】:
  • 在目录中保存并复制文件{文件不需要可执行}
  • 导出数据库实例的ORACLE_HOME、PATH和SID
  • 导航到该目录并执行 sqlplus
  • 假脱机文件将创建在与 .sql 文件相同的目录中

    SET COLSEP ,
    SET HEADSEP OFF       -- character used when defining a two-line column heading
    SET TRIMSPOOL ON      -- trim trailing spaces from each line
    SET LINESIZE 32000    -- number of characters to be printed on one line
    SET WRAP OFF          -- truncates lines longer than LINESIZE
    SET NUMWIDTH 5        -- default width while displaying numbers
    
    COLUMN tm new_value iso8601 noprint
    SELECT to_char(sysdate, 'YYYY-MM-DD') tm FROM dual;
    
    spool output_file_&iso8601..csv
    -- Append new data to spool file: "spool output_file_&iso8601..csv append"
    
    SELECT
      * 
    FROM
      table_name
    
    spool OFF
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多