ORACLE學習之PL/SQL編程——本地動態SQL

来源:http://www.cnblogs.com/shizhongxing/archive/2016/01/19/3284611.html
-Advertisement-
Play Games

目錄讀前註意與概述動態SQL簡介使用EXCUTE IMMEDIATE語句處理DDL和DCL語句處理DML語句處理單行查詢處理多行查詢在動態SQL中使用批量綁定讀前註意與概述 當編寫PL/SQL塊時,靜態SQL語句只能完成一些固定任務。為了使得PL/SQL塊可以靈活的處理SQL語句,需要使用動態SQ....


目錄

  • 讀前註意與概述
  • 動態SQL簡介
  • 使用EXCUTE IMMEDIATE語句
    1. 處理DDL和DCL語句
    2. 處理DML語句
    3. 處理單行查詢
  • 處理多行查詢
  • 在動態SQL中使用批量綁定

讀前註意與概述

  當編寫PL/SQL塊時,靜態SQL語句只能完成一些固定任務。為了使得PL/SQL塊可以靈活的處理SQL語句,需要使用動態SQL。動態SQL包括本地動態SQL和DBMS_SQL動態SQL兩種實現方法,其中本地動態SQL只適用於oracle伺服器端,而DBMS_SQL動態SQL不僅適用於oracle伺服器端,而且可以在某些客戶端應用程式中使用。從oracle 11g開始,允許使用超過32Kb的本地動態SQL語句。本節學習任務:

  • 學會使用本地動態SQL處理DDL、DCL、和DML語句。
  • 學會使用本地動態SQL處理查詢語句。
  • 學會在本地動態SQL中使用批量綁定。

 

動態SQL簡介

  • 靜態SQL:指直接嵌入在PL/SQL塊中的SQL語句,用於完成特定的或相對固定的任務。

      例如:簡單的CRUD操作

      SELECT * FROM emp_learn WHERE employee_id=v_eno;

      INSERT INTO emp_learn (employee_id,first_name) VALUES (v_eid,v_name);

      UPDATE emp_learn SET salary=salary*1.1 WHERE first_name=v_name;

      DELETE FROM emp_learn WHERE employee_id=v_eid;

  • 動態SQL:指在執行PL/SQL塊時動態輸入的SQL語句。當在PL/SQL塊中嵌入DDL或者DCL語句時,必須使用動態SQL。另外,如果需要執行更加靈活的select和DML語句(爆好占位符“:”冒號開始),也需要使用動態SQL.

      CREATE TABLE temp(col1 INT,col2 VARCHAR2(20));--DDL

      GRANT SELECT ON emp_learn TO smith;--DCL

      DELETE FROM emp_learn WHERE salary>:a;--帶有占位符

      SELECT first_name,salary FROM emp_learn WHERE employee_id=:1;--帶有占位符

  • 比較靜態和動態SQL

      a)靜態SQL是在編寫PL/SQL塊時直接嵌入的SQL語句,動態SQL是在執行PL/SQL塊時動態輸入的SQL語句。

      b)靜態SQL性能優於動態SQL。因此當編寫PL/SQL塊時,如果功能完全確定,則使用靜態SQL;如果不能確定要執行的SQL語句,則使用動態SQL。

  • 動態SQL處理方法

      a)使用EXECUTE IMMEDIATE語句:用於處理 除多行查詢之外的任何其他動態SQL,包括DDL語句、DCL語句、DML語句以及單行SELECT語句。

      b)使用OPEN-FOR、FETCH和CLOSE語句:用於處理多行查詢操作。

      c)使用批量動態SQL:用於加快SQL語句處理,提高PL/SQL的性能。

 

使用EXCUTE IMMEDIATE語句

  • 處理DDL、DCL和無占位符和returning的DML語句,語法:  

    EXCUTE IMMEDIATE dyn_string;

    dyn_string指定存放DDL、DCL或者DML的語句。

  示例:

DECLARE
   ddl_string VARCHAR2(200):='&ddl_string';--DDL
   dcl_string VARCHAR2(200):='&dcl_string';--DCL
   dml_string VARCHAR2(200):='&dml_string';--DML
BEGIN
   EXECUTE IMMEDIATE ddl_string; 
   EXECUTE IMMEDIATE dcl_string; 
   EXECUTE IMMEDIATE dml_string; 
END;

  • 處理包含占位符的DML語句語法:

   EXCUTE IMMEDIATE dyn_string USING bind_arg1 [,bind_arg2,...]

  • 處理包含returning into子句的DML語句(只能接收單行數據,否則需使用批量綁定)語法:

   EXCUTE IMMEDIATE dyn_string RETURNING INTO variable1 [, variable2,...];

1 DECLARE
2    dml_string VARCHAR2(200):='UPDATE emp_learn SET salary=:sal WHERE LOWER(first_name)=LOWER(:name) RETURNING salary INTO :newsal';
3    v_newsal emp_learn.salary%TYPE;
4 BEGIN
5    EXECUTE IMMEDIATE dml_string USING &1,'&2' RETURNING INTO v_newsal;
6    dbms_output.put_line('新工資為:'||v_newsal); 
7 END;

 

  • 處理單行查詢,語法:

    EXCUTE IMMEDIATE dyn_string INTO variable1 [,variable2,...] [USING bing_arg1 [,bind_arg2,...]];

  示例:處理單行查詢

DECLARE
   v_select1 VARCHAR2(200):='SELECT * FROM emp_learn WHERE employee_id=&eno';
   v_select2 VARCHAR2(200):='SELECT * FROM emp_learn WHERE employee_id=:eno';
   emp_record emp%ROWTYPE;
BEGIN
   EXECUTE IMMEDIATE v_select1 INTO emp_record;
   dbms_output.put_line('姓名:'||emp_record.first_name||',職位:'||emp_record.job_id);
   EXECUTE IMMEDIATE v_select2 INTO emp_record  USING &1;
   dbms_output.put_line('姓名:'||emp_record.first_name||',職位:'||emp_record.job_id);
END;

 

處理多行查詢

   EXCUTE IMMEDIATE只能用於處理單行查詢,為了動態處理select語句所返回的多行數據,需要定義游標變數,並使用open for、fetch和close語句共同完成,步驟:

    a)定義游標變數:TYPE cursor_type IS REF CURSOR;

              cursor_var cursor_type;

    b)打開游標變數獲取結果集:OPEN cursor_var FOR dyn_string [USING bind_args];

    c)提取數據:FETCH cursor_var INTO vars;

    d)關閉游標變數:CLOSE cursor_var;  

  示例:處理多行查詢

DECLARE
   TYPE emp_cursor_type IS REF CURSOR;
   emp_cursor emp_cursor_type;
   emp_record emp_learn%ROWTYPE;
   v_string VARCHAR2(200):='SELECT * FROM emp_learn WHERE department_id=:dno';
BEGIN
   OPEN emp_cursor FOR v_string USING &1;
   LOOP
       FETCH emp_cursor INTO emp_record;
       EXIT WHEN emp_cursor%NOTFOUND;
       dbms_output.put_line('雇員名:'||emp_record.first_name);
   END LOOP;
   CLOSE emp_cursor;
END;

 

在動態SQL中使用批量綁定

  使用在動態SQL中使用批量綁定,可以加快批量數據的處理速度,提高性能。需要註意的是:使用批量綁定時,集合元素需要使用SQL固有數據類型(例如number、char等),而不能使用PL/SQL特有的數據類型(例如BINARY_INTGER、BOOLEAN等)。

  • 在動態DML上使用批量綁定,語法:

    FORALL index IN lower_boud..upper_bound

        EXECUTE IMMEDIATE dyn_string ...;

DECLARE
   TYPE name_table_type IS TABLE OF emp.first_name%TYPE;
   emp_name_table name_table_type:=name_table_type('&name1','&name2','&name3');
   dml_string VARCHAR2(100):='UPDATE emp_learn SET salary=salary*1.2 WHERE LOWER (first_name)=LOWER(:1)';
BEGIN
   FORALL i IN 1..emp_name_table.count
      EXECUTE IMMEDIATE dml_string USING emp_name_table(i);
END;
  • 批量綁定查詢、在DML返回子句上使用批量綁定

    批量綁定查詢語法:EXECUTE IMMEDIATE dyn_string BULK COLLECT INTO collect_vars;

    在DML返回子句上使用批量綁定語法:EXECUTE IMMEDIATE dyn_string RETURNING BULK COLLECT INTO collect_vars;

 1 DECLARE
 2    TYPE emp_name_table_type IS TABLE OF emp_learn.first_name%TYPE;
 3    TYPE enp_sal_table_type  IS TABLE OF emp_learn.salary%TYPE;
 4    emp_name_table emp_name_table_type;--裝雇員名
 5    emp_sal_table enp_sal_table_type;  --裝工資
 6    v_deptno NUMBER:=&dno;
 7    c_string VARCHAR2(100):='SELECT first_name,salary FROM emp_learn WHERE department_id='||v_deptno;
 8    dml_string VARCHAR(150):=
 9       'UPDATE emp_learn SET salary=salary*1.1 WHERE department_id=:1 RETURNING first_name,salary INTO :2,:3';
10 BEGIN
11    EXECUTE IMMEDIATE c_string BULK COLLECT INTO emp_name_table,emp_sal_table;--裝載更新前的雇員名和工資
12    FOR i IN 1..emp_name_table.count LOOP
13       dbms_output.put_line('雇員:'||emp_name_table(i)||',前工資:'||emp_sal_table(i));
14    END LOOP;
15    EXECUTE IMMEDIATE dml_string USING v_deptno RETURNING BULK COLLECT INTO emp_name_table,emp_sal_table;--執行更新並返回數據
16    FOR i IN 1..emp_name_table.count LOOP
17       dbms_output.put_line('雇員:'||emp_name_table(i)||',後工資:'||emp_sal_table(i));
18    END LOOP;
19 END;
  • 在fetch語句章使用批量提取

    這個功能可以一次性提取游標結果集中的所有數據,很方便哦,使用一次後我就喜歡上它了,語法:

    FETCH cursor_var BULK COLLECT INTO collect_var;

 1 DECLARE
 2    TYPE emp_name_cursor_type IS REF CURSOR;
 3    TYPE emp_name_table_type  IS TABLE OF emp_learn.first_name%TYPE;
 4    emp_name_cursor emp_name_cursor_type;
 5    emp_name_table  emp_name_table_type;
 6    c_string VARCHAR2(150):='SELECT first_name FROM emp_learn WHERE department_id=:1';
 7 BEGIN
 8    OPEN emp_name_cursor FOR c_string USING '&dno';
 9    FETCH emp_name_cursor BULK COLLECT INTO emp_name_table;
10    CLOSE  emp_name_cursor;
11    FOR i IN 1..emp_name_table.count LOOP
12       dbms_output.put_line('名字:'||emp_name_table(i));
13    END LOOP;
14 END;

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • iOS開發大部分情況下會使用到導航欄,由於我司的app導航欄需要與下麵緊挨著的視窗顏色一致,導航欄底部的橫線就會影響這個美觀,LZ使用了以下方法。覺得不錯,分享來給小伙伴們。1)聲明UIImageView變數,存儲底部橫線@interface MyViewController { UIImag...
  • ExpandableListView(可摺疊的列表)一、ExpandableListView(可摺疊的列表)和ListView有很多地方差不多的,使用也差不多,只是他們使用適配器不一樣的,ExpandableListView使用的是ExpandableAdapter適配器,常用的有BaseExpan...
  • 近日學習了延遲執行的幾種方法,分享一下. 1.performSelector(NSObject)方法 2.NSTimer方法 3.GCD方法 4.sleep(NSThread)方法延遲執行代碼:- (void)delayDo : (id)sender { NSLog(@"do:%@",send...
  • 如上圖右上角,菜單選項的編輯,第一種代碼實現方式如下:package com.example.menu;import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view....
  • 一、快速提高Android開發效率的Web工具在Google的廣大支持下,便捷開發Android程式的Native工具層出不窮。其實Android開發涉及到的範圍也不小,一些Web工具有時候也會帶來事半功倍的效果。二、Android App 性能優化實踐本文記錄了Android App優化需要用到的...
  • TabLayout——選項卡佈局,通過選項卡的方式切換view並不是material design中才有的新概念,選項卡既可以固定,也可以滾動顯示效果如下: 通過addTab方法可以實現選項卡的動態添加:tabLayout.addTab(tabLayout.newTab().setText...
  • 不管怎樣,我相信,每一個我遇到的難題,對我來說都是一次提升的機會。 作為一隻C++,混SQL群壓力還是蠻大的。
  • 1.http://www.cnblogs.com/huangxincheng/archive/2012/02/18/2356595.html
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...