『壹』 如何動態執行sql語句
這里只介紹動態SQL的使用。關於動態SQL語句的語法,參見:http://blog.csdn.NET/chiclewu/article/details/16097133
1.什麼是時候需要使用動態SQL?
SQL文本在編譯時是未知的。
例如,SELECT語句包含的標識符(如表名)在編譯時是未知的,或者WHERE子句的條件數量在編譯時是未知。
靜態SQL不支持
例如,在PL/SQL中用靜態SQL只能執行查詢以及DML語句。如果想要執行DDL語句,只能使用動態SQL。
當讓使用靜態SQL,也有它的好處:
編譯成功驗證了靜態SQL語句引用有效的資料庫對象和訪問這些對象的許可權
編譯成功創建了模式對象的依賴關系
2.EXECUTE IMMEDIATE語句
EXECUTE IMMEDIATE語句的意思是使用本地動態SQL處理大多數動態SQL語句。
如果動態SQL語句是自包含的(也就是說,它的綁定參數沒有佔位符,並且結果不可能返回錯誤),則EXECUTE IMMEDIATE語句不需要子句。
如果動態SQL語句包行佔位符綁定參數,每個佔位符在EXECUTE IMMEDIATE語句的子句中必須有一個相應的綁定參數,具體如下:
如果動態SQL語句是一個最多隻能返回一行的SELECT語句,OUT綁定參數放置在INTO子句,IN綁定參數放置在USING子句。
如果動態SQL語句是一個可以返回多行的SELECT語句,OUT綁定參數放置在BULK COLLECT INTO子句,IN綁定參數放置在USING子句。
如果動態SQL語句是一個除了SELECT以外的其他DML語句,且沒有RETURNING INTO子句,所有的綁定參數放置在USING子句中。
如果動態SQL還語句一個匿名PL/SQL塊或CALL語句,把所有的綁定參數放置在USING子句中。
如果動態SQL語句調用一個子程序,請確保:
每個對應子程序參數佔位符的綁定參數與子程序參數具有相同的參數模式和兼容的數據類型。
綁定參數不要有SQL不支持的數據類型(例如,布爾類型,關聯數組,以及用戶自定的記錄類型)
USING子句不能包含NULL字面量。如果想要在USING子句中使用NULL值,可以使用位初始化的變數或者函數顯示將NULL轉換成一個有類型的值。
2.1動態SQL語句是一個最多隻能返回一行的SELECT語句
使用動態SQL語句返回單列,查詢SCOTT的薪水:
declare
v_sql_text varchar2(1000);
v_sal number;
v_ename emp.ename%type := 'SCOTT';
begin
v_sql_text := 'select e.sal from emp e where e.ename = :ename';
execute immediate v_sql_text
into v_sal
using v_ename;
dbms_output.put_line(v_ename || ':' || v_sal);
end;
使用動態SQL返回一條記錄,查詢SCOTT的基本信息:
declare
v_sql_text varchar2(1000);
v_ename emp.ename%type := 'SCOTT';
vrt_emp emp%rowtype;
begin
v_sql_text := 'select * from emp e where e.ename = :ename';
execute immediate v_sql_text
into vrt_emp
using v_ename;
dbms_output.put_line(v_ename || '的基本信息:');
dbms_output.put_line('工號:' || vrt_emp.empno);
dbms_output.put_line('工資:' || vrt_emp.sal);
dbms_output.put_line('入職日期:' || vrt_emp.hiredate);
end;
2.2動態SQL語句是一個可以返回多行的SELECT語句
2.2.1隻有一個佔位符
使用動態SQL語句返回多行記錄,查詢30部門的員工基本信息:
declare
v_sql_text varchar2(1000);
v_deptno emp.deptno%type := 30;
type nt_emp is table of emp%rowtype;
vnt_emp nt_emp;
begin
v_sql_text := 'select * from emp e where e.deptno = :deptno';
execute immediate v_sql_text bulk collect
into vnt_emp
using v_deptno;
for i in 1 .. vnt_emp.count loop
dbms_output.put_line(vnt_emp(i).ename || '的基本信息:');
dbms_output.put_line('工號:' || vnt_emp(i).empno);
dbms_output.put_line('工資:' || vnt_emp(i).sal);
dbms_output.put_line('入職日期:' || vnt_emp(i).hiredate);
dbms_output.put_line('');
end loop;
end
2.2.2多個佔位符
查詢20部門工資大於2000的員工基本信息:
declare
v_sql_text varchar2(1000);
v_deptno emp.deptno%type := 20;
v_sal number := 2000;
type nt_emp is table of emp%rowtype;
vnt_emp nt_emp;
begin
v_sql_text := 'select * from emp e where e.sal>:sal and e.deptno = :deptno';
execute immediate v_sql_text bulk collect
into vnt_emp
using v_sal, v_deptno; --注意綁定多個變數時,綁定變數只與佔位符位置有關,與佔位符名稱無關,
for i in 1 .. vnt_emp.count loop
dbms_output.put_line(vnt_emp(i).ename || '的基本信息:');
dbms_output.put_line('工號:' || vnt_emp(i).empno);
dbms_output.put_line('工資:' || vnt_emp(i).sal);
dbms_output.put_line('入職日期:' || vnt_emp(i).hiredate);
dbms_output.put_line('');
end loop;
注意:對於SQL文本,佔位符名稱是沒有意義的,綁定變數與佔位符名稱無關,只與佔位符的配置有關。即使有多個相同名稱佔位符,也需要每個佔位符對應一個綁定變數。對於PL/SQL塊,佔位符名稱是有意義的,相同名稱的佔位符,只需要第一個佔位符綁定變數。
2.3動態SQL語句是一個帶有RETURNING子句的DML語句
KING的工資增長20%,返回增長後的工資:
eclare
v_sql_text varchar2(1000);
v_sal number;
v_ename emp.ename%type := 'KING';
begin
v_sql_text := 'update emp e set e.sal= e.sal*1.2 where e.ename = :ename returning e.sal into :sal';
execute immediate v_sql_text
using v_ename
returning into v_sal;
dbms_output.put_line(v_ename || ':' || v_sal);
end;
注意:只有當v_sql_text語句有returning into子句時,動態SQL語句才能使用returning into子句。
2.4給佔位符傳遞NULL值
2.4.1通過未初始化變數傳遞NULL值
declare
v_sql_text varchar2(1000);
v_deptno emp.ename%type := 'ALLEN';
v_comm emp.comm%type;
begin
v_sql_text := 'update emp e set e.comm = :comm where e.ename =:ename';
execute immediate v_sql_text
using v_comm, v_deptno;
end;
2.4.2通過函數將NULL值顯式的轉換成一個有類型的值
declare
v_sql_text varchar2(1000);
v_deptno emp.ename%type := 'ALLEN';
begin
v_sql_text := 'update emp e set e.comm = :comm where e.ename =:ename';
execute immediate v_sql_text
using to_number(null), v_deptno;
end;
3.OPEN FOR語句
PL/SQL引入OPEN FOR語句實際上並不是為了支持本地動態SQL,而是為了支持游標變數。現在它以一種極其優雅的方式實現了多行的動態查詢。
使用OPEN FOR語句來關聯動態SQL語句的游標變數,在OPEN FOR語句的USING子句中,指定動態SQL語句每個佔位符的綁定參數。
使用FETCH語句獲取運行時結果集。
使用CLOSE語句關閉游標變數
使用OPEN FOR語句查詢出10部門的員工的基本信息:
declare
type rc_emp is ref cursor;
vrc_emp rc_emp;
v_sql_text varchar2(1000);
v_deptno emp.deptno%type := 10;
vrt_emp emp%rowtype;
begin
v_sql_text := 'select * from emp e where e.deptno=:deptno';
open vrc_emp for v_sql_text
using v_deptno;
loop
exit when vrc_emp%notfound;
fetch vrc_emp
into vrt_emp;
dbms_output.put_line(vrt_emp.ename || '的基本信息:');
dbms_output.put_line('工號:' || vrt_emp.empno);
dbms_output.put_line('工資:' || vrt_emp.sal);
dbms_output.put_line('入職日期:' || vrt_emp.hiredate);
dbms_output.put_line('');
end loop;
close vrc_emp;
end;
4.重復的佔位符名稱
如果在動態SQL語句重復佔位符名稱,要知道佔位符關聯綁定參數的方式依賴於動態語句的類型。
如果執行的是一個動態SQL字元串,則必須為每一個佔位符提供一個綁定參數,即使這些佔位符是重復的。
如果執行的是一個動態PL/SQL塊,則必須為每一個唯一佔位符提供一個綁定參數,即重復的佔位符只需要提供一個綁定參數。
4.1重復佔位符的動態SQL字元串
declare
v_sql_text varchar2(1000);
v_sal emp.sal%type := 4000;
v_comm emp.comm%type;
v_ename emp.ename%type := 'SCOTT';
begin
v_sql_text := 'update emp e set e.sal=:sal , e.comm = :sal*0.1 where e.ename =:ename returning e.comm into :comm ';
execute immediate v_sql_text
using v_sal, v_sal, in v_ename
returning into v_comm;
dbms_output.put_line(v_ename || '分紅:' || v_comm);
end;
4.2重復佔位符的動態PL/SQL塊
declare
v_sql_text varchar2(1000);
v_sal number;
v_ename emp.ename%type := 'KING';
begin
v_sql_text := ' begin select e.sal,e.ename into :sal,:ename from emp e where e.ename =:ename; end;';
execute immediate v_sql_text
using out v_sal, in out v_ename;
dbms_output.put_line(v_ename || ':' || v_sal);
end;
『貳』 如何生成ibatis 動態sql
IBATIS:最大的優點是可以有效的控制sql發送的數目,提高數據層的執行效率!好象阿里巴巴現在就用的是IBATIS;它需要程序員自己去寫sql 語句,不想hibernate那樣是完全面向對象的,自動化的,ibatis是半自動化的,通過表和對象的映射以及手工書寫的sql語句,能夠實現比 hibernate等更高的查詢效率。
給個文章你參考下:
1.優點
簡單:
易於學習,易於使用,通過文檔和源代碼,可以比較完全的掌握它的設計思路和實現。
實用:
提供了數據映射功能,提供了對底層數據訪問的封裝(例如ado.net),提供了DAO框架,可以使我們更容易的開發和配置我們的DAL層。靈活:
通過sql基本上可以實現我們不使用數據訪問框架可以實現的所有功能,或許更多。功能完整:
提供了連接管理,緩存支持,線程支持,(分布式)事物管理,通過配置作關系對象映射等數據訪問層需要解決的問題。提供了DAO支持,並在DAO框架中封裝了ADO.NET,NHibernate和DataMapper。增強系統的可維護性:
通過提供DAL層,將業務邏輯和數據訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql和代碼的分離,提高了可維護性。
2.缺點
滯後性:
還沒有明確對.NET2.0的支持。最新版本在2.0下編譯可以,但有些單元測試不能通過。
不成熟,工程實踐較少:
IbatisNet在實際項目中的使用較少。 只是理論上可行.
半ORM,工具支持較少:
需要我們自己寫sql,並且.NET下還未發現可以自動生成業務層類和配置文件的工具,這點和NHibernate不一樣,NHibernate會為我們的資料庫直接產生sql,並有一些輔助工具。因此使用Ibatis比NHibernate要多做一些工作。
3.可行性
沒有最好的框架,只有最適合的框架。存在的便是合理的,它存在就說明有它存在的道理。但它未必為我們存在。所以選擇一個框架最主要的是看它對你有沒有意義,意義有多大,是不是比其他框架帶給你的好處要多。沒有絕對的優點也沒有絕對的缺點,重要的是看在什麼情況下討論。上面說了部分的Ibatis的優點和部分缺點。這些優點從理論上證明Ibatis對任何數據持久層都合適,但未必是最好的選擇。下面對上面的優缺點分別從兩方面討論。簡單:我們都喜歡簡單,簡單意味著學習成本低,使用中出錯的可能性低。同時,簡單的東西一般來說功能不夠強大。反過來,復雜的東西學習成本高,用起來不方便,並且團隊沒有很強的技術實力,一般不要使用。實用:
解決了項目中需要解決的問題,這是任何實際工程中採用的框架和工具都應具有的性質,否則就不要拿到實際項目中來。靈活:靈活有兩層意思,一種是簡單易擴展,另一種是功能強大提供了很多選項。Ibatis屬於前者,Hibernate屬於後者。兩者各有優缺點。功能完整: Ibatis的功能完整也是相對的,比我們自己開發的框架應該完整,但對比其他框架肯定也有一些解決不了的問題。增強系統的可維護性:利用Ibatis可以做到sql和代碼分離,可以設計出一個清晰的數據訪問層(DAL)。但項目架構是否科學合理,是否以維護,關鍵不在Ibatis,因為它只是一個數據層框架。但是我們也不得不清楚,要想發揮Ibatis的優勢,我們需要做一些額外工作,比如最好設計DAO介面,需要將業務層實體和對實體的訪問放在不同的工程中,同時需要維護xml配置文件。滯後性: Ibatis組現在還沒有提到要支持.NET2.0,很多人在.NET2.0下使用Ibatis都出現了問題。所以如果要使用.NET2.0開發,IBatis不是一個好選擇,還需要等待。不成熟:開源的東西很難說成熟,但一般比我們自己寫的框架要成熟。由於我們可以拿到他的源代碼,所以關鍵在於我們能否駕馭它。半ORM,工具支持少:這註定了Ibatis不能從本質上提升開發效率,我們需要自己寫sql,寫實體類,寫配置文件。但這也是它優越的地方,它沒有為我們做的他多,所以我們就有更多的施展空間。而且它非常適合那些並不能完全控制資料庫的系統和需要利用資料庫本身提供的高級特性的統計查詢系統的開發。
使用Ibatis需要自己寫sql,由於我們的sql不可能完全符合sql標准,比起NHibernate產生的sql來,可移植性差。不過由於我們更改資料庫的可能性較小,對我們來說sql符合標准以便可以在遷移到不同伺服器時代價最小並不是十分必要的。另一方面,NHibernate雖然可以屏蔽很多資料庫間的不同,但是卻很難利用某些資料庫的高級特性,比如Oracle的分析統計函數。
NHibernate不適合資料庫模式不規范,約束不完整,需要大量復雜查詢的系統,同時NHibernate的學習成本較高,完全掌握 NHibernate也較困難,風險較大。 自己寫框架未必比Ibatis的好,穩定,強大和可擴展。而且自己開發框架也需要較大的工作量。如果使用DotNet並且要選一個數據層框架,而系統中有相當一部分較復雜的sql,或資料庫設計不合理,臟數據多,對性能和資源要求嚴格,Ibatis 是一個比較不錯的選擇。他的那些缺點並不是致命的,而且也是有一些解決方案的。尤其是,當選用了Ibatis的DataAccess作為DAO框架時,我們可以同時使用NHibernate,ADO.NET和DataMapper(IbatisNet的核心組件),那樣將會使風險降到最低,並且整個系統的框架比較合理。
另外,利用Ibatis可以統一編碼風格,節約開發成本,大家不會再把精力浪費到分頁 連接池 主鍵生成等地方了,可以集中精力進行業務組件的編寫。
綜上:
很多時候我們要在是自己開發框架和選用第三方框架和選用什麼樣的框架問題上進行綜合考慮。考慮的標准當然是項目的當前情況和我們希望達到目的的一個平衡。
Ibatis只是封裝了數據訪問層,替我們做了部分的對象關系映射。但我們的代價是必須要寫xml配置文件,相對於Hibernate我們還要寫很多 sql。Hibernate通過工具直接從資料庫模式生成實體類和基本的配置文件,而且大部分情況下不需要我們寫sql,會較大的提升開發效率。但這些也有很多的局限性,尤其是對環境的要求較高(資料庫設計,對象設計,團隊的協作等)。個人感覺Ibatis對項目比較有意義的地方在於它小巧靈活,可擴展,封裝了數據訪問層(事務,緩存,異常,日誌),並提供了DAO框架支持。
利用Ibatis我們可以做到代碼和sql的分離,只要sql能夠解決的問題,Ibatis就能幫我們較容易的解決,同時也使我們的項目對某一框架的依賴性變小(因為Ibatis是非侵入性的)。這將極大的降低項目風險,減少解決復雜問題的時間,使項目的維護變得簡單。
Ibatis對於應用的修改,調試,擴充和維護將會變得容易自然。修改時,我們主要修改的是代表模型的實體對象,xml配置文件中的sql,和/或配置文件的ResultMap(很多時候是不需要的)。同時,sql和代碼分離,我們不用在代碼的StringBuffer的append方法之間尋找需要修改的sql。配置文件中的sql便利了我們的調試和對sql的評審及以後的sql重用。
利用一些框架在前期一般會拖慢開發效率。因為我們需要付出學習成本,很多時候,使用框架需要寫很多配置文件,在使用不熟時開發速度較慢;同時利用框架往往使系統代碼量增大,比如Model1和Model2模型,開發效率應該還是Model1快,四層的架構肯定比兩層的代碼量大。但對於中後期開發和維護將會極大的提高效率。
利用一些較完全的開發框架和代碼生成工具,在前期會較大的提高開發效率,但在後期常常會拖慢進度,並有可能成為以後維護的夢魘。比如torque生成實體類和其對應的sql,雖大幅提高了效率,但修改負擔較大。
比較理想的開發方式是使用簡單框架結合簡單的代碼生成工具。框架提供系統的基礎服務,並規范開發。框架一方面提供了開發中某一方面的開發基礎支持,比如數據訪問層,事務,日誌,公用類,異常等。另一方面,也為開發定義了模式,定義了系統的基本輪廓。同時,通過簡單的代碼生成工具生成部分低級的代碼。比如通過工具從資料庫模式生成實體類。這些類生成後我們可以自由修改。
Hibernate是十分強大,比較完善的ORM框架,不過這是它的優點也是它的缺點。 j2ee系統是否採用Hibernate3,是一個需要認真評估的問題。
要想Hibernate工作的好,資料庫的設計必須好。同時對於復雜的數據操作同時需要使用sql,Hibernate3對於直接使用sql的支持比Hibernate2要自然,這一點是可以接受的。
Hibernate比較復雜,功能強大而靈活,要用好Hibernate確實不是很簡單,當然Spring框架提供了對Hibernate的封裝,使 Hibernate的使用變得簡單了點。可以說Ibatis在任何系統里都適用,但未必是最好選擇。不過Ibatis提供的思路是我們應該仔細考慮的。
『叄』 怎樣在DAL層調用SQL寫好的存儲過程及BLL層的調用
BLL:public class TestBll { ITestDal dal = TestFactory.CreateDal(); public string GetData() { return dal.GetData(); } } IDAL: public interface ITestDal { public string GetData(); } DAL: public class TestDal : ITestDal { public override string GetData() { return "test"; } } Factory: public class TestFactory { public static ITestDal CreateDal() { return new TestDal(); } }
『肆』 ASP.NET為什麼我的sql語句一直不執行我的DAL層是這樣寫的,別的層沒問題
我net學的不好,看不懂你寫的。
strpassworpdate(string departmentname, string password1)這個是你定義的函數名和參數。
那麼在寫sql語句的時候就這樣寫:
string strsql = "update DanWei set password='"+password1+"' where departname='"+departmentname+"'";
我不知道你寫的是不是對的,但是最好就是能輸出你的sql語句,然後拿這個語句到資料庫去執行,看看能不能成功。
能成功說明不是sql的問題,說不定就是你的資料庫連接封裝的函數寫錯了。
『伍』 什麼是動態SQL語句
所謂動態sql,其實就是把sql語句使用字元串組裝起來,然後使用 exec 關鍵字來運行的 語句。
如:
declare @sql = 'select 1 + 2'
exec @sql
這里的@sql就是動態sql
『陸』 ASP.NET我的DAL層是這么寫的,別的層都沒問題,為什麼sql語句不執行
這個無從下手,你到底是走語句呢還是存儲過程呢,cf里怎麼寫的呢? ss是打醬油的嗎?
『柒』 Dal層的sql帶參數的模糊查詢語句
DataTable dt = SqlHelper.ExecuteDataTable("Select * from T_Warehouse where Material like @Material",new SqlParameter("@Material",string.Format("%{0}%", material));
這樣寫。
『捌』 dal是數據連接層,寫sql語句,添刪改查,然後有返回值.BLL是業務邏輯層,model又是做什麼用的,可以不用它嗎
DAL是數據連接層,寫sql語句,添刪改查方法,然後有返回值。BLL是業務邏輯層,這裡面不寫sql語句,可以調用DAL層傳過來的值做判斷分析,並返回相應的值。最後在頁面的隱藏代碼中調用BLL的方法。
<connectionStrings>
<add name="ConnectionString" connectionString="Data Source=.;Initial Catalog=Database;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
對你的DAL項目右鍵添加System.Configuration引用(必須步驟),
添加Model項目引用
然後在DB類(假設為UserDAL.cs)
using System.Configuration;//這個必須.
using Model那個項目
public class UserDAL
{
public const string ConnectionString = ConfigurationManager.ConnectionStrings [ "ConnectionString" ].ConnectionString;
public int Insert(UserInfo user)// Model
{
SqlConnection sqlcon=new SqlConnection ( ConnectionString );
.................
}
}
BLL
添加DB和Model項目引用
using 那個DB
public class UserBLL
{
public int Insert(UserInfo user)
{
int i = UserDAL.Insert(user);
}
}
『玖』 ASP.NET 中DAL層的SQL語句問題.
第一種比較直觀吧,不過不建議上邊的寫法,容易sql注入,還是建議用參數比較好