PLSQL==》本地動態SQL

1.EXECUTE IMMEDIATE 語句:在執行前才解析動態SQL語句或者PLSQL語句塊。

DECLARE

    sql_stmt         VARCHAR2(100);
    plsql_block      VARCHAR2(300);
    v_zip            VARCHAR2(5) := '11106';
    v_total_students NUMBER;
    v_new_zip        VARCHAR2(5);
    v_student_id     NUMBER := 151;
BEGIN
    --create table MY_STUDENT
    sql_stmt := 'CREATE TABLE MY_STUDENT ' ||
                'AS SELECT * FROM STUDENT WHERE ZIP= ' || v_zip;
    EXECUTE IMMEDIATE sql_stmt;
    --select total number of records from my.student table
    --add display results on the screen
    EXECUTE IMMEDIATE 'select count(*) from MY_STUDENT'
        INTO v_total_students;
    dbms_output.put_line('Students added: ' || v_total_students);
    --select current date and display it on the screen
    plsql_block := 'declare ' || 'v_date date;' || 'begin ' ||
                   'select sysdate into v_date from dual;' ||
                   'dbms_output.put_line(to_char(v_date,''dd-mon-yyyy''));' ||
                   'end;';
    --dbms_output.put_line(plsql_block);
    EXECUTE IMMEDIATE plsql_block;
    --update record in my_student table
    sql_stmt := 'update my_student set zip=11105 where student_id=:1' ||
                'returning zip into :2';
    EXECUTE IMMEDIATE sql_stmt
        USING v_student_id
        RETURNING INTO v_new_zip;
    dbms_output.put_line('New zip code: ' || v_new_zip);

END;

BEGIN
    --drop table my_student
    --EXECUTE IMMEDIATE 'DROP TABLE MY_student';
    --create table MY_STUDENT
    sql_stmt := 'CREATE TABLE MY_STUDENT ' ||
                'AS SELECT * FROM STUDENT WHERE ZIP= :zip';
    EXECUTE IMMEDIATE sql_stmt
        USING v_zip;
    --select total number of records from my.student table
    --add display results on the screen
    EXECUTE IMMEDIATE 'select count(*) from MY_STUDENT'
        INTO v_total_students;
    dbms_output.put_line('Students added: ' || v_total_students);
 18  END;
 19  /
DECLARE
*
ERROR at line 1:
ORA-01027: bind variables not allowed for data definition operations --create table 是DDL語句,他不接受任何綁定參數;

ORA-06512: at line 11

修改如下:

DECLARE
    sql_stmt         VARCHAR2(100);
    v_zip            VARCHAR2(5) := '11106';
    v_total_students NUMBER;
BEGIN
    --drop table my_student
    EXECUTE IMMEDIATE 'DROP TABLE MY_student';
    --create table MY_STUDENT
    sql_stmt := 'CREATE TABLE MY_STUDENT ' ||
                'AS SELECT * FROM STUDENT WHERE ZIP= ' || v_zip;
    EXECUTE IMMEDIATE sql_stmt;
    --select total number of records from my.student table
    --add display results on the screen
    EXECUTE IMMEDIATE 'select count(*) from MY_STUDENT'
        INTO v_total_students;
    dbms_output.put_line('Students added: ' || v_total_students);
END;


動態SQL結尾不應該是分號;

BEGIN
    --drop table my_student
    --EXECUTE IMMEDIATE 'DROP TABLE MY_student';
    --create table MY_STUDENT
    sql_stmt := 'CREATE TABLE MY_STUDENT ' ||
                'AS SELECT * FROM STUDENT WHERE ZIP= ' || v_zip;
    EXECUTE IMMEDIATE sql_stmt;
    --select total number of records from my.student table
    --add display results on the screen
    EXECUTE IMMEDIATE 'select count(*) from MY_STUDENT;'
        INTO v_total_students;
    dbms_output.put_line('Students added: ' || v_total_students);
 17  END;
 18  /
DECLARE
*
ERROR at line 1:
ORA-00911: invalid character
ORA-06512: at line 14


DECLARE
    sql_stmt VARCHAR2(100);
BEGIN
    sql_stmt := 'update course' || ' set prerequisite=:some_value';
    EXECUTE IMMEDIATE sql_stmtl
        USING NULL;
END;
  6    7    8  
  9  /
    EXECUTE IMMEDIATE sql_stmtl
                      *
ERROR at line 5:
ORA-06550: line 5, column 23:
PLS-00201: identifier 'SQL_STMTL' must be declared

ORA-06550: line 5, column 5:
PL/SQL: Statement ignored


DECLARE
    sql_stmt VARCHAR2(100);
    v_null   VARCHAR2(1);
BEGIN
    sql_stmt := 'update course' || ' set prerequisite=:some_value';
    EXECUTE IMMEDIATE sql_stmt
        USING v_null;
END;


DECLARE
    sql_stmt     VARCHAR2(200);
    v_student_id NUMBER := &sv_student_id;
    v_first_name VARCHAR2(25);
    v_last_name  VARCHAR2(25);
BEGIN
    sql_stmt := 'select first_name,last_name' || ' from student' ||
                ' where student_id=:1';
    EXECUTE IMMEDIATE sql_stmt
        INTO v_first_name, v_last_name
        USING v_student_id;
    dbms_output.put_line('First Name: ' || v_first_name);
    dbms_output.put_line('Last Name: ' || v_last_name);
END;


輸出更多的信息:

DECLARE
    sql_stmt     VARCHAR2(200);
    v_student_id NUMBER := &sv_student_id;
    v_first_name VARCHAR2(25);
    v_last_name  VARCHAR2(25);
    v_street     VARCHAR2(50);
    v_city       VARCHAR2(25);
    v_state      VARCHAR2(2);
    v_zip        VARCHAR2(5);
BEGIN
    sql_stmt := 'select a.first_name,a.last_name,a.street_address,b.city,b.state,b.zip' ||
                ' from student a,zipcode b' || '
    where a.zip=b.zip' || ' and student_id=:1';
    EXECUTE IMMEDIATE sql_stmt
        INTO v_first_name, v_last_name, v_street, v_city, v_state, v_zip
        USING v_student_id;
    dbms_output.put_line('First Name: ' || v_first_name);
    dbms_output.put_line('Last Name: ' || v_last_name);
    dbms_output.put_line('Steet: ' || v_street);
    dbms_output.put_line('City: ' || v_city);
    dbms_output.put_line('State: ' || v_state);
    dbms_output.put_line('Zip Code: ' || v_zip);
END;


OPEN-FOR ,FETCH,CLOSE:

  DECLARE
      TYPE student_cur_type IS REF CURSOR;
      student_cur  student_cur_type;
      v_zip        VARCHAR2(5) := '&sv_zip';
      v_first_name VARCHAR2(25);
      v_last_name  VARCHAR2(25);
  BEGIN
      OPEN student_cur FOR 'select first_name,last_name from student' || ' where zip=:1'
          USING v_zip;
      LOOP
          FETCH student_cur
              INTO v_first_name, v_last_name;
          EXIT WHEN student_cur%NOTFOUND;
          dbms_output.put_line('First Name: ' || v_first_name);
          dbms_output.put_line('Last Name: ' || v_last_name);
      END LOOP;
      CLOSE student_cur;
  EXCEPTION
      WHEN OTHERS THEN
          IF student_cur%ISOPEN
          THEN
              CLOSE student_cur;
          END IF;
          dbms_output.put_line('ERROR: ' || substr(SQLERRM, 1, 200));
  END;

同時使用open for,fetch和close語句:

DECLARE
    TYPE zip_cur_type IS REF CURSOR;
    zip_cur  zip_cur_type;
    sql_stmt VARCHAR2(500);
    v_zip    VARCHAR2(5);
    v_total  NUMBER;
    v_count  NUMBER;
BEGIN
    sql_stmt := 'select zip,count(*) total' || ' from student ' ||
                'group by zip';
    v_count  := 0;
    OPEN zip_cur FOR sql_stmt;
    LOOP
        fetch zip_cur
            INTO v_zip, v_total;
        EXIT WHEN zip_cur%NOTFOUND;
        v_count := v_count + 1;
        IF v_count <= 10
        THEN
            dbms_output.put_line('Zip code: ' || v_zip || ' Total: ' ||
                                 v_total);
        END IF;
    END LOOP;


    CLOSE zip_cur;
EXCEPTION
    WHEN OTHERS THEN
        IF zip_cur%ISOPEN
        THEN
            CLOSE zip_cur;
        END IF;
        dbms_output.put_line('ERROR: ' || substr(SQLERRM, 1, 200));
END;



DECLARE
    TYPE zip_cur_type IS REF CURSOR;
    zip_cur      zip_cur_type;
    sql_stmt     VARCHAR2(500);
    v_table_name VARCHAR2(20) := '&sv_table_name';
    TYPE zip_rec_type IS RECORD(
        zip   VARCHAR2(5),
        total NUMBER);
    zip_rec zip_rec_type;
    v_count NUMBER;
BEGIN
    dbms_output.put_line('Totals from ' || v_table_name || ' talbe');


    sql_stmt := 'select zip,count(*) total' || ' from ' || v_table_name || '  ' ||
                'group by zip';
    v_count  := 0;
    OPEN zip_cur FOR sql_stmt;
    LOOP
        FETCH zip_cur
            INTO zip_rec;
        EXIT WHEN zip_cur%NOTFOUND;
        v_count := v_count + 1;
        IF v_count <= 10
        THEN
            dbms_output.put_line('Zip code: ' || zip_rec.zip || ' Total: ' ||
                                 zip_rec.total);
        END IF;
    END LOOP;


    CLOSE zip_cur;
EXCEPTION
    WHEN OTHERS THEN
        IF zip_cur%ISOPEN
        THEN
            CLOSE zip_cur;
        END IF;
        dbms_output.put_line('ERROR: ' || substr(SQLERRM, 1, 200));
END;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章