存儲過程預處理
『壹』 如何:使用存儲過程執行查詢(實體框架)
許多應用程序開發人員和資料庫管理員都使用存儲過程來增強安全性、提供可預測性以及對資料庫內的數據封裝邏輯。檢索映射到存儲過程的數據的應用程序代碼使用由 FunctionImport 元素標識的函數。如何:使用存儲過程定義模型(實體框架) 中介紹了將存儲過程映射到實體數據模型 (EDM) 實現所需的架構語法的基本元素。EDM 支持兩種存儲過程映射。有關映射用於更新數據的存儲過程的更多信息,請參見存儲過程支持(實體框架)。本主題中的示例基於 Adventure Works 銷售模型。若要運行本示例中的代碼,必須已將 AdventureWorks 銷售模型添加到您的項目中,並將項目配置為使用實體框架。為此,請完成如何:手動配置實體框架項目和如何:手動定義實體數據模型(實體框架) 中的過程。此架構中定義了五個實體:以下步驟實現一個客戶端應用程序,以及一段執行存儲過程的代碼,該存儲過程映射到數據模型的概念架構中的 GetOrderDetailsFunctionImport。該函數檢索與給定 SalesOrderHeader 相關的 SalesOrderDetail 實體。(此模型中的 FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID 關聯可以實現與此示例相同的功能。)在資料庫中創建存儲過程創建控制台應用程序。添加對主題如何:使用存儲過程定義模型(實體框架)中實現的 dll 的引用。添加對 System.Data.Entity 和System.Runtime.Serialization 的引用。為在如何:使用存儲過程定義模型(實體框架)中實現的 AdventureWorksModel 添加預處理器指令。示例存儲過程中使用了 SalesOrderHeaderId 所需的參數。在對象瀏覽器中可以找到該語法(AdventureWorksEntities 命名空間中的方法:GetOrderDetails(int)。)下面的代碼運行存儲過程來返回結果,這些結果隨後在 foreach 循環中枚舉。C#VBOptionExplicitOnOption Strict OnImports System Imports System.Collections.Generic Imports System.Linq Imports System.Text Imports AdvWrksSalesModel Mole Mole1 Sub Main() TryUsing db As AdvWksSalesEntities = New AdvWksSalesEntities() Dim soHeaderNumber AsInteger = 43659 ForEachorderAs SalesOrderDetail _ In db.GetOrderDetails(soHeaderNumber) Console.WriteLine("Header#: {0} " & _ "Order#: {1} ProctID: {2} Quantity: {3} Price: {4}", _ soHeaderNumber, order.SalesOrderDetailID, order.ProctID, _ order.OrderQty, order.UnitPrice) NextEndUsingCatch ex As System.Data.MappingException Console.WriteLine(ex.ToString()) Catch ex As System.Data.CommandExecutionException Console.WriteLine(ex.ToString()) EndTryEndSubEndMole輸出結果將如下所示: Header#: 43659 Order#: 1 ProctID: 776 Quantity: 1 Price: 2024.9940 Header#: 43659 Order#: 2 ProctID: 777 Quantity: 3 Price: 2024.9940 Header#: 43659 Order#: 3 ProctID: 778 Quantity: 1 Price: 2024.9940 Header#: 43659 Order#: 4 ProctID: 771 Quantity: 1 Price: 2039.9940 Header#: 43659 Order#: 5 ProctID: 772 Quantity: 1 Price: 2039.9940 Header#: 43659 Order#: 6 ProctID: 773 Quantity: 2 Price: 2039.9940 Header#: 43659 Order#: 7 ProctID: 774 Quantity: 1 Price: 2039.9940 Header#: 43659 Order#: 8 ProctID: 714 Quantity: 3 Price: 28.8404 Header#: 43659 Order#: 9 ProctID: 716 Quantity: 1 Price: 28.8404 Header#: 43659 Order#: 10 ProctID: 709 Quantity: 6 Price: 5.7000 Header#: 43659 Order#: 11 ProctID: 712 Quantity: 2 Price: 5.1865 Header#: 43659 Order#: 12 ProctID: 711 Quantity: 4 Price: 20.1865 另請參見任務如何:使用存儲過程定義模型(實體框架)概念AdventureWorks 銷售模型 (EDM)存儲過程支持(實體框架)ModificationFunctionMapping (EntityTypeMapping)ModificationFunctionMapping (AssociationSetMapping)
『貳』 預處理與存儲過程的含義,二者什麼區別程序中預處理只在insert時用嗎存儲過程一般什麼時候用
許多成熟的資料庫都支持預處理語句(Prepared Statements)的概念。它們是什麼東西?
你可以把它們想成是一種編譯過的要執行的sql語句模板,
可以使用不同的變數參數定製它。預處理語句具有兩個主要的優點:
查詢只需要被解析(或准備)一次,但可以使用相同或不同的參數執行多次。當查詢准備好(Prepared)之後,資料庫就會分析,編譯並優化它要執行查詢的計劃。對於復雜查詢來說,如果你要重復執行許多次有不同參數的但結構相同的查詢,這個過程會佔用大量的時間,使得你的應用變慢。通過使用一個預處理語句你就可以避免重復分析、編譯、優化的環節。簡單來說,預處理語句使用更少的資源,執行速度也就更快。
存儲過程
(stored procere)是一組為了完成特定功能的sql 語句集,經編譯後存儲在資料庫。中用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它
預處理不止是在插入數據時候用的 在改變、刪除的時候都可以用到
這兩個方法什麼時候都可以用 但是本人認為預處理比較好 因為不是每個高級資料庫都有很好的存儲過程 oracle 、mysql 、ms sql、DB2等每個資料庫軟體的存儲過程都不相同 其運行效率也不盡相同
具體喜好 因人而異
『叄』 淺談MySQL存儲過程中declare和set定義變數的區別
MySQL存儲過程中,定義變數有兩種方式:
1.使用set或select直接賦值,變數名以 @ 開頭.
例如:set @var=1;
可以在一個會話的任何地方聲明,作用域是整個會話,稱為會話變數。
2.以 DECLARE 關鍵字聲明的變數,只能在存儲過程中使用,稱為存儲過程變數,例如:
DECLARE var1 INT DEFAULT 0;
主要用在存儲過程中,或者是給存儲傳參數中。
兩者的區別是:
在調用存儲過程時,以DECLARE聲明的變數都會被初始化為 NULL。而會話變數(即@開頭的變數)則不會被再初始化,在一個會話內,只須初始化一次,之後在會話內都是對上一次計算的結果,就相當於在是這個會話內的全局變數。
在存儲過程中,使用動態語句,預處理時,動態內容必須賦給一個會話變數。
例:
set @v_sql= sqltext;
PREPARE stmt FROM @v_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
『肆』 Mysql存儲過程是在創建時預編譯還是在執行時預編譯,怎麼能看出來或者怎麼測出來
語法
show create {procere|function} sp_name;
例如查看存儲過程myPro的創建語句
show create procere myPro;
查看自定義函數myFunc的創建語句
show create function myFunc;
『伍』 php預處理執行為什麼
預處理語句與存儲過程 :
很多更成熟的資料庫都支持預處理語句的概念。什麼是預處理語句?可以把它看作是想要運行的 SQL 的一種編譯過的模板,它可以使用變數參數進行定製。預處理語句可以帶來兩大好處:
查詢僅需解析(或預處理)一次,但可以用相同或不同的參數執行多次。當查詢准備好後,資料庫將分析、編譯和優化執行該查詢的計劃。對於復雜的查詢,此過程要花費較長的時間,如果需要以不同參數多次重復相同的查詢,那麼該過程將大大降低應用程序的速度。通過使用預處理語句,可以避免重復分析/編譯/優化周期。簡言之,預處理語句佔用更少的資源,因而運行得更快。
提供給預處理語句的參數不需要用引號括起來,驅動程序會自動處理。如果應用程序只使用預處理語句,可以確保不會發生SQL 注入。(然而,如果查詢的其他部分是由未轉義的輸入來構建的,則仍存在 SQL 注入的風險)。
預處理語句如此有用,以至於它們唯一的特性是在驅動程序不支持的時PDO 將模擬處理。這樣可以確保不管資料庫是否具有這樣的功能,都可以確保應用程序可以用相同的數據訪問模式。
Example #1 用預處理語句進行重復插入
下面例子通過用name和value替代相應的命名佔位符來執行一個插入查詢
<?php
$stmt=$dbh->prepare("INSERTINTOREGISTRY(name,value)VALUES(:name,:value)");
$stmt->bindParam(':name',$name);
$stmt->bindParam(':value',$value);
//插入一行
$name='one';
$value=1;
$stmt->execute();
//用不同的值插入另一行
$name='two';
$value=2;
$stmt->execute();
?>
Example #2 用預處理語句進行重復插入
下面例子通過用name和value取代?佔位符的位置來執行一條插入查詢。
<?php
$stmt=$dbh->prepare("INSERTINTOREGISTRY(name,value)VALUES(?,?)");
$stmt->bindParam(1,$name);
$stmt->bindParam(2,$value);
//插入一行
$name='one';
$value=1;
$stmt->execute();
//用不同的值插入另一行
$name='two';
$value=2;
$stmt->execute();
?>
Example #3 使用預處理語句獲取數據
下面例子獲取數據基於鍵值已提供的形式。用戶的輸入被自動用引號括起來,因此不會有 SQL 注入攻擊的危險。
<?php
$stmt=$dbh->prepare("SELECT*FROMREGISTRYwherename=?");
if($stmt->execute(array($_GET['name']))){
while($row=$stmt->fetch()){
print_r($row);
}
}
?>
如果資料庫驅動支持,應用程序還可以綁定輸出和輸入參數.輸出參數通常用於從存儲過程獲取值。輸出參數使用起來比輸入參數要稍微復雜一些,因為當綁定一個輸出參數時,必須知道給定參數的長度。如果為參數綁定的值大於建議的長度,就會產生一個錯誤。
Example #4 帶輸出參數調用存儲過程
<?php
$stmt=$dbh->prepare("CALLsp_returns_string(?)");
$stmt->bindParam(1,$return_value,PDO::PARAM_STR,4000);
//調用存儲過程
$stmt->execute();
print"procerereturned$return_value ";
?>
還可以指定同時具有輸入和輸出值的參數,其語法類似於輸出參數。在下一個例子中,字元串「hello」被傳遞給存儲過程,當存儲過程返回時,hello 被替換為該存儲過程返回的值。
Example #5 帶輸入/輸出參數調用存儲過程
<?php
$stmt=$dbh->prepare("CALLsp_takes_string_returns_string(?)");
$value='hello';
$stmt->bindParam(1,$value,PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT,4000);
//調用存儲過程
$stmt->execute();
print"procerereturned$value ";
?>
Example #6 佔位符的無效使用
<?php
$stmt=$dbh->prepare("SELECT*FROMREGISTRYwherenameLIKE'%?%'");
$stmt->execute(array($_GET['name']));
//佔位符必須被用在整個值的位置
$stmt=$dbh->prepare("SELECT*FROMREGISTRYwherenameLIKE?");
$stmt->execute(array("%$_GET[name]%"));
?>
『陸』 oracle存儲過程和觸發器用途
都重要,存儲過程和觸發器在做小項目有時可以起到簡化代碼的作用,有時不用他們一樣可以作到,只是要麻煩些.
存儲過程是用PL/SQL語言編寫,可以成塊提交數據,進行批處理,這樣可以避免因一些異常狀況而出現的數據不完整問題,例如停電什麼的.並且可以在後台拋出異常,簡化前台壓力.它的用處還有很多,這里我就不一一介紹了.
觸發器是與表幾乎同時執行的PL/SQL塊,它有時起著不可替代的功能.例如在視圖中的替代觸發器,可以將基於兩個表的視圖修改,並將修改結果作用於基表中.觸發器有預處理功能,可以在增刪改操作起判斷和限製作用,也有之後觸發的可以連接表,並通過修改此表達到修改其他表的目的.
這里我只是說了一小部分它們的內容,剩下的你可以自己再學習.但我要告訴你的是,oracle不學存儲過程和觸發器想進行高級操作是不太可能的.所以建議你學好它們啊.
呵呵,這些都是我一個字一個字打的,我學的也不是很豐富,算初學者吧,交個朋友啊?以後一起交流技術.
『柒』 mysql存儲過程問題 存儲過程中有這樣一條語句,例INSERT INTO tbl1 values(null,xxx,xxx);其中tbl1是一個
這種情況需要用到預處理。將表名作為變數傳遞進來,如叫v_tablename
set @sql = concat('INSERT INTO ', v_tablename,' values(null, xxx, xxx)');
prepare s from @sql;
EXECUTE s ;
DEALLOCATE PREPARE s;
這樣表名那裡就可以作為變數了。
『捌』 mysql 存儲過程執行太慢怎麼優化
1.當我們請求mysql伺服器的時候,MySQL前端會有一個監聽,請求到了之後,伺服器得到相關的SQL語句,執行之前(虛線部分為執行),還會做許可權的判斷
2.通過許可權之後,SQL就到MySQL內部,他會在查詢緩存中,看該SQL有沒有執行過,如果有查詢過,則把緩存結果返回,說明在MySQL內部,也有一個查詢緩存.但是這個查詢緩存,默認是不開啟的,這個查詢緩存,和我們的Hibernate,Mybatis的查詢緩存是一樣的,因為查詢緩存要求SQL和參數都要一樣,所以這個命中率是非常低的(沒什麼卵用的意思)。
3.如果我們沒有開啟查詢緩存,或者緩存中沒有找到對應的結果,那麼就到了解析器,解析器主要對SQL語法進行解析
4.解析結束後就變成一顆解析樹,這個解析樹其實在Hibernate裡面也是有的,大家回憶一下,在以前做過Hibernate項目的時候,是不是有個一個antlr.jar。這個就是專門做語法解析的工具.因為在Hibernate裡面有HQL,它就是通過這個工具轉換成SQL的,我們編程語言之所以有很多規范、語法,其實就是為了便於這個解析器解析,這個學過編譯原理的應該知道.
5.得到解析樹之後,不能馬上執行,這還需要對這棵樹進行預處理,也就是說,這棵樹,我沒有經過任何優化的樹,預處理器會這這棵樹進行一些預處理,比如常量放在什麼地方,如果有計算的東西,把計算的結果算出來等等...
6.預處理完畢之後,此時得到一棵比較規范的樹,這棵樹就是要拿去馬上做執行的樹,比起之前的那棵樹,這棵得到了一些優化
7.查詢優化器,是MySQL裡面最關鍵的東西,我們寫任何一條SQL,比如SELECT * FROM USER WHERE USERNAME = toby AND PASSWORD = 1,它會怎麼去執行?它是先執行username = toby還是password = 1?每一條SQL的執行順序查詢優化器就是根據MySQL對數據統計表的一些信息,比如索引,比如表一共有多少數據,MySQL都是有緩存起來的,在真正執行SQL之前,他會根據自己的這些數據,進行一個綜合的判定,判斷這一次在多種執行方式裡面,到底選哪一種執行方式,可能運行的最快.這一步是MySQL性能中,最關鍵的核心點,也是我們的優化原則.我們平時所講的優化SQL,其實說白了,就是想讓查詢優化器,按照我們的想法,幫我們選擇最優的執行方案,因為我們比MySQL更懂我們的數據.MySQL看數據,僅僅只是自己收集到的信息,這些信息可能是不準確的,MySQL根據這些信息選了一個它自認為最優的方案,但是這個方案可能和我們想像的不一樣.
8.這里的查詢執行計劃,也就是MySQL查詢中的執行計劃,比如要先執行username = toby還是password = 1
9.這個執行計劃會傳給查詢執行引擎,執行引擎選擇存儲引擎來執行這一份傳過來的計劃,到磁碟中的文件中去查詢,這個時候重點來了,影響這個查詢性能最根本的原因是什麼?就是硬碟的機械運動,也就是我們平時熟悉的IO,所以一條查詢語句是快還是慢,就是根據這個時間的IO來確定的.那怎麼執行IO又是什麼來確定的?就是傳過來的這一份執行計劃.(優化就是制定一個我們認為最快的執行方案,最節省IO,和執行最快)
10.如果開了查詢緩存,則返回結果給客戶端,並且查詢緩存也放一份。