简体   繁体   中英

Export single table as csv file, syntax, SQL Developer

I have looked at asktom, and thatjeffsmith, and on this site, but I still unclear. It is confusing b/c in other tools I have used it is very simple.

I have a script that creates a small table from the data in my database (Oracle), I want to include syntax at the end of the script that exports the table I just created to my computer as a csv file. I would prefer to have this at the end of the script as opposed to a stored procedure or anything like that, b/c I have to frequently change where I save the csv files, and I'd just prefer to do it that way.

Something like:

SELECT /*csv*/ *
FROM table_name
EXPORT/OUTPUT/SAVE TO filepath.csv

I can do this with R, SPSS, STATA, SAS, in a line or two. Something like that is what I am looking for. I think I might need to specify format, quotes, header, or delimiter, but am not sure given the csv modifier in the SELECT statement. I feel like this is day 2 stuff but for some reason I cannot find a simple answer.

Thank you in advance.

Create a package like below

    CREATE OR REPLACE PACKAGE APPS.csv AS

PROCEDURE generate (p_dir        IN  VARCHAR2,
                    p_file       IN  VARCHAR2,
                    p_query      IN  VARCHAR2);

PROCEDURE generate_rc (p_dir        IN  VARCHAR2,
                       p_file       IN  VARCHAR2,
                       p_refcursor  IN OUT SYS_REFCURSOR);

PROCEDURE set_separator (p_sep  IN  VARCHAR2);

END csv;
/

CREATE OR REPLACE PACKAGE BODY APPS.csv AS


g_sep         VARCHAR2(5)  := ',';

-- Prototype for hidden procedure.
PROCEDURE generate_all (p_dir        IN  VARCHAR2,
                        p_file       IN  VARCHAR2,
                        p_query      IN  VARCHAR2,
                        p_refcursor  IN OUT SYS_REFCURSOR);


-- Stub to generate a CSV from a query.
PROCEDURE generate (p_dir        IN  VARCHAR2,
                    p_file       IN  VARCHAR2,
                    p_query      IN  VARCHAR2) AS
  l_cursor  SYS_REFCURSOR;
BEGIN
  generate_all (p_dir        => p_dir,
                p_file       => p_file,
                p_query      => p_query,
                p_refcursor  => l_cursor);
END generate;


-- Stub to generate a CVS from a REF CURSOR.
PROCEDURE generate_rc (p_dir        IN  VARCHAR2,
                       p_file       IN  VARCHAR2,
                       p_refcursor  IN OUT SYS_REFCURSOR) AS
BEGIN
  generate_all (p_dir        => p_dir,
                p_file       => p_file,
                p_query      => NULL,
                p_refcursor  => p_refcursor);
END generate_rc;


-- Do the actual work.
PROCEDURE generate_all (p_dir        IN  VARCHAR2,
                        p_file       IN  VARCHAR2,
                        p_query      IN  VARCHAR2,
                        p_refcursor  IN OUT  SYS_REFCURSOR) AS
  l_cursor    PLS_INTEGER;
  l_rows      PLS_INTEGER;
  l_col_cnt   PLS_INTEGER;
  l_desc_tab  DBMS_SQL.desc_tab;
  l_buffer    VARCHAR2(32767);

  l_file      UTL_FILE.file_type;
BEGIN
  IF p_query IS NOT NULL THEN
    l_cursor := DBMS_SQL.open_cursor;
    DBMS_SQL.parse(l_cursor, p_query, DBMS_SQL.native);
  ELSIF p_refcursor%ISOPEN THEN
     l_cursor := DBMS_SQL.to_cursor_number(p_refcursor);
  ELSE
    RAISE_APPLICATION_ERROR(-20000, 'You must specify a query or a REF CURSOR.');
  END IF;

  DBMS_SQL.describe_columns (l_cursor, l_col_cnt, l_desc_tab);

  FOR i IN 1 .. l_col_cnt LOOP
    DBMS_SQL.define_column(l_cursor, i, l_buffer, 32767 );
  END LOOP;

  IF p_query IS NOT NULL THEN
    l_rows := DBMS_SQL.execute(l_cursor);
  END IF;

  l_file := UTL_FILE.fopen(p_dir, p_file, 'w', 32767);

  -- Output the column names.
  FOR i IN 1 .. l_col_cnt LOOP
    IF i > 1 THEN
      UTL_FILE.put(l_file, g_sep);
    END IF;
    UTL_FILE.put(l_file, l_desc_tab(i).col_name);
  END LOOP;
  UTL_FILE.new_line(l_file);

  -- Output the data.
  LOOP
    EXIT WHEN DBMS_SQL.fetch_rows(l_cursor) = 0;

    FOR i IN 1 .. l_col_cnt LOOP
      IF i > 1 THEN
        UTL_FILE.put(l_file, g_sep);
      END IF;

      DBMS_SQL.COLUMN_VALUE(l_cursor, i, l_buffer);
      UTL_FILE.put(l_file, l_buffer);
    END LOOP;
    UTL_FILE.new_line(l_file);
  END LOOP;

  UTL_FILE.fclose(l_file);
  DBMS_SQL.close_cursor(l_cursor);
EXCEPTION
  WHEN OTHERS THEN
    IF UTL_FILE.is_open(l_file) THEN
      UTL_FILE.fclose(l_file);
    END IF;
    IF DBMS_SQL.is_open(l_cursor) THEN
      DBMS_SQL.close_cursor(l_cursor);
    END IF;
    DBMS_OUTPUT.put_line('ERROR: ' || DBMS_UTILITY.format_error_backtrace);
    RAISE;
END generate_all;


-- Alter separator from default.
PROCEDURE set_separator (p_sep  IN  VARCHAR2) AS
BEGIN
  g_sep := p_sep;
END set_separator;

END csv;
/

CREATE A DIRECTORY IN DATABASE LIKE THIS

CREATE OR REPLACE DIRECTORY EXTRACT_DIR AS 'c:\oracle\extract';
GRANT READ, WRITE ON DIRECTORY EXTRACT_DIR TO SCOTT;
GRANT EXECUTE ON UTL_FILE TO SCOTT;


EXEC csv.generate('EXTRACT_DIR', 'emp.csv', p_query => 'SELECT * FROM emp');

Hope this help to Extract a table data into csv at desired location

This is as close as I could get to answering my own question.

SET FEEDBACK OFF
SELECT /*csv*/
    var1, var2, var3...varX
FROM 
    tablename;

Run as script (F5) in Oracle, it will produce script output in csv format, without producing any notes or documentation inside output. From there, click small disk icon, save as 'all files' and add .csv extension to end of filename.

...I'm pretty surprised there isn't a 2-3 line snippet of syntax that outputs the result of a query or script as formatX in locationY. But I guess there isn't.

Thank you to those who posted comments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM