存儲過程的使用場景
『壹』 sql procere 怎麼調用
為了演示方便,新創建了一個存儲過程 [dbo].[pr_test] 。
怎麼調用SQL存儲過程
存儲過程內容很簡單就是幾個數字,實際應用中可能還會使用的到一些存儲過程參數。
怎麼調用SQL存儲過程
執行存儲過程,來檢驗一下新建的存儲過程結果集。
怎麼調用SQL存儲過程
若我們在其實場景需要調用這個存儲過程中的結果集,則不需要直接調用,而是將結果集先插入一個臨時表即可。
create table #data (
Ftest1 int,
Ftest2 int,
Ftest3 int
)
注意:表定義的列數目要與存儲過程的一致。
怎麼調用SQL存儲過程
臨時表創建好了之後,使用insert into #data exec [dbo].[pr_test] 將結果集插入到臨時表#data中。
怎麼調用SQL存儲過程
可以將以上的創建臨時表和插入存儲過程結果的SQL語句放在需要的調用存儲過程的場景中。
怎麼調用SQL存儲過程
這樣就可以通過臨時表#data來連接其他表了。
『貳』 sql 存儲過程 游標用在什麼地方(新手剛學,不知道使用場景)我是C#做Web開發的
web開發很多用orm框架,存儲過程和游標都很少用。比如你用EF提倡CodeFirst,這得看你框架的規則上進行。純粹來講所有的sql執行語句都可以放到存儲過程里。比如insert,uodate,delete,select都可以。存儲過程有執行速度快的優勢,參數傳遞佔用空間小。同時方便後期修改和管理。比如像我現在用的一個簡單的存儲過程,返回當前客戶期數:
create proc proc_name(@account nvarchar(30))
as
begin
/*-------------------------------------------------------------------------------------
程序說明:返回當前客戶的期初數,業務結算月為26,以列印時間為准
BY:ChuiFeng 2013-02-27
返回結果:@CreditAmount欄位
-------------------------------------------------------------------------------------*/
declare @ARAmount decimal(22,10) = 0 --已經收到的客戶金額, 實收金額
declare @SaleAmount decimal(22,10) = 0 --貨物金額, 應收金額
--declare @amount decimal(22,10) =0 --存放期初
declare @endDate datetime --截止日期
--構造截止日期
if(DATEPART(DAY, GETDATE())>26) --當前日期超過結算日26號
set @endDate = CAST(CAST(DATEPART(year, GETDATE()) AS varchar(4)) + '-' + CAST(DATEPART(MONTH, GETDATE()) AS nvarchar(2)) + '-26' AS DateTime)
else
set @endDate = CAST(CAST(DATEPART(year, GETDATE()) AS varchar(4)) + '-' + CAST(DATEPART(MONTH, GETDATE())-1 AS nvarchar(2)) + '-26' AS DateTime)
select @ARAmount=SUM(Amount) from T_AR where CusCode=@account and PrintState=255 and DATEDIFF(DAY,PrintedTime,@endDate)>0
--select @SaleAmount=SUM(Amount) from T_SOs where SONO in (select SONO from T_SO where CusCode=@account and PrintState=255 and DATEDIFF(DAY,PrintedTime,@endDate)>0)
select @SaleAmount=SUM(Amount) from T_SO where CusCode=@account and PrintState=255 and DATEDIFF(DAY,PrintedTime,@endDate)>0
if(@ARAmount is null) set @ARAmount=0
if(@SaleAmount is null) set @SaleAmount=0
return @SaleAmount-@ARAmount
end
如果客戶需求發生了變化比如結算日改了,那麼我們只需要修改存儲過程就行了 而不必要修改程序代碼重新編譯。
至於游標:建議慎用 少用。主要就是性能問題。一般是在大數據量循環的情況下可能用但是最好別用,用好的存儲過程可以實現就別用游標...
『叄』 為什麼web項目開發者很少使用存儲過程
你可以想想存念罩掘儲過程都在什仔核么業務場景下會用?
一般銀行,保險等金融機構,這種場景下web肯定少啊悶茄
『肆』 存儲過程記錄日誌怎麼理解
您可以參考以下信息去理解:
存儲過程存儲了一系列sql語句
存儲過程的需求場景:下邊是一個經典的需求場景,很多Mysql的書都有:
存儲過程存儲了一系列sql語句,使得簡化了操作,不要求重復執行一系列操作。只需要在需要的時候調用一下存儲過程就行了。
一般來說,可以認為存儲過程的功能與函數的功能類似(應該都學櫻改過函數吧),但只是要注意存儲過程沒有脊洞判返回值,所以可以依據函顫賣數可用場景來理解存儲過程。
『伍』 在entity framework中怎麼調用存儲過程
一、使用存儲過程的必要性
我們知道EF通過元數據,即概念模型(Concept Model)、存儲模型(Storage Model)和概念/存儲映射(C/S Mapping),和狀態追蹤(State Tracking)機制可以為基於模型的操作自動生成SQL。對於一些簡單的項目開發,這是非常理想的,因為他們完全可以不用關注數據存儲層面的東西,你可以採用一些完全不具有資料庫知識的開發者。但是理想總歸是理想,對於企業級開發來說,我們需要的是對資料庫層面數據的操作有自己的控制。在這方面,我們可以隨便舉兩個典型的場景:
邏輯刪除:對於一些重要的數據,我們可能需要讓它們永久保存。當我們試圖「刪除」這些數據的時候,我們並不是將它們從數據表中移除(物理刪除),而是為這條記錄作一個已經被刪除的標記;
並發處理:為了解決相同的數據在獲取和提交這段時間內被另一個用戶修改或者刪除,我們往往SQL層面增加並發控制的邏輯。比較典型的做法是在每一個表中添加一個VersionNo這樣的欄位,你可以採用TimeStamp,也可以直接採用INT或者GUID。在執行Update或者Delete的SQL中判斷之前獲取的VersionNo是否和當前的一致。
讓解決這些問題,就不能使用EF為我們自動生成的SQL,只有通過使用我們自定義的存儲過程。
二、實現存儲過程自動匹配的必要條件
本篇文章提供的存儲過程自動映射機制是通過代碼生成的方式完成的。說白了,就是讀取原來的.edmx模型文件,通過分析在存儲模型中使用的數據表,導入基於該表的CUD存儲過程;然後再概念/存儲映射節點中添加實體和這些存儲過程的映射關系。那實現這樣的代碼生成,需要具有如下三個固定的映射規則。
數據表名-存儲過程名:這個映射關系幫助我們通過存儲模型中的實體名找到對應CUD三個存儲過程(如果實體是數據表);
數據表列名-存儲過程參數名:當存儲過程被執行的時候,通過這個映射讓概念模型實體某個屬性值作為對應的參數;
存儲過程參數名-版本:當進行參數賦值的時候,通過這個映射決定是使用Original或者Current版本。
在實際的開發過程中,這樣的標准存儲過程一般都是通過代碼生成器生成的(在我的文章《創建代碼生成器可以很簡單:如何通過T4模板生成代碼?[下篇]》中有過相應的實現),它們具有這樣的映射關系。
基於這三種映射關系,我定義了如下一個名為IProcereNameConverter的介面。其中OperationKind是我自定義的一個表示CUD操作類型的枚舉。
1: public interface IProcereNameConverter
2: {
3: string GetProcereName(string tableName, OperationKind operationKind);
4: string GetColumnName(string parameterName);
5: DataRowVersion GetVersion(string parameterName);
6: }
7:
8: public enum OperationKind
9: {
10: Insert,
11: Update,
12: Delete
13: }
按照我們當前項目採用的命名規范,我定義了如下一個默認的DefaultNameConverter。它體現的是這樣的映射關系,比如有個數據表明為T_USER(大寫,單詞之間用「_」隔開,並以T_為前綴),它對應的CUD存儲過程名分別為:P_USER_I、P_USER_U和P_USER_D(大寫,以代表存儲過程的P_為前綴,後綴_I/U/D表示CUD操作類型,中間為去除前綴的表名)。如果列名為USER_ID,參數名為p_user_id(小寫,加p_前綴)。如果需要用Original值為參數賦值,需要將p_前綴改成o_前綴(o_user_id)。
1: public class DefaultNameConverter: IProcereNameConverter
2: {
3: public string GetProcereName(string tableName, OperationKind operationKind)
4: {
5: switch (operationKind)
6: {
7: case OperationKind.Insert:
8: return string.Format("P_{0}_I", tableName.Substring(2));
9: case OperationKind.Update:
10: return string.Format("P_{0}_U", tableName.Substring(2));
11: default:
12: return string.Format("P_{0}_D", tableName.Substring(2));
13: }
14: }
15:
16: public string GetColumnName(string parameterName)
17: {
18: return parameterName.Substring(2).ToUpper();
19: }
20:
21: public DataRowVersion GetVersion(string parameterName)
22: {
23: if(parameterName.StartsWith("o"))
24: {
25: return DataRowVersion.Original;
26: }
27: else
28: {
29: return DataRowVersion.Current;
30: }
31: }
32: }
三、通過T4生成新的.edmx模型
我們採用的基於T4的代碼生成,了解EF的應該對T4不會感到陌生了。如果對代碼生成感興趣的話,可以看看我的文章《與VS集成的若干種代碼生成解決方案[博文匯總(共8篇)]》。這里利用藉助於T4 ToolBox這個開源工具箱,並採用SQL Server SMO獲取存儲過程信息。所有涉及到的文本轉化都實現在如下一個ProcereMappingTemplate類型中,由於內容較多,具體實現就忽略了,有興趣的朋友可能下載源代碼。ProcereMappingTemplate具有兩個構造函數的參數分別表示:源.edmx文件,伺服器和資料庫名,存儲過程的Schema(默認為dbo)和具體的ProcereNameConverter(默認為DefaultNameConverter)。
1: public class ProcereMappingTemplate: Template
2: {
3: public XmlDocument SourceModel { get; private set; }
4: public IProcereNameConverter ProcereNameConverter { get; private set; }
5: public Database Database { get; private set; }
6: public string Schema { get; private set; }
7:
8: public ProcereMappingTemplate(string sourceModelFile, string serverName, string databaseName);
9: public ProcereMappingTemplate(string sourceModelFile, string serverName, string databaseName,
10: IProcereNameConverter procereNameConverter, string schema);
11:
12: protected virtual XElement GenerateStorageModelNode();
13: protected virtual XElement GenerateMappingNode();
14: public override string TransformText()
15: {
16: XElement newStorageModelNode = this.GenerateStorageModelNode();
17: XElement newMappingNode = this.GenerateMappingNode();
18:
19: XmlNode storageModelNode = this.SourceModel.GetElementsByTagName("edmx:StorageModels")[0];
20: storageModelNode.InnerXml = newStorageModelNode.Elements().ToArray()[0].ToString();
21:
22: XmlNode mappingNode = this.SourceModel.GetElementsByTagName("edmx:Mappings")[0];
23: mappingNode.InnerXml = newMappingNode.Elements().ToArray()[0].ToString();
24:
25: this.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
26: this.Write(this.SourceModel.DocumentElement.OuterXml.Replace("xmlns=\"\"",""));
27: return GenerationEnvironment.ToString();
28: }
29: }
在使用過程中,你只需要在tt模板中創建這個ProcereMappingTemplate對象,調用Render方法即可。
1: <#@ template debug="true" hostSpecific="true" #>
2: <#@ output extension=".edmx" #>
3: <#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #>
4: <#@ assembly name="Microsoft.SqlServer.Smo" #>
5: <#@ assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>
6: <#@ assembly name="$(TargetDir)Artech.ProcereMapping.dll" #>
7: <#@ import namespace="Artech.ProcereMapping" #>
8: <#@ include file="T4Toolbox.tt" #>
9: <#
10: new ProcereMappingTemplate(this.Host.ResolvePath("UserModel.edmx"),".","EFExtensions").Render();
11: #>
四、看看生成出來的.emdx
通過上面創建的TT模板(你指定的資料庫中一定要存在具有相應映射關系的存儲過程),新的.edmx模型文件會作為該tt文件的依賴文件被生成出來。而這個新生成的.edmx具有存儲過程映射信息。具體來說,下面是原始的.edmx文件(只保留元數據節點)。
1: <?xml version="1.0" encoding="utf-8"?>
2: <edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
3: <!-- EF Runtime content -->
4: <edmx:Runtime>
5: <!-- SSDL content -->
6: <edmx:StorageModels>
7: <Schema Namespace="Artech.UserModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
8: <EntityContainer Name="ArtechUserModelStoreContainer">
9: <EntitySet Name="T_USER" EntityType="Artech.UserModel.Store.T_USER" store:Type="Tables" Schema="dbo" />
10: </EntityContainer>
11: <EntityType Name="T_USER">
12: <Key>
13: <PropertyRef Name="USER_ID" />
14: </Key>
15: <Property Name="USER_ID" Type="varchar" Nullable="false" MaxLength="50" />
16: <Property Name="USER_NAME" Type="nvarchar" Nullable="false" MaxLength="50" />
17: </EntityType>
18: </Schema>
19: </edmx:StorageModels>
20: <!-- CSDL content -->
21: <edmx:ConceptualModels>
22: <Schema Namespace="Artech.UserModel" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
23: <EntityContainer Name="EFExtensionsEntities" annotation:LazyLoadingEnabled="true">
24: <EntitySet Name="Users" EntityType="Artech.UserModel.User" />
25: </EntityContainer>
26: <EntityType Name="User">
27: <Key>
28: <PropertyRef Name="ID" />
29: </Key>
30: <Property Name="ID" Type="String" Nullable="false" MaxLength="50" Unicode="false" FixedLength="false" />
31: <Property Name="Name" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
32: </EntityType>
33: </Schema>
34: </edmx:ConceptualModels>
35: <!-- C-S mapping content -->
36: <edmx:Mappings>
37: <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
38: <EntityContainerMapping StorageEntityContainer="ArtechUserModelStoreContainer" CdmEntityContainer="EFExtensionsEntities">
39: <EntitySetMapping Name="Users">
40: <EntityTypeMapping TypeName="Artech.UserModel.User">
41: <MappingFragment StoreEntitySet="T_USER">
42: <ScalarProperty Name="ID" ColumnName="USER_ID" />
43: <ScalarProperty Name="Name" ColumnName="USER_NAME" />
44: </MappingFragment>
45: </EntityTypeMapping>
46: </EntitySetMapping>
47: </EntityContainerMapping>
48: </Mapping>
49: </edmx:Mappings>
50: </edmx:Runtime>
51: </edmx:Edmx>
這是新生成的.edmx文件中的XML。
『陸』 SQL SERVER 一個資料庫中使用大量的存儲過程,會影響性能嗎
一、在SQL Server中存儲過程不會影響性能。
1、只會大大的減輕伺服器的壓力,而不會增加,只有不合理的存儲過程才會造成伺服器性能下降的惡果。一個大型的資料庫,一般鉛沒存儲過程也不會超過幾千個,對當前的資料庫及它依附的硬體來說,這點兒負載是大象身上的老鼠,負載基本可以怱略不計。
2、但是,存儲過程是批量的SQL語句的合成,如果設計上混亂,引發死循環、死鎖、大范圍查詢、臨時表沒有及時清理釋放等問題的情況下,是會嚴重影響伺服器性能的,但這根子不在存儲過程上,而在於存儲過程的設計上。錯誤的SQL代碼指揮服務灶歷器,無論它的形式是存儲過程,還是客戶端及時發向資料庫的請求,都會使伺服器出現問題。
二、相關擴展
1、在當前,針對資料庫的編程設計,沒有存儲過程是不可想像的,這就象某個公司的大型貨品倉庫中沒有倉庫保管員一樣,所有的貨品進出都得進貨員或銷售員去臨時取放,會嚴重降低工作效率。
2、存儲過程在資料庫中無論是否編譯好,其效率都要比客戶端臨時向資料庫發槐辯納送指令調數據來得要高,因為至少減少了發向伺服器的指令的量。況且很多的中間值、臨時值如果不通過存儲過程來實現的話,就只能先全取到客戶端,這樣會大大增加網路負擔與伺服器的負鉭。
3、正如微軟所說,存儲過程來實現,可以使得很多中間量不必傳入到客戶上,客戶端只能得到需要的結果,所以同時可以提高安全。
『柒』 存儲過程的變數指什麼
存儲過程是面向對象的資料庫編程語言,與其他面向對象編程語言類似,可聲明變數,用變數來存取某一類值,變數在存儲過程中佔有非常重要的位置。變數聲明在MySQL語言的存儲過程中,變數有會話變數、存儲過程變數兩種。兩種變數的聲明方式不同,作用場景也不盡相同,在實際使用中要根據需要加以選擇。
1.變數種類((1)會話變數會話變數也稱用戶變數,可以在一個客戶端會話的任何地方聲明,作用域是整個會話,會話斷開後,會話變數也就消失。會話變數名以@開頭,使用set直接賦值,在一個會話內,會話變數只需初始化一次。
例如,Set@num=1;表示聲明了一個名字叫「@num」的會話變數,其初始值為1。
(2)存儲過程變數存儲過程變數以DECLARE為關鍵字聲明的變數,只能在存儲過程中使用,其命名不需要以@開頭。以DECLARE聲明的變數都會被初始化為NULL,存儲過程變數存在於資料庫伺服器上。2.變數定義存儲過程變數定義格式:DECLARE+變數名+數據類型+[DEFAULTVALUE]其中,((1)DECLARE為聲明存儲過程變數的關鍵字;
(2)變數名可以任意,但盡可能達到能表意的目的;
(3)數據類型為MySQL的數據類型,如int
『捌』 ASP.NET中如何執行各種類型的存儲過程
看到這個手寫的類,就知道還是手工作坊的產物。
在實際項目中從不用手寫數據訪問類,用微軟給的,或者用MSORM直接生成,
比這樣手寫,更快,更安全,代碼量更少,調用更方便。
---------------------------
代碼重用目地在於提高生產力,
並不是你寫一個類就永垂不朽了,
而是要在需求有變更的情況下,能夠復用和擴展。
你可以看看.NET裡面的ORM是如何進行代碼復用和擴展的,
觀察一下資料庫結構以及存儲過程改變的情況下,代碼是如何變化的。
事實上,完全不需要手動編碼。
能夠應付更加復雜的應用場景和需求變更,才能提高生產力,才能被稱之為面向對象。