hibernate存儲過程
⑴ Hibernate 調用存儲過程 該語句沒有返回結果集
修改存儲過程試試:
alter procere test()
as
SET NOCOUNT ON --加上這句話;有的出現這個問題,加上之後問題解決了;嘿嘿
⑵ hibernate調用存儲過程
hibernate3.0以上提供了兩種方式執行存儲過程。
第一種 :用JDBC 方式
Session session =HibernateSessionFactory.getSession(); //獲取hibernate會話
Connection conn = session.connection(); // 用session對象獲取連接
ResultSet rs =null;
try
{
CallableStatement call = conn.prepareCall("{Call pro_getManager(?,?)}");
call.setString(1, "admin");
call.setString(2, "admin");
rs = call.executeQuery();
}
catch (Exception e)
{
e.printStackTrace();
}finally
{
rs.close();//關閉
session.close();//關閉連接
HibernateSessionFactory.closeSession(); //關閉會話
}
這種方式本人感覺與hibernate結合不很緊密,還難以控制,還要自己控制關閉
第二種: 用hibernate中sqlQuery 介面執行,其實與執行sql沒有兩樣。
Session session =HibernateSessionFactory.getSession(); //獲取hibernate會話
String procName="{Call pro_getManager(?,?) }";
SQLQuery query = session.createSQLQuery(proc);
query.setString(0, "admin");
query.setString(1, "admin");
List list =query.list();
session.close();
HibernateSessionFactory.closeSession();
⑶ hibernate緩存的詳細配置
很多人對二級緩存都不太了解,或者是有錯誤的認識,我一直想寫一篇文章介紹一下hibernate的二級緩存的,今天終於忍不住了。
我的經驗主要來自hibernate2.1版本,基本原理和3.0、3.1是一樣的,請原諒我的頑固不化。
hibernate的session提供了一級緩存,每個session,對同一個id進行兩次load,不會發送兩條sql給資料庫,但是session關閉的時候,一級緩存就失效了。
二級緩存是SessionFactory級別的全局緩存,它底下可以使用不同的緩存類庫,比如ehcache、oscache等,需要設置hibernate.cache.provider_class,我們這里用ehcache,在2.1中就是
hibernate.cache.provider_class=net.sf.hibernate.cache.EhCacheProvider
如果使用查詢緩存,加上
hibernate.cache.use_query_cache=true
緩存可以簡單的看成一個Map,通過key在緩存裡面找value。
Class的緩存
對於一條記錄,也就是一個PO來說,是根據ID來找的,緩存的key就是ID,value是POJO。無論list,load還是iterate,只要讀出一個對象,都會填充緩存。但是list不會使用緩存,而iterate會先取資料庫select id出來,然後一個id一個id的load,如果在緩存裡面有,就從緩存取,沒有的話就去資料庫load。假設是讀寫緩存,需要設置:
<cache usage="read-write"/>
如果你使用的二級緩存實現是ehcache的話,需要配置ehcache.xml
<cache name="com.xxx.pojo.Foo" maxElementsInMemory="500" eternal="false" timeToLiveSeconds="7200" timeToIdleSeconds="3600" overflowToDisk="true" />
其中eternal表示緩存是不是永遠不超時,timeToLiveSeconds是緩存中每個元素(這里也就是一個POJO)的超時時間,如果eternal="false",超過指定的時間,這個元素就被移走了。timeToIdleSeconds是發呆時間,是可選的。當往緩存裡面put的元素超過500個時,如果overflowToDisk="true",就會把緩存中的部分數據保存在硬碟上的臨時文件裡面。
每個需要緩存的class都要這樣配置。如果你沒有配置,hibernate會在啟動的時候警告你,然後使用defaultCache的配置,這樣多個class會共享一個配置。
當某個ID通過hibernate修改時,hibernate會知道,於是移除緩存。
這樣大家可能會想,同樣的查詢條件,第一次先list,第二次再iterate,就可以使用到緩存了。實際上這是很難的,因為你無法判斷什麼時候是第一次,而且每次查詢的條件通常是不一樣的,假如資料庫裡面有100條記錄,id從1到100,第一次list的時候出了前50個id,第二次iterate的時候卻查詢到30至70號id,那麼30-50是從緩存裡面取的,51到70是從資料庫取的,共發送1+20條sql。所以我一直認為iterate沒有什麼用,總是會有1+N的問題。
(題外話:有說法說大型查詢用list會把整個結果集裝入內存,很慢,而iterate只select id比較好,但是大型查詢總是要分頁查的,誰也不會真的把整個結果集裝進來,假如一頁20條的話,iterate共需要執行21條語句,list雖然選擇若干欄位,比iterate第一條select id語句慢一些,但只有一條語句,不裝入整個結果集hibernate還會根據資料庫方言做優化,比如使用mysql的limit,整體看來應該還是list快。)
如果想要對list或者iterate查詢的結果緩存,就要用到查詢緩存了
查詢緩存
首先需要配置hibernate.cache.use_query_cache=true
如果用ehcache,配置ehcache.xml,注意hibernate3.0以後不是net.sf的包名了
<cache name="net.sf.hibernate.cache.StandardQueryCache"
maxElementsInMemory="50" eternal="false" timeToIdleSeconds="3600"
timeToLiveSeconds="7200" overflowToDisk="true"/>
<cache name="net.sf.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="5000" eternal="true" overflowToDisk="true"/>
然後
query.setCacheable(true);//激活查詢緩存
query.setCacheRegion("myCacheRegion");//指定要使用的cacheRegion,可選
第二行指定要使用的cacheRegion是myCacheRegion,即你可以給每個查詢緩存做一個單獨的配置,使用setCacheRegion來做這個指定,需要在ehcache.xml裡面配置它:
<cache name="myCacheRegion" maxElementsInMemory="10" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200" overflowToDisk="true" />
如果省略第二行,不設置cacheRegion的話,那麼會使用上面提到的標准查詢緩存的配置,也就是net.sf.hibernate.cache.StandardQueryCache
對於查詢緩存來說,緩存的key是根據hql生成的sql,再加上參數,分頁等信息(可以通過日誌輸出看到,不過它的輸出不是很可讀,最好改一下它的代碼)。
比如hql:
from Cat c where c.name like ?
生成大致如下的sql:
select * from cat c where c.name like ?
參數是"tiger%",那麼查詢緩存的key*大約*是這樣的字元串(我是憑記憶寫的,並不精確,不過看了也該明白了):
select * from cat c where c.name like ? , parameter:tiger%
這樣,保證了同樣的查詢、同樣的參數等條件下具有一樣的key。
現在說說緩存的value,如果是list方式的話,value在這里並不是整個結果集,而是查詢出來的這一串ID。也就是說,不管是list方法還是iterate方法,第一次查詢的時候,它們的查詢方式很它們平時的方式是一樣的,list執行一條sql,iterate執行1+N條,多出來的行為是它們填充了緩存。但是到同樣條件第二次查詢的時候,就都和iterate的行為一樣了,根據緩存的key去緩存裡面查到了value,value是一串id,然後在到class的緩存裡面去一個一個的load出來。這樣做是為了節約內存。
可以看出來,查詢緩存需要打開相關類的class緩存。list和iterate方法第一次執行的時候,都是既填充查詢緩存又填充class緩存的。
這里還有一個很容易被忽視的重要問題,即打開查詢緩存以後,即使是list方法也可能遇到1+N的問題!相同條件第一次list的時候,因為查詢緩存中找不到,不管class緩存是否存在數據,總是發送一條sql語句到資料庫獲取全部數據,然後填充查詢緩存和class緩存。但是第二次執行的時候,問題就來了,如果你的class緩存的超時時間比較短,現在class緩存都超時了,但是查詢緩存還在,那麼list方法在獲取id串以後,將會一個一個去資料庫load!因此,class緩存的超時時間一定不能短於查詢緩存設置的超時時間!如果還設置了發呆時間的話,保證class緩存的發呆時間也大於查詢的緩存的生存時間。這里還有其他情況,比如class緩存被程序強制evict了,這種情況就請自己注意了。
另外,如果hql查詢包含select字句,那麼查詢緩存裡面的value就是整個結果集了。
當hibernate更新資料庫的時候,它怎麼知道更新哪些查詢緩存呢?
hibernate在一個地方維護每個表的最後更新時間,其實也就是放在上面net.sf.hibernate.cache.UpdateTimestampsCache所指定的緩存配置裡面。
當通過hibernate更新的時候,hibernate會知道這次更新影響了哪些表。然後它更新這些表的最後更新時間。每個緩存都有一個生成時間和這個緩存所查詢的表,當hibernate查詢一個緩存是否存在的時候,如果緩存存在,它還要取出緩存的生成時間和這個緩存所查詢的表,然後去查找這些表的最後更新時間,如果有一個表在生成時間後更新過了,那麼這個緩存是無效的。
可以看出,只要更新過一個表,那麼凡是涉及到這個表的查詢緩存就失效了,因此查詢緩存的命中率可能會比較低。
Collection緩存
需要在hbm的collection裡面設置
<cache usage="read-write"/>
假如class是Cat,collection叫children,那麼ehcache裡面配置
<cache name="com.xxx.pojo.Cat.children"
maxElementsInMemory="20" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200"
overflowToDisk="true" />
Collection的緩存和前面查詢緩存的list一樣,也是只保持一串id,但它不會因為這個表更新過就失效,一個collection緩存僅在這個collection裡面的元素有增刪時才失效。
這樣有一個問題,如果你的collection是根據某個欄位排序的,當其中一個元素更新了該欄位時,導致順序改變時,collection緩存裡面的順序沒有做更新。
緩存策略
只讀緩存(read-only):沒有什麼好說的
讀/寫緩存(read-write):程序可能要的更新數據
不嚴格的讀/寫緩存(nonstrict-read-write):需要更新數據,但是兩個事務更新同一條記錄的可能性很小,性能比讀寫緩存好
事務緩存(transactional):緩存支持事務,發生異常的時候,緩存也能夠回滾,只支持jta環境,這個我沒有怎麼研究過
讀寫緩存和不嚴格讀寫緩存在實現上的區別在於,讀寫緩存更新緩存的時候會把緩存裡面的數據換成一個鎖,其他事務如果去取相應的緩存數據,發現被鎖住了,然後就直接取資料庫查詢。
在hibernate2.1的ehcache實現中,如果鎖住部分緩存的事務發生了異常,那麼緩存會一直被鎖住,直到60秒後超時。
不嚴格讀寫緩存不鎖定緩存中的數據。
使用二級緩存的前置條件
你的hibernate程序對資料庫有獨占的寫訪問權,其他的進程更新了資料庫,hibernate是不可能知道的。你操作資料庫必需直接通過hibernate,如果你調用存儲過程,或者自己使用jdbc更新資料庫,hibernate也是不知道的。hibernate3.0的大批量更新和刪除是不更新二級緩存的,但是據說3.1已經解決了這個問題。
這個限制相當的棘手,有時候hibernate做批量更新、刪除很慢,但是你卻不能自己寫jdbc來優化,很郁悶吧。
SessionFactory也提供了移除緩存的方法,你一定要自己寫一些JDBC的話,可以調用這些方法移除緩存,這些方法是:
void evict(Class persistentClass)
Evict all entries from the second-level cache.
void evict(Class persistentClass, Serializable id)
Evict an entry from the second-level cache.
void evictCollection(String roleName)
Evict all entries from the second-level cache.
void evictCollection(String roleName, Serializable id)
Evict an entry from the second-level cache.
void evictQueries()
Evict any query result sets cached in the default query cache region.
void evictQueries(String cacheRegion)
Evict any query result sets cached in the named query cache region.
不過我不建議這樣做,因為這樣很難維護。比如你現在用JDBC批量更新了某個表,有3個查詢緩存會用到這個表,用evictQueries(String cacheRegion)移除了3個查詢緩存,然後用evict(Class persistentClass)移除了class緩存,看上去好像完整了。不過哪天你添加了一個相關查詢緩存,可能會忘記更新這里的移除代碼。如果你的jdbc代碼到處都是,在你添加一個查詢緩存的時候,還知道其他什麼地方也要做相應的改動嗎?
----------------------------------------------------
總結:
不要想當然的以為緩存一定能提高性能,僅僅在你能夠駕馭它並且條件合適的情況下才是這樣的。hibernate的二級緩存限制還是比較多的,不方便用jdbc可能會大大的降低更新性能。在不了解原理的情況下亂用,可能會有1+N的問題。不當的使用還可能導致讀出臟數據。
如果受不了hibernate的諸多限制,那麼還是自己在應用程序的層面上做緩存吧。
在越高的層面上做緩存,效果就會越好。就好像盡管磁碟有緩存,資料庫還是要實現自己的緩存,盡管資料庫有緩存,咱們的應用程序還是要做緩存。因為底層的緩存它並不知道高層要用這些數據干什麼,只能做的比較通用,而高層可以有針對性的實現緩存,所以在更高的級別上做緩存,效果也要好些吧。
⑷ hibernate 存儲過程問題 Caused by: java.sql.SQLException: ORA-06550: 第 1 行, 第 7 列: PLS-00905:
我想你java里定義的應該是float或者double類型吧?float是精確到小數點後6位,double是15位..所以你的222.00應該保存的比這個要更精確,而你的oracle里,只精確了兩位所以....就是這個錯誤了,其實如果要求不嚴的話,直接定義成number就行了,那麼接到的值是什麼精度什麼類型的他就自動存了.
⑸ 我在做hibernate調用存儲過程的時候報了一個無效索引不知道是哪裡出了問題請高手解決
先檢查你的存儲過程能不能執行,直接在資料庫上執行,先不用hibernate.....
⑹ hibernate中調用存儲過程,如果返回了多個結果集,怎麼處理
過程如下:
public Boolean doInHibernate(Session session)
throws HibernateException, SQLException {
try{
Transaction tr = session.beginTransaction();
SQLQuery query = session.createSQLQuery("{call CommandAdapter(?,?,?,?)}");
query.setString(0,"ls");
query.setInteger(1, machineid);
query.setString(2, param);
query.setInteger(3, 0); //
query.executeUpdate();
tr.commit();
return true;
}catch(Exception e){
e.printStackTrace();
return false;
}finally{
session.close();
}
}
使用hibernate調用帶參數返回值的存儲過程方法
在調用帶參數返回值的方法時,需使用到CallableStatement對象。因此,首先得設法獲取一個Connection。
獲取Connection 方法:
(1)session.connection();//此方法目前已被棄用
(2)SessionFactoryUtils.getDataSource(sessionFactory).getConnection()
不
過我在使用SessionFactoryUtils.getDataSource(sessionFactory)時,一直獲取的都是空值,為此參考
SessionFactoryUtils的源代碼直接利用ConnectionProvider對象來獲取一個Connection實例。
完整代碼:
SessionFactory sessionFactory=this.getSessionFactory();
if (sessionFactory instanceof SessionFactoryImplementor){
ConnectionProvider cp = ((SessionFactoryImplementor) sessionFactory).getConnectionProvider();
try {
CallableStatement statement = cp.getConnection().prepareCall(
"{call MachineDataQuery(?,?,?,?,?,?,?,?,?,?,?,?,?,?)}");
statement.setInt(1, machineId);
statement.setInt(2, jobId);
statement.setInt(3, partTypeId);
statement.setInt(4, compentId);
statement.setInt(5, opId);
statement.setInt(6, roleId);
statement.setInt(7, userId);
statement.setString(8, sd);
statement.setString(9, ed);
statement.registerOutParameter(10, Types.FLOAT);
statement.registerOutParameter(11, Types.FLOAT);
statement.registerOutParameter(12, Types.FLOAT);
statement.registerOutParameter(13, Types.FLOAT);
statement.registerOutParameter(14, Types.FLOAT);
statement.execute();
System.out.println(statement.getFloat(10));
System.out.println(statement.getFloat(11));
System.out.println(statement.getFloat(12));
System.out.println(statement.getFloat(13));
System.out.println(statement.getFloat(14));
} catch (SQLException e) {
e.printStackTrace();
}finally{
cp.close();
}
}
ps:切記存儲過程中不可有多餘的print或select語句,否則會拋出異常「com.microsoft.sqlserver.jdbc.SQLServerException: 已生成用於更新的結果集。」
⑺ 存儲過程如何使用
問題一:SQL 中存儲過程怎麼使用? sql存儲過程及應用
一、簡介:
存儲過程(Stored Procere), 是一組為了完成特定功能的SQL 語句,集經編譯後
存儲在資料庫中,用戶通過指定存儲過程的名字並給出參數,如果該存儲過程帶有參數來執行
它,
在SQL Server 的系列版本中,存儲過程分為兩類:系統提供的存儲過程和用戶自定義存儲過程
。
系統SP,主要存儲master 資料庫中,並以sp_為前綴並且系統存儲過程主要是從系統表中獲取
信息,從而為系統管理員管理SQL Server。用戶自定義存儲過程是由用戶創建,並能完成
某一特定功能,如:查詢用戶所需數據信息的存儲過程。
存儲過程具有以下優點
1.存儲過程允許標准組件式編程(模塊化設計)
存儲過程在被創建以後,可以在程序中被多次調用,而不必重新編寫該存儲過程的SQL語句,而
且數
據庫專業人員可隨時對存儲過程進行修改,但對應用程序源代碼毫無影響。因為應用程序源代
碼只包含存
儲過程的調用語句,從而極大地提高了程序的可移植性。
2.存儲過程能夠實現快速的執行速度
如果某一操作包含大量的Transaction-SQL 代碼,,或分別被多次執行,那麼存儲過程要比批處理
的
執行速度快很多,因為存儲過程是預編譯的,在首次運行一個存儲過程時,查詢優化器對其進
行分析優
化,並給出最終被存在系統表中的執行計劃,而批處理的Transaction-SQL 語句在每次運行時
都要進行
編譯和優化,因此速度相對要慢一些。
3.存儲過程能夠減少網路流量
對於同一個針對數據資料庫對象的操作,如查詢修改,如果這一操作所涉及到的Transaction-SQL
語句被組織成一存儲過程,那麼當在客戶計算機上調用該存儲過程時,網路中傳送的只是該調
用語句,否
則將是多條SQL 語句從而大大增加了網路流量降低網路負載。
4.存儲過程可被作為一種安全機制來充分利用
系統管理員通過,對執行某一存儲過程的許可權進行限制,從而能夠實現對相應的數據訪問許可權的
限
制。
二、變數
@I
三、流程式控制制語句(if else | select case | while )
Select ... CASE 實例
DECLARE @iRet INT, @PKDisp VARCHAR(20)
SET @iRet = '1'
Select @iRet =
CASE
WHEN @PKDisp = '一' THEN 1
WHEN @PKDisp = '二' THEN 2
WHEN @PKDisp = '三' THEN 3
WHEN @PKDisp = '四' THEN 4
WHEN @PKDisp = '五' THEN 5
ELSE 100
END
四、存儲過程格式
創建存儲過程
Create Proc dbo.存儲過程名
存儲過程參數
AS
執行語句
RETURN
執行存儲過程
GO
*********************************************************/
-- 變數的聲明,sql裡面聲明變數時必須在變數前加@符號
DECLARE @I INT
-- 變數的賦值,變數賦值時變數前必須加set
SET @I = 30
-- 聲明多個變數
DECLARE @s varchar(10),@a INT
-- Sql 里if語句
IF 條件 BEGIN
執行語句
END
ELSE BEGIN
......>>
問題二:為什麼要使用存儲過程? 幾個去 IBM 面試的兄弟回來抱怨:去了好幾個不同的 IBM項目組,幾乎每個面試官問到資料庫的時候都要問用沒用過存儲過程,煩人不?大家去面的程序員,又不是筆者認為,存儲過程說白了就是一堆 SQL 的合並。中間加了點邏輯控制。但是存儲過程處理比較復雜的業務時比較實用。比如說,一個復雜的數據操作。如果你在前台處理的話。可能會涉及到多次資料庫連接。但如果你用存儲過程的話。就只有一次。從響應時間上來說有優勢。也就是說存儲過程可以給我們帶來運行效率提高的好處。另外,程序容易出現 BUG數據量小的,或者和錢沒關系的項目不用存儲過程也可以正常運作。mysql 的存儲過程還有待實際測試。如果是正式項目,建議你用 sqlserver 或 oracle的存儲過程。數據與數據之間打交道的話,過程會比程序來的快的多。面試官問有沒有用存儲,實際上就是想知道前來面試的程序員到底做過數據量大的項目沒。如果是培訓出來的,或者小項目小公司出來的,對存儲肯定接觸的少了。所以,要想進大公司,沒有豐富存儲過程經驗,是不行的。錯。存儲過程不僅僅適用於大型項目,對於中小型項目,使用存儲過程也是非常有必要的。其威力和優勢主要體現在:1.存儲過程只在創造時進行編譯,以後每次執行存儲過程都不需再重新編譯,而一般 SQL語句每執行一次就編譯一次,所以使用存儲過程可提高資料庫執行速度。2.當對資料庫進行復雜操作時(如對多個表進行Update,Insert,Query,Delete時),可將此復雜操作用存儲過程封裝起來與資料庫提供的事務處理結合一起使用。這些操作,如果用程序來完成,就變成了一條條的 SQL語句,可能要多次連接資料庫。而換成存儲,只需要連接一次資料庫就可以了。3.存儲過程可以重復使用,可減少資料庫開發人員的工作量。4.安全性高,可設定只有某此用戶才具有對指定存儲過程的使用權。存儲過程的缺點1:調試麻煩,但是用 PL/SQL Developer 調試很方便!彌補這個缺點。 2:移植問題,資料庫端代碼當然是與資料庫相關的。但是如果是做工程型項目,基本不存在移植問題。 3:重新編譯問題,因為後端代碼是運行前編譯的,如果帶有引用關系的對象發生改變時,受影響的存儲過程、包將需要重新編譯(不過也可以設置成運行時刻自動編譯)。4:如果在一個程序系統中大量的使用存儲過程,到程序交付使用的時候隨著用戶需求的增加會導致數據結構的變化,接著就是系統的相關問題了,最後如果用戶想維護該系統可以說是很難很難、而且代價是空前的。維護起來更加麻煩!
問題三:oracle中的存儲過程,有什麼作用,以及怎麼在代碼中使用? 樓上也不知道從哪扒下來的,一看LZ就是初學,舉點例子不行嗎?
比如建立個測試表
create table test(id int,name varchar2(10),counts int); insert into test values (1,'張三',100);insert into test values (2,'李四',200); mit;
現在給你出個題目是
查詢所有人加在一起的counts是多少
創建存儲過程
create or replace p_test --創建存儲過程,asv_counts int;--定義變數begin --開始select sum(counts) into v_counts from test;--將得到的結果放到變數里DBMS_OUTPUT.PUT_LINE(v_counts);--將結果列印輸出end;--結束
執行這種不帶輸入參數的
begin p_test;end;
然後你檢查下結果
再給你創建一個帶輸入參數的
題目是,查詢id為1的人名是什麼
create or replace p_test1(v_id int)asv_name varchar2(10);beginselect name into v_name from test where id=v_id;DBMS_OUTPUT.PUT_LINE(v_name);end;
執行時這樣
beginp_test1(1);end;
第2個我沒給你寫注釋,你看你自己應該能理解吧
補充一下,存儲過程不一定只是執行查詢,也可以做刪除或者修改等sql語句,總體來說就是幾個或N個sql語句的 *** ,來完成系統內某些特定的需求,這些需求可以是一個sql搞定的,也可以是多個sql組合的
問題四:SQL 存儲過程建立和使用方法? Sql Server的存儲過程是一個被命名的存儲在伺服器上的Transacation-Sql語句 *** ,是封裝重復性工作的一種方法,它支持用戶聲明的變數、條件執行和其他強大的編程功能。 存儲過程相對於其他的資料庫訪問方法有以下的優點: (1)重復使用。存儲過程可以重復使用,從而可以減少資料庫開發人員的工作量。 (2)提高性能。存儲過程在創建的時候就進行了編譯,將來使用的時候不用再重新編譯。一般的SQL語句每執行一次就需要編譯一次,所以使用存儲過程提高了效率。 (3)減少網路流量。存儲過程位於伺服器上,調用的時候只需要傳遞存儲過程的名稱以及參數就可以了,因此降低了網路傳輸的數據量。 (4)安全性。參數化的存儲過程可以防止SQL注入式的攻擊,而且可以將Grant、Deny以及Revoke許可權應用於存儲過程。 存儲過程一共分為了三類:用戶定義的存儲過程、擴展存儲過程以及系統存儲過程。 其中,用戶定義的存儲過程又分為Transaction-SQL和CLR兩種類型。 Transaction-SQL 存儲過程是指保存的Transaction-SQL語句 *** ,可以接受和返回用戶提供的參數。 CLR存儲過程是指對.Net Framework公共語言運行時(CLR)方法的引用,可以接受和返回用戶提供的參數。他們在.Net Framework程序集中是作為類的公共靜態方法實現的。(本文就不作介紹了) 創建存儲過程的語句如下:Code
CREATE { PROC | PROCEDURE } [schema_name.] procere_name [ ; number ]
[ { @parameter [ type_schema_name. ] data_type }
[ VARYING ] [ = default ] [ [ OUT [ PUT ]
] [ ,n ]
[ WITH [ ,n ]
[ FOR REPLICATION ]
AS { [;][ n ] | }
[;]
::=
[ ENCRYPTION ]
[ REPILE ]
[ EXECUTE_AS_Clause ]
::=
{ [ BEGIN ] statements [ END ] }
::=
EXTERNAL NAME assembly_name.class_name.method_name [schema_name]: 代表的是存儲過程所屬的架構的名稱 例如: Create Schema yangyang8848
Go
Create Proc yangyang8848.AllGoods
As Select * From Master_Goods
Go 執行:Exec AllGoods 發生錯誤。 執......>>
問題五:資料庫中的存儲過程怎麼用 啊!!求解..... 10分 關鍵字:procere
例子:
SQL> create [or replace] procere procere_name is
begin
--開始執行
insert into test('10001','Visket');
end;
/
以上操作就能為test表添加一條信息
執行存儲過程procere用的命令是exec
記住存儲過程中,語句結尾一定要有分號
問題六:存儲過程是多用還是少用? 做項目的時候我們有時候會面臨一個選擇,我們到底是應該多寫存儲過程還是少寫存儲過程了?這個問題的爭論也是由來已久,在不同的公司以及不同的技術負責人那裡往往會得到不同的答案。在實際項目中我們最後所採取的方式,往往不外乎以下三種方式。
第一種方式是要求所有資料庫操作不使用任何的存儲過程,所有操作都採用標准sql語句來完成,即便是一個動作需要完成多步資料庫操作,也不使用任何存儲過程,而是在程序代碼中採用事務的方式來完成;第二種方式就是就要求所有的資料庫操作都用存儲過程封裝起來,哪怕是一個最簡單的insert 操作。在程序代碼看不到一行 sql語句,如果採用分工合作的方式,程序員甚至都可以不懂sql語法。第三種方式是一般相對簡單的資料庫操作採用標准sql語句來完成,一些相對比較復雜的商務邏輯用存儲過程來完成。
當然系統如果採用了hibernate或nhibernate之類的框架,不需要寫sql語句的時候,我想還是應該屬於第三種方式,因為在開發的時候hibernate框架允許我們在適當的時候,拋開其框架自己寫存儲過程和sql語句來完成資料庫操作。其實這三種方式都各有所長,也各有不足。
第一種方式是所有的資料庫操作都採用標准sql語句來完成的方式,在程序的執行效率上是肯定不如後面兩種方式,系統如果是一個大型的ERP,這種方式就是絕對不可取的。因為在開發基本結束後,系統如果需要優化或者希望得到優化時,那對開發人員來說就是一件非常麻煩的事情了,因為優化的重點基本上都是集中資料庫操作上,開發人員所能做的就是一個個sql語句去檢查,是不是還能進一步優化,尤其是一些相對比較復雜的查詢語句是我們所檢查的重點。分頁顯示就是一個典型的存儲過程提高程序效率的例子。如果使用存儲過程來進行分頁操作,就是利用存儲過程從系統中提取我們所需要的記錄集,分頁的效率就大大提高了。反過來如果我們不用存儲過程進行分頁操作,是利用sql語句的方式把所有記錄集都讀入內存中,然後再從內存中獲取我們所需要的記錄 *** ,這樣分頁效率自然就降低了。當然利用sql語句也能得到我們所需要的記錄,而不是所有記錄,但是那樣麻煩多了,不在我們討論范圍之內。
這種方式另外還有一個不足之處,一個系統或一個項目總會或多或少地存在有一些容易變化而又復雜的商務邏輯,如果把這些復雜的商務邏輯封裝到存儲過程中,商務邏輯的變化都只涉及存儲過程變化,而與程序代碼不 *** ,那麼不用存儲過程太可惜了。
這種方式雖然有不足,但是一旦採用這種方式的話,我們如果對該項目進行資料庫移植的時候,開發人員就會覺得當時的決策人是多麼的偉大與英明。而且我們知道access和mysql的以前版本是不提供存儲過程支持的,所有一些中小項目在這個方面的選擇往往也是不得已而為之。不用存儲過程有一個優點,調試代碼的時候沒有存儲過程可是要方便很多很多的哦,所以在很多很多的項目中都是採用標準的sql語句而不使用任何的存儲過程。這可是大多程序員用標准sql而不用存儲過程的直接原因,說白了,就是嫌麻煩。
第二種方式是所有的資料庫操作全部採用存儲過程封裝的方式,如果採用這種方式,程序的執行效率相對要高,尤其面對在一些復雜的商務邏輯時候,不僅在效率方面有明顯的提高,而且當商務邏輯發生變化時,我們開發人員做相應的修改的時候,往往都不用修改程序代碼,僅僅修改存儲過程就能滿足系統變化了。
還有一個好處就是當我們開發好的一個系統後,如果發現一種模式或語言在某些方面難以滿足需求時,我們就可以很快的用兩外一種語言來重新開發,那個時候就非常方便了。比如在02年中科院下屬的一個公司就用ASP開......>>
問題七:在SQL中存儲過程的一般語法是什麼? sql server存儲過程語法
存儲過程就是作為可執行對象存放在資料庫中的一個或多個SQL命令。
定義總是很抽象。存儲過程其實就是能完成一定操作的一組SQL語句,只不過這組語句是放在資料庫中的(這里我們只談SQL Server)。如果我們通過創建存儲過程以及在ASP中調用存儲過程,就可以避免將SQL語句同ASP代碼混雜在一起。這樣做的好處至少有三個:
第一、大大提高效率。存儲過程本身的執行速度非常快,而且,調用存儲過程可以大大減少同資料庫的交互次數。
第二、提高安全性。假如將SQL語句混合在ASP代碼中,一旦代碼失密,同時也就意味著庫結構失密。
第三、有利於SQL語句的重用。
在ASP中,一般通過mand對象調用存儲過程,根據不同情況,本文也介紹其它調用方法。為了方便說明,根據存儲過程的輸入輸出,作以下簡單分類:
1. 只返回單一記錄集的存儲過程
假設有以下存儲過程(本文的目的不在於講述T-SQL語法,所以存儲過程只給出代碼,不作說明):
/*SP1*/
CREATE PROCEDURE dbo.getUserList
as
set nocount on
begin
select * from dbo.[userinfo]
end
go
以上存儲過程取得userinfo表中的所有記錄,返回一個記錄集。通過mand對象調用該存儲過程的ASP代碼如下:
'**通過mand對象調用存儲過程**
DIM Mym,MyRst
Set Mym = Server.CreateObject(ADODB.mand)
Mym.ActiveConnection = MyConStr 'MyConStr是資料庫連接字串
Mym.mandText = getUserList '指定存儲過程名
Mym.mandType = 4 '表明這是一個存儲過程
Mym.Prepared = true '要求將SQL命令先行編譯
Set MyRst = Mym.Execute
Set Mym = Nothing
存儲嘩程取得的記錄集賦給MyRst,接下來,可以對MyRst進行操作。
在以上代碼中,mandType屬性表明請求的類型,取值及說明如下:
-1 表明mandText參數的類型無法確定
1 表明mandText是一般的命令類型
2 表明mandText參數是一個存在的表名稱
4 表明mandText參數是一個存儲過程的名稱
還可以通過Connection對象或Recordset對象調用存儲過程,方法分別如下:
'**通過Connection對象調用存儲過程**
DIM MyConn,MyRst
Set MyConn = Server.CreateObject(&qu......>>
問題八:如何使用Oracle存儲過程的一個簡單例子 樓主您好
---創建表
create table TESTTABLE
(
id1 VARCHAR2(12),
name VARCHAR2(32)
)
select t.id1,t.name from TESTTABLE t
insert into TESTTABLE (ID1, NAME)
values ('1', 'zhangsan');
insert into TESTTABLE (ID1, NAME)
values ('2', 'lisi');
insert into TESTTABLE (ID1, NAME)
values ('3', 'wangwu');
insert into TESTTABLE (ID1, NAME)
values ('4', 'xiaoliu');
insert into TESTTABLE (ID1, NAME)
values ('5', 'laowu');
---創建存儲過程
create or replace procere test_count
as
v_total number(1);
begin
select count(*) into v_total from TESTTABLE;
DBMS_OUTPUT.put_line('總人數:'||v_total);
end;
--准備
--線對scott解鎖:alter user scott account unlock;
--應為存儲過程是在scott用戶下。還要給scott賦予密碼
---alter user scott identified by tiger;
---去命令下執行
EXECUTE test_count;
----在ql/spl中的sql中執行
begin
-- Call the procere
test_count;
end;
create or replace procere TEST_LIST
AS
---是用游標
CURSOR test_cursor IS select t.id1,t.name from TESTTABLE t;
begin
for Test_record IN test_cursor loop---遍歷游標,在列印出來
DBMS_OUTPUT.put_line(Test_record.id1||Test_record.name);
END LOOP;
test_count;--同時執行另外一個存儲過程(TEST_LIST中包含存儲過程test_count)
end;
-----執行存儲過程TEST_LIST
begin
TEST_LIST;
END;
---存儲過程的參數
---IN 定義一個輸入參數變數,用於傳遞參數給存儲過程
--OUT 定義一個輸出參數變數,用於從存儲過程獲取數據
---IN OUT 定義一個輸入、輸出參數變數,兼有以上兩者的功能
......>>
問題九:如何使用sql語句查看存儲過程 --下面這條語句可以查看存儲過程具體代碼exec sp_helptext 存儲過程名--下面這條語句查看資料庫中有哪些存儲過程select * from sysobjects where type='P'
問題十:存儲過程中怎麼使用row 一般分為十種情況,每種語法各不相同: 1、 創建語法create proc | procere pro_name [{@參數數據類型} [=默認值] [output], {@參數數據類型} [=默認值] [output], .... ]as SQL_statements2、 創建不帶參數存儲過程--創建存儲過程if (exists (select * from sys.objects where name = 'proc_get_student')) drop proc proc_get_studentgocreate proc proc_get_studentas select * from student;--調用、執行存儲過程exec proc_get_student;3、 修改存儲過程--修改存儲過程alter proc proc_get_studentasselect * from student;4、 帶參存儲過程--帶參存儲過程if (object_id('proc_find_stu', 'P') is not null) drop proc proc_find_stugocreate proc proc_find_stu(@startId int, @endId int)as select * from student where id between @startId and @endIdgoexec proc_find_stu 2, 4;5、 帶通配符參數存儲過程--帶通配符參數存儲過程if (object_id('proc_findStudentByName', 'P') is not null) drop proc proc_findStudentByNamegocreate proc proc_findStudentByName(@name varchar(20) = '%j%', @nextName varchar(20) = '%')as select * from student where name like @name and name like @nextName;goexec proc_findStudentByName;exec proc_findStudentByName '%o%', 't%';6、 帶輸出參數存儲過程if (object_id('proc_getStudentRecord', 'P') is not null) drop proc proc_getStudentRecordgocreate proc proc_getStudentRecord( @id int, --默認輸入參數 @name varchar(20) out, --輸出參數 @age varchar(20) output--輸入輸出參數)as select @name = name, @age = age from student where id = @id and sex = @age;go-- declare @id int, @name varchar(20), @temp varchar(20)......>>
⑻ Hibernate中調用存儲過程並傳入Date型的參數出問題
你試驗一下
首先將日期格式轉換成你要的格式
SimpleDateFormat f = new SimpleDateFormat("yyyy-mm-dd hh:cc:ss");
保存的時候為
session.save(f.format(new Date());
試驗一下
另外在hibernate中設置date類型看看給它的長度也就是length是否超過