การสร้างไฟล์ CSV ต่อ Loop | PLSQL นักพัฒนา Oracle SQL

อัปเดตแล้ว

Rad-คน!

TL;DR

ต้องการโค้ดที่ใช้งานได้เพื่อวนซ้ำรายการที่มีอยู่ของตารางทั้งหมดของฉัน ซึ่งจะสร้างไฟล์ CSV โดยเลือก 100 แถวบนสุดของแต่ละตาราง มีตัวแปรที่ตั้งค่าไว้เพื่อจับชื่อตารางที่จะใช้แบบไดนามิก เรียกตารางเพื่อเลือกและตั้งชื่อไฟล์ ต้องทำผ่าน PLSQL และ SQLDeveloper คุณรู้จักดาแวไหม?

นี่คือสถานการณ์:

  • ต้องรวบรวมตารางทั้งหมด (ตารางฐานไม่ใช่ตารางชั่วคราว) และจำนวนแถว (จำนวนแถว>0)
  • สร้างวงวนเพื่อเลือก(*) 100 แถวบนสุดจากรายการตาราง
  • นำผลลัพธ์ของการสืบค้นมาวางไว้ในไฟล์ CSV

ปัญหา:

  • การประกาศตัวแปร
  • การใช้เริ่มต้นและสิ้นสุด
  • การใช้ชื่อไดนามิกเพื่อสร้างไฟล์ CSV ที่ไม่ซ้ำใคร

นี่คือรหัสของฉัน:

CREATE GLOBAL TEMPORARY TABLE NameRow (nom VARCHAR2(100), rowc INTEGER)
  on commit delete ROWS;
  insert into NameRow(nom, rowc) select table_name, num_rows from user_tables where temporary = 'N' and num_rows > 0;
    --select * from namerow;
    --select count(nom) from namerow;
    --drop table namerow;
    --no need for the row count > 0 because that was already done above
 declare
  counter number := 0;
  totalrecords number := 0;
  nmbre varchar2(100);
 BEGIN

    Select count(nom) into totalrecords from namerow;
    WHILE counter <= totalrecords LOOP
      select nom into nmbre from NameRow where rownum =1;
    SET SPOOL ON
    SPOOL c:\Users\l.r.enchaustegui\Documents\reporepo\||nmbre||.csv
    select /*csv*/ * from HR.nmbre;
    SET SPOOL OFF 
        delete from namerow where rownum=1;
        counter := counter + 1;
    End loop;
 END;

รหัสอธิบาย:

  • ตารางชั่วคราวถูกสร้างขึ้นด้วยคอลัมน์ varchare และจำนวนเต็มเพื่อบันทึกตารางทั้งหมดใน DB ด้วย RowCount
  • ชื่อตารางที่แทรกในตารางชั่วคราวต้องไม่ใช่ชื่อชั่วคราวและมีจำนวนแถวมากกว่า 0

ส่วนถัดไป

  • ประกาศตัวแปร 3 ตัว คือ จำนวนเต็ม 2 ตัว และ varchar 1 ตัว
  • 2 จำนวนเต็ม: 1 เป็นตัวนับสำหรับการวนซ้ำ 1 บันทึกแถวทั้งหมดในตาราง Temp ซึ่งจะทำหน้าที่เป็นการวนซ้ำสูงสุดในลูป
  • Varchar: Nmbre จะบันทึกชื่อของชื่อตารางที่ 1 ภายในตารางชั่วคราว

ส่วนถัดไป

  • เก็บพักในพาธต่อไปนี้ โดยใช้ตัวแปร Nmbre เพื่อตั้งชื่อไฟล์ CSV แบบไดนามิก
  • Spool Query โดยใช้ตัวแปร Nmbre เพื่อเลือกตารางแบบไดนามิก
  • ลบแถวที่ 1 ออกจากตารางชั่วคราว [ทำหน้าที่หมุนเป็นชื่อตารางถัดไป]
  • สปูลปิด
  • วนซ้ำ
  • สิ้นสุดวง; จบ;

ฉันผิดตรงไหน? นอกจากนี้ ฉันได้รับข้อผิดพลาดนี้:

รอบโบนัส: จำกัดเฉพาะนักพัฒนา SQL


person ThereIsLeo    schedule 20.02.2018    source แหล่งที่มา
comment
คุณสามารถใช้ SQLcl ซึ่งเป็นคอร์ของ sqldev เป็นบรรทัด cmd ได้หรือไม่?   -  person Kris Rice    schedule 20.02.2018
comment
คุณไม่สามารถติดคำสั่ง sqlplus ที่ฝังอยู่ในคำสั่ง sql ได้ ตัวเลือกอื่นคือใช้ UTL_FILE สำหรับไฟล์ i/o แต่ไฟล์จะถูกสร้างขึ้นบนเซิร์ฟเวอร์ ไม่ใช่เวิร์กสเตชันของคุณ   -  person OldProgrammer    schedule 20.02.2018
comment
@KrisRice ฉันแน่ใจว่าฉันทำได้ คุณเห็นว่าวิธีแก้ปัญหาใดเกิดขึ้น   -  person ThereIsLeo    schedule 20.02.2018
comment
@OldProgrammer ฉันขอโทษฉันค่อนข้างใหม่กับ PLSQL ฉันฝังคำสั่ง SQLPLUS อะไรไว้ คุณเห็นภาพโซลูชันโดยใช้ UTL_FILE ได้อย่างไร   -  person ThereIsLeo    schedule 20.02.2018
comment
นี่คือการบ้านที่ได้รับมอบหมายใช่ไหม?   -  person Stilgar    schedule 20.02.2018
comment
คำสั่งสปูลคือ SQL*Plus   -  person William Robertson    schedule 20.02.2018
comment
ด้วย sqlcl คุณสามารถมิกซ์แมตช์ได้มากขึ้นอีกเล็กน้อย มิฉะนั้นในฐานะ @OldProgrammer คุณมีรหัสไคลเอนต์ที่ตรงกันใน plsql ซึ่งจะไม่ทำงาน   -  person Kris Rice    schedule 20.02.2018
comment
@Stilgar นั่นเป็นเชิงลบ ทำงานเล็กๆ น้อยๆ (สกปรก) กับทีมที่ทำ ETL ฉันค่อนข้างใหม่กับ PLSQL และใช้ทรัพยากรไปมากมายในการพยายามไขปริศนานี้   -  person ThereIsLeo    schedule 20.02.2018
comment
ฉันยังพบว่าตัวเองไม่สามารถแก้ไขปัญหานี้ได้ :(   -  person ThereIsLeo    schedule 21.02.2018


คำตอบ (1)


นี่คือตัวเลือกที่ใช้ SQLcl SQLcl คือความกล้าของ SQLDEV แต่รวมอยู่ในบรรทัด cmd นอกจากนี้ การเป็นจาวายังมีความสามารถในการเขียนสคริปต์ของคอร์จาวาอีกด้วย นี่คือการใช้ JavaScript เป็นเครื่องมือสร้างสคริปต์

เรามีเอกสารและตัวอย่างมากมายเกี่ยวกับวิธีการทำงานทั้งหมดนี้บน github ที่นี่: https://github.com/oracle/oracle-db-tools/tree/master/sqlcl

script
 var binds = {};

// get complete list of tables
 var tables = util.executeReturnList("select table_name from user_tables", binds);

 for (i = 0; i < tables.length; i++) {
   // get count of rows
    var rows = util.executeReturnOneCol('select count(1)  from ' +  tables[i].TABLE_NAME );
    ctx.write( tables[i].TABLE_NAME + ">>"  + rows + " \n" ) ;

    // if more than zero dump to a csv file
    if ( rows > 0 ){
        sqlcl.setStmt("set sqlformat csv ")
        sqlcl.run();
        sqlcl.setStmt("spool " + tables[i].TABLE_NAME + ".csv")
        sqlcl.run();

        sqlcl.setStmt("select * from  " + tables[i].TABLE_NAME )
        sqlcl.run();
        sqlcl.setStmt("spool off")
        sqlcl.run();

    }
 }
/
person Kris Rice    schedule 20.02.2018
comment
ขอบคุณคริส ฉันจะพยายามคลุมหัวเรื่องนี้ - person ThereIsLeo; 21.02.2018
comment
แน่นอน. มันแตกต่างออกไปโดยเฉพาะอย่างยิ่งเมื่อการเพิ่มโฟลว์การควบคุมไคลเอนต์เป็นการเปลี่ยนแปลงที่สำคัญจาก PLSQL 100% - person Kris Rice; 21.02.2018
comment
แม้ว่าฉันจะไร้ความสามารถในปัจจุบันก็ตาม ขอบคุณสำหรับการสนับสนุนของคุณ! - person ThereIsLeo; 21.02.2018
comment
นั่นคือสิ่งที่เรามาที่นี่เพื่อ :) - person Kris Rice; 21.02.2018