2010年5月5日
1. oncontextmenu="window.event.returnValue=false" 將徹底屏蔽鼠標(biāo)右鍵,其實(shí)是禁止快捷菜單,因?yàn)椴还庥益I可以彈出這個(gè)菜單,鍵盤上空格鍵右邊的windows鍵也可以激活這個(gè)快捷菜單
<table border oncontextmenu=return(false)><td>no</table> 可用于Table
2. <body onselectstart="return false"> 禁止選取、防止復(fù)制
3. onpaste="return false" 禁止粘貼
4. oncopy="return false;" oncut="return false;" 禁止復(fù)制和剪切
5. <input style="ime-mode:disabled"> 關(guān)閉輸入法

一般用這三個(gè)就足夠了

<body onselectstart='return false' ondrag='return false' oncontextmenu='return false'>

Tomcate啟動(dòng)內(nèi)存設(shè)置

其初始空間(即-Xms)是物理內(nèi)存的1/64,最大空間(-Xmx)是物理內(nèi)存的1/4??梢岳肑VM提供的-Xmn -Xms -Xmx等選項(xiàng)可
進(jìn)行設(shè)置
實(shí)例,以下給出1G內(nèi)存環(huán)境下java jvm 的參數(shù)設(shè)置參考:
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "
JAVA_OPTS="-server -Xms768m -Xmx768m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:
NewSize=192m -XX:MaxNewSize=384m"
CATALINA_OPTS="-server -Xms768m -Xmx768m -XX:PermSize=128m -XX:MaxPermSize=256m
-XX:NewSize=192m -XX:MaxNewSize=384m"


Linux:
在/usr/local/apache-tomcat-5.5.23/bin目錄下的catalina.sh
添加:JAVA_OPTS='-Xms512m -Xmx1024m'
要加“m”說(shuō)明是MB,否則就是KB了,在啟動(dòng)tomcat時(shí)會(huì)報(bào)內(nèi)存不足。
-Xms:初始值
-Xmx:最大值
-Xmn:最小值


Windows
在catalina.bat最前面加入
set JAVA_OPTS=-Xms128m -Xmx350m
如果用startup.bat啟動(dòng)tomcat,OK設(shè)置生效.夠成功的分配200M內(nèi)存.
但是如果不是執(zhí)行startup.bat啟動(dòng)tomcat而是利用windows的系統(tǒng)服務(wù)啟動(dòng)tomcat服務(wù),上面的設(shè)置就不生效了,
就是說(shuō)set JAVA_OPTS=-Xms128m -Xmx350m 沒(méi)起作用.上面分配200M內(nèi)存就OOM了..

windows服務(wù) 執(zhí)行的是bin\tomcat.exe.他讀取注冊(cè)表中的值,而不是catalina.bat的設(shè)置.
解決辦法:
修改注冊(cè)表HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Procrun 2.0\Tomcat6\Parameters\JavaOptions
原值為
-Dcatalina.home=E:\Tomcat 6.0
-Dcatalina.base=E:\Tomcat 6.0
-Djava.endorsed.dirs=E:\Tomcat 6.0\common\endorsed
-Djava.io.tmpdir=E:\Tomcat 6.0\temp
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.util.logging.config.file=E:\Tomcat 6.0\conf\logging.properties

加入 -Xms300m -Xmx350m

重起tomcat服務(wù),設(shè)置生效

本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/peijunlin/archive/2009/06/05/4244401.aspx
INSTEAD OF 觸發(fā)器
AFTER 觸發(fā)器(也叫“FOR”觸發(fā)器)會(huì)在觸發(fā) insert、update 或是delect 動(dòng)作之后執(zhí)行。例如,一個(gè) Employees 表上的 AFTER 觸發(fā)器會(huì)在在 Employee 表上執(zhí)行一條 update 語(yǔ)句后激活。因此,AFTER 觸發(fā)器只有在已插入一行或是多行和所有約束已被處理且通過(guò)后才觸發(fā)。INSTEAD OF 觸發(fā)器和 AFTER 觸發(fā)器有本質(zhì)上的不同,因?yàn)?nbsp;INSTEAD OF 觸發(fā)器代替觸發(fā)動(dòng)作進(jìn)行激發(fā)。就拿同樣的例子來(lái)說(shuō),如果在 Emplyees 表上有一個(gè) INSTEAD OF UPDATE 觸發(fā)器和在這個(gè)表上執(zhí)行一條 UPDATE 語(yǔ)句,結(jié)果是這條 UPDATE 語(yǔ)句并不會(huì)改變 Employee 表中的任何一行。相反,這條 UPDATE 語(yǔ)句只有是為了踢離 INSTEAD OF UPDATE 觸發(fā)器,這個(gè)觸發(fā)器可能會(huì),也可能不會(huì)改變 Employees 表中的數(shù)據(jù)。
因此,怎么決定在合適的時(shí)間和位置放置 INSTEAD OF 觸發(fā)器呢?有幾個(gè)關(guān)鍵的因素在做決定是值得考慮的。AFTER 觸發(fā)器多用在動(dòng)作必須在表中數(shù)據(jù)發(fā)生改變之后才執(zhí)行后情情況。比如,AFTER 觸發(fā)器可以用于將對(duì)數(shù)據(jù)作任何變動(dòng)的日志記錄在一個(gè)相對(duì)獨(dú)立的審計(jì)表中。INTEAD OF 觸發(fā)器也能做同樣的工作。但是 INSTEAD OF 觸發(fā)器在這個(gè)情況下的效率比較低,因?yàn)楦聞?dòng)作只能在將它發(fā)生的動(dòng)作準(zhǔn)確地記錄在審計(jì)表之后才允許執(zhí)行。
一般來(lái)說(shuō),只要不影響數(shù)據(jù)的修改,AFTER 觸發(fā)器比 INSTEAD OF 觸發(fā)器更有效率。在對(duì)數(shù)據(jù)進(jìn)行計(jì)算或是對(duì)數(shù)據(jù)的修改作為一個(gè)整體提交或是作為一個(gè)整體回退的情況下,AFTER 觸發(fā)器也是一個(gè)很好的選擇。例如,存在這樣一條規(guī)則:對(duì)在 Products 表的產(chǎn)品價(jià)格的變動(dòng)超過(guò)30%的必須回退。AFTER 觸發(fā)器能很漂亮地完成這個(gè)工作,它利用已插入同已刪除的表中的產(chǎn)品價(jià)格作比較,然后在有必要的時(shí)回滾事務(wù)。這些都是 AFTER 觸發(fā)器的理想條件,但有時(shí) INSTEAD OF會(huì)更好些。
INSTEAD OF 觸發(fā)器有一個(gè)很大的特點(diǎn)——就是它允許你在某個(gè)表或視圖上用多個(gè)復(fù)雜的查詢操作來(lái)代替單一的查詢。跟 AFTER 觸發(fā)器只能對(duì)表起作用不同,INSTEAD OF 觸發(fā)器可以同時(shí)對(duì)表和視圖起作用。我常常被問(wèn)到怎么樣去解決這種情況:有一個(gè)多表組成的視圖,如何對(duì)該視圖進(jìn)行一次更新。如果視圖包含有關(guān)鍵字段和包含有基本表的某些字段,這只是簡(jiǎn)單的更新基本表。但是,當(dāng)有視圖中包含有多個(gè)基本表示,邏輯上的更新比單單一個(gè) UPDATE 語(yǔ)句會(huì)更復(fù)雜。因此,你是怎么利用什么可以替代的工具來(lái)解決這個(gè)問(wèn)題的呢?其中一個(gè)方法就是將一個(gè)INSTEAD OF 觸發(fā)器放在視圖上。INSTEAD OF 觸發(fā)器可以定義在一個(gè)或多個(gè)表上.INSTEAD OF 觸發(fā)器就能轉(zhuǎn)開(kāi)在多個(gè)基本表中修改的范圍.
例如,如果一個(gè)視圖將 Customers、Products、orders 和 OrderDteils 等表合并成一個(gè)視圖,并利用視圖通過(guò)程序在屏幕上來(lái)顯示所有的數(shù)據(jù)。更新操作便允許用來(lái)代替這個(gè)視圖,假如存在一個(gè)這個(gè)樣的視圖:它包含 Northwind 數(shù)據(jù)庫(kù)中的四個(gè)表,并且被命名為vwCustomersOrdersOrderDetailsProducts,它看起來(lái)像這樣(Figure 1):

Figure 1 連接 Customers 及其 Order Details 的視圖

CREATE VIEW vwCustomersOrdersOrderDetailsProducts
AS
SELECT c.CustomerID,
c.CompanyName,
o.OrderID,
o.OrderDate,
od.UnitPrice,
od.Quantity,
od.Discount,
p.ProductID,
p.ProductName
FROM Customers c
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN [Order Details] od ON o.OrderID = od.OrderID
INNER JOIN Products p ON od.ProductID = p.ProductID
GO
vwCustomersOrdersOrderDetailsProducts 視圖連接著四個(gè)表,并且每個(gè)表都暴露一個(gè)取樣字段。必須記住的一點(diǎn)是,當(dāng)你設(shè)計(jì)一個(gè)含有 INSTEAD OF UPDATE 的觸發(fā)器時(shí),將每個(gè)表的主關(guān)鍵字段包含在SELECT語(yǔ)句中是很有益的做法。即使這些字段在應(yīng)用程序不會(huì)用到,它們也以在 INSTEAD OF 觸發(fā)器中用來(lái)定位將要被修改的行,然后對(duì)基表作相應(yīng)的修改。假設(shè)你打算允許更新該視圖以便按非關(guān)鍵字過(guò)濾基表。更新代碼應(yīng)該寫在 INSTEAD OF UPDATE 觸發(fā)器中,讓觸發(fā)器去更新 Customers 表中的 CompnayName 列,Orders 表中的 OrderDate 列,Order Details 表的 UnitPrice 和 Quantity 列以及在 Products 表中的 ProductName 列。在這種情況下,使用 AFTER 觸發(fā)器就不適合了,而 INSTEAD OF 觸發(fā)器則是一個(gè)很好的選擇,參見(jiàn) Figure 2: Figure 2 用 INSTEAD OF 觸發(fā)器更新視圖

CREATE TRIGGER tr_vwCustomersOrdersOrderDetailsProducts_IO_U
ON vwCustomersOrdersOrderDetailsProducts
INSTEAD OF UPDATE
AS
— 更新 Customers
UPDATE Customers
SET CompanyName = i.CompanyName
FROM inserted i
INNER JOIN Customers c ON i.CustomerID = c.CustomerID

— 更新 Orders
UPDATE Orders
SET OrderDate = i.OrderDate
FROM inserted i
INNER JOIN Orders o ON i.OrderID = o.OrderID

— 更新 Order Details
UPDATE [Order Details]
SET UnitPrice = i.UnitPrice,
Quantity = i.Quantity
FROM inserted i
INNER JOIN [Order Details] od ON i.OrderID = od.OrderID AND
i.ProductID = od.ProductID

— 更新 Products
UPDATE Products
SET ProductName = i.ProductName
FROM inserted i
INNER JOIN Products p ON i.ProductID = p.ProductID
GO
注意在 Figure 2 中的 INSTEAD OF UPDATE 觸發(fā)器包含了四個(gè) UPDATE 語(yǔ)句。每個(gè) UPDATE語(yǔ)句目的都是為了對(duì)其中一個(gè)基表中的非關(guān)鍵字段進(jìn)行修改。在 UPDATE 語(yǔ)句中包含了每個(gè)表中的關(guān)鍵字段對(duì)應(yīng)于視圖中的字段。這樣就允許 UPDATE 語(yǔ)句在相應(yīng)的表中定位對(duì)應(yīng)的列并只對(duì)這些列作修改。下面的 UPDATE 語(yǔ)句將對(duì) INSTEAD OF 觸發(fā)器進(jìn)行測(cè)試: UPDATE vwCustomersOrdersOrderDetailsProducts
SET Quantity = 100,
UnitPrice = 20,
CompanyName = ''''Fake Name'''',
OrderDate = ''''11/23/2001'''',
ProductName = ''''Widget''''
WHERE OrderID = 10265
AND ProductID = 17
如果你(通過(guò)視圖或是表自身)檢查相應(yīng)表中的值,很明顯,這些值已被更新了。當(dāng)然,對(duì)INSTEAD OF 觸發(fā)器作一些改變會(huì)使其有不同的結(jié)果。例如,不存在寫一個(gè)觸發(fā)器去改變四個(gè)基表的需求,因此,可以將觸發(fā)器中的一個(gè)或是多個(gè) UPDATE 語(yǔ)句刪去。假設(shè) INSTEAD OF 觸發(fā)器僅僅是為了更新 Order Details 表的值,這就會(huì)僅僅更新在 Order Details 表中的字段,而忽視任何在其他基表上的修改。在這種情況下,在 Customers,Products 或是 Orders 表中不會(huì)產(chǎn)生任何錯(cuò)誤同時(shí)也不會(huì)發(fā)生任何改變。當(dāng)然,如果這三個(gè)表中的某些字段發(fā)生改變的話,會(huì)發(fā)生報(bào)錯(cuò)。如我呆會(huì)在這篇文章會(huì)討論的一樣,UPDATE 和 COLUMNS_UPDATED 函數(shù)是個(gè)檢測(cè)哪些字段發(fā)生改變的理想的方法。
Figure 2 也演示了怎么寫一個(gè)觸發(fā)器修改多行記錄。注意到 UPDATE 語(yǔ)句如何按關(guān)鍵字連接被插入的表和各個(gè)基表。這就保證更新是對(duì)所有的行,這些行在視圖中被原有的 UPDATE 語(yǔ)句修改。通過(guò)循環(huán)被插入表的記錄行也能完成該操作。不管怎么樣,通常避免使用游標(biāo)是個(gè)好主意,尤其是在使用觸發(fā)器時(shí)更應(yīng)如此。SQL SERVER 被設(shè)計(jì)成以數(shù)據(jù)集的方式來(lái)處理數(shù)據(jù),而游標(biāo)是為一次處理一個(gè)數(shù)據(jù)行而設(shè)計(jì)的。在觸發(fā)器中使用游標(biāo)會(huì)降低程序的性能,因此,最好能使用象 Figure 2 中那樣更有效代替方法或使用一個(gè)子查詢。
另一個(gè)改變 INSERT OF UPDATE 觸發(fā)器的方法就是使其在視圖的 INSERT 和 DELETE 語(yǔ)句中激發(fā)。這也就意味著在適當(dāng)?shù)牡胤?,觸發(fā)器會(huì)實(shí)現(xiàn) INSERT 或是 DELETE 的功能。但是必須記隹的是 DELETE 可能會(huì)刪除多個(gè)記錄,這關(guān)鍵在于觸發(fā)器是怎樣寫的。因此,檢查觸發(fā)器的需求,在實(shí)現(xiàn)之前進(jìn)行測(cè)試,這些做法十分重要。INSERT OF UPDATE 觸發(fā)器可寫在視圖中,因此它可插入一個(gè)新的顧客、訂單、詳細(xì)的訂單和產(chǎn)品。這個(gè)觸發(fā)器也可以用來(lái)在插入一個(gè)新顧客之前檢查這個(gè)顧客是否是新的(對(duì)其它記錄的操作也是一樣)。當(dāng)采用的是 INSTEAD OF 觸發(fā)器時(shí)存在有許多機(jī)會(huì),但是,當(dāng)然,觸發(fā)器是為解決相應(yīng)的需求這才是它的本質(zhì)。
通常,當(dāng)引用一張表的 UPDATE 語(yǔ)句試圖去賦值一個(gè)計(jì)算型的,恒等型的或是時(shí)間戳型的列時(shí),會(huì)產(chǎn)生一個(gè)錯(cuò)誤,因?yàn)檫@些列的值必須是由SQL SERVER來(lái)決定的。這些列必須被包含在UPDATE 語(yǔ)句中以便能滿足列不能為空的要求。但是,如果 UPDATE 語(yǔ)句用 INSTEAD OF 觸發(fā)器引用一個(gè)視圖,定義在觸發(fā)器中的邏輯可以旁路掉這些列來(lái)避免錯(cuò)誤的發(fā)生。為了達(dá)到這個(gè)目的,觸發(fā)器決不能嘗試去更新基表中相應(yīng)列的值(讓它們遠(yuǎn)離 UPDATE 語(yǔ)句的 SET 從句)。當(dāng)某一條被處理的記錄來(lái)自被插入的表時(shí),計(jì)算型的,恒等型的或是時(shí)間戳型的列可以用一個(gè)虛假值以滿足不為空值的要求,這時(shí),INSTEAD OF 觸發(fā)器將忽略這些值,正確的值由 SQL SERVER 設(shè)置。

更新分開(kāi)的列
INSTEAD OF 觸發(fā)器也很普遍地用于更新基表中計(jì)算型的列。例如,假設(shè)存在有如下這樣一個(gè)叫 vwOrdersOrderDetailsProducts 的視圖: CREATE VIEW vwOrdersOrderDetailsProducts
AS
SELECT o.OrderID,
o.OrderDate,
od.UnitPrice * od.Quantity AS ExtendedPrice,
p.ProductID,
p.ProductName
FROM Orders o
INNER JOIN [Order Details] od ON o.OrderID = od.OrderID
INNER JOIN Products p ON od.ProductID = p.ProductID
GO

這個(gè)視圖揭示了一個(gè)計(jì)算型的列叫ExtendedPrice,這個(gè)列不能被直接被更新,因?yàn)樗荒軐⑵渥约鹤優(yōu)楸碇歇?dú)立的一列。雖然你可實(shí)現(xiàn)這樣一個(gè)生意規(guī)則,在這個(gè)規(guī)則中ExtendedPrice通過(guò)這個(gè)視圖來(lái)修改,Quantity列不應(yīng)修改,但是UnitPrice可被修改(我知道這條規(guī)則有點(diǎn)奇怪,但我可以忍受這點(diǎn))??梢詫懸粋€(gè)INSTEAD OF UPDATE觸發(fā)器來(lái)增強(qiáng)這條生意規(guī)則,其代碼如下所示: CREATE TRIGGER tr_vwOrdersOrderDetailsProducts_IO_U
ON vwOrdersOrderDetailsProducts
INSTEAD OF UPDATE
AS
UPDATE [Order Details]
SET UnitPrice = i.ExtendedPrice / Quantity
FROM inserted i
INNER JOIN [Order Details] od ON i.OrderID = od.OrderID AND
i.ProductID = od.ProductID

GO

這些代碼揭示了怎樣用一個(gè)在INSTEAD OF 觸發(fā)器中的邏輯來(lái)代替對(duì)一個(gè)計(jì)算型列的更新。假設(shè)一個(gè)產(chǎn)品在一張?zhí)囟ǖ亩▎伪碇蠶uantity為100而ExtendedPrice要更新為200,這時(shí)新的UnitPrice值就變?yōu)?。在這種情況下,在執(zhí)行一個(gè)對(duì)ExtendedPrice列進(jìn)行修改的UPDATE語(yǔ)句時(shí),最終的結(jié)果是UnitPrice被賦為ExtendedPrice除以Quantity的商。下面的代碼可以用來(lái)測(cè)試這種情況: UPDATE vwOrdersOrderDetailsProducts
SET ExtendedPrice = 200
WHERE OrderID = 10265
AND ProductID = 17

檢查改變
在INSTEAD OF和AFTER觸發(fā)器中都有UPDATE和COLUMNS_UPDATE功能,這二種功能允許由觸發(fā)器決定哪些字段由觸發(fā)器的語(yǔ)句來(lái)改變。例如,下面的觸發(fā)器阻止任何對(duì)Employees表中的lastname字段進(jìn)行修改。在這里,UPDATE功能用來(lái)決定對(duì)哪些對(duì)字段的修改可以執(zhí)行。如果超出發(fā)生了改變(而又是不允許修改的)就會(huì)產(chǎn)生一個(gè)錯(cuò)誤。PAISERR OR功能和事務(wù)就會(huì)回退,回退會(huì)撤消所做的任何修改。UPDATE功能都可以在AGTER觸發(fā)器和INSTEAD OF觸發(fā)器中工作,而不是在外部工作。 CREATE TRIGGER tr_Employees_U on Employees AFTER UPDATE AS
IF UPDATE(lastname)
BEGIN
RAISERROR (''''cannot change lastname'''', 16, 1)
ROLLBACK TRAN
RETURN
END
GO

UPDATE功能是為了判斷單一列是否被INSERT或是UPDATE語(yǔ)句修改過(guò)。UPDATE(列)是一個(gè)用來(lái)檢測(cè)更新的標(biāo)準(zhǔn)的方法。但是當(dāng)需要用來(lái)他檢測(cè)多列是否受到INSERT或UPDATE語(yǔ)句的影響時(shí)就變得更低效率。而這恰恰是COLUM_UPDATE功能的一個(gè)亮點(diǎn)。COLUMN_UPDATE功能返回一個(gè)位掩碼來(lái)判斷特定的列是否被修改過(guò)。位掩碼是包含在被表中被修改的列中的一個(gè)比特,目的是為了在表模式中定義這些列。如果一行修改,這比特位的值就為1,否則為0。不像從右到左地讀字節(jié)的常規(guī)方法,位掩碼是從左往右讀。例如,下面的代碼提示了一個(gè)在Order Details表中的觸發(fā)器,這個(gè)觸發(fā)器是為了檢測(cè)Quantity和UnitPrice二個(gè)字段是否被修改過(guò)。 CREATE TRIGGER tr_OrderDetails ON [Order Details] AFTER UPDATE
AS
IF (COLUMNS_UPDATED() = 12)
BEGIN
RAISERROR (''''Cannot change both UnitPrice and Quantity at the
same time'''', 16, 1)
ROLLBACK TRAN
END
GO

如果這個(gè)字段都被修改了,就會(huì)產(chǎn)生一個(gè)錯(cuò)誤,同時(shí)事務(wù)也將回滾。就拿Order Details表來(lái)說(shuō),COLUMN_UPDATED功能返回代表Order Details表中字段的五個(gè)字節(jié)。只要第三和第四個(gè)字段被修改,上面這種情況就會(huì)發(fā)生,它檢測(cè)這些位是不是已賦值為1.當(dāng)?shù)谌偷谒奈欢即蜷_(kāi)的慶,它就如:00110。L因這個(gè)位掩碼代表2次冪,第一位表示1,第二位表示2,第三位表示4,第四位表示8,第五位表示16(是的,這是和正常二進(jìn)制數(shù)相反的順序);因此只表示UnitPrice和Quantity字段被修改位掩碼的值為00110,這個(gè)值為12(4+8)。請(qǐng)注意,這個(gè)觸發(fā)器只有在UnitPrice和Quantity字段被修改才會(huì)將事務(wù)回滾。如果其他字段修改的話,位掩碼就會(huì)不一樣,因此就不等于整數(shù)12了。如果觸發(fā)器被修改為禁止對(duì)這二個(gè)字段修改即使對(duì)其他字段也禁止,它就可重新編寫為如下: ALTER TRIGGER tr_OrderDetails ON [Order Details] AFTER UPDATE
AS
IF (COLUMNS_UPDATED() >= 12)
BEGIN
RAISERROR (''''Cannot change both UnitPrice and Quantity
at the same time'''', 16, 1)
ROLLBACK TRAN
END
GO

請(qǐng)注意 COLUMN_UPDATED 功能現(xiàn)在是怎么去檢測(cè)位掩碼的但是否小于等于12.如果你修改聯(lián)系UnitPrice,Quantity和Discount列的話,位掩碼就變?yōu)?0111,代表整數(shù)28(4+8+16)。當(dāng)在一個(gè)表中不止有8個(gè)列時(shí),這個(gè)函數(shù)就會(huì)先返回包含了前八列的五個(gè)字節(jié),而第從第九到第十六就會(huì)在第二個(gè)字節(jié)中,以此類推。這個(gè)功能在決定允許哪些列可以被更新比只對(duì)第列進(jìn)行更新的UPDATE功能更有用。
如前期所描述的一樣,在潢足特定條件規(guī)則條件下,觸發(fā)器可以回滾事務(wù),當(dāng)一個(gè)含有回滾的觸發(fā)器在SQL腳本中執(zhí)行時(shí),整個(gè)處理將被取消。因此,被觸發(fā)動(dòng)作修改的的所有數(shù)據(jù)將由ROLLBACK TRANSACION語(yǔ)句回滾。雖然一個(gè)回滾并不阻止觸發(fā)執(zhí)行SQL語(yǔ)句所有在ROLLBACK TRANSACION語(yǔ)句后面的語(yǔ)句都會(huì)被執(zhí)行 。特別是當(dāng)一個(gè)觸發(fā)器繼續(xù)執(zhí)行回滾語(yǔ)句后面的語(yǔ)句時(shí),在回滾以后所作的任何修改都不會(huì)回滾。發(fā)生這種情況是因?yàn)楫?dāng)在觸發(fā)器中執(zhí)行了一個(gè)ROLLBACK TRANSACTION時(shí),所以有的事務(wù)都被取消。因此當(dāng)一個(gè)新的查詢語(yǔ)句被執(zhí)行時(shí),一個(gè)新的不同與以前事務(wù)的事務(wù)就重新開(kāi)始。因此,一般情況下,建議不要在ROLLBACK TRANSACTION語(yǔ)句后放置任何語(yǔ)句。
像回滾不會(huì)自動(dòng)退出觸發(fā)器一樣,它也不會(huì)自動(dòng)產(chǎn)生錯(cuò)誤。如果必須回滾且必會(huì)產(chǎn)生錯(cuò)誤,PAISERR OR語(yǔ)句應(yīng)該放在退出觸發(fā)器代碼前,緊跟在回滾后.

結(jié)束語(yǔ)
在對(duì)同一個(gè)表的數(shù)據(jù)所作的修改會(huì)激發(fā)同樣的INSTEAD OF觸發(fā)器,這種觸發(fā)器不會(huì)遞歸調(diào)用。因此,如果在Emplyee表中有一個(gè)INSTEAD OF觸發(fā)器,P這個(gè)觸發(fā)器是用來(lái)更新Employee表的,這并不會(huì)發(fā)生調(diào)用同一個(gè)INSTEAD OF觸發(fā)器。如果允許這種遞旭的話,更新應(yīng)該被禁止。INSTEAD OF觸發(fā)器和AFTER觸發(fā)器的另一個(gè)不同在于Text,Ntext和Image列可以出現(xiàn)在被更新和刪除的表的觸發(fā)器中。這些二進(jìn)制列會(huì)以如VARCAHAR數(shù)值出現(xiàn)在更新和刪除表的觸發(fā)器中,這種是可行的,但這并不是他們?cè)嫉臄?shù)據(jù)類型。
這有一個(gè)有用的存儲(chǔ)過(guò)程-sp_helptrigger 系統(tǒng)存儲(chǔ)過(guò)程-來(lái)檢測(cè)觸發(fā)器。他返回定義在表上的觸發(fā)器類型,這個(gè)表是傳遞給存儲(chǔ)過(guò)程的。用這種方法,你可以看到哪些觸發(fā)器和某個(gè)表有關(guān)聯(lián),什么操作動(dòng)觸發(fā)這些觸發(fā)器和判斷觸發(fā)器是AFTER觸發(fā)器還是INSTEAD OF觸發(fā)器。
在最后二欄中,我已經(jīng)討論了AFTER觸發(fā)器和INSTEAD OF觸發(fā)器的多個(gè)方面。當(dāng)然,還有許多情形下他們很有用,還有許多使用時(shí)機(jī)也沒(méi)有提出來(lái)。當(dāng)一個(gè)觸發(fā)器必須查詢其他表的情況下,觸發(fā)器就會(huì)沒(méi)有什么效率了。在這些情況下,觸發(fā)器的性能和觸發(fā)動(dòng)作會(huì)受到很大損害。當(dāng)使用得好時(shí),觸發(fā)器是一個(gè)很棒的工具,但是必須保證在使用他們之前必須對(duì)你的程序作一個(gè)全面的測(cè)試。


import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;


public class DoDate
{

//當(dāng)前月份的第一天

public static String firstDay()
{
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd");
GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
gc.setTime(new Date());
gc.set(Calendar.DAY_OF_MONTH, 1);
String day_first = df.format(gc.getTime())+" 00:00:00";
return day_first;
}
//當(dāng)前月份的最后一天

public static String lastDay()
{
Calendar cal=Calendar.getInstance();
cal.add( cal.MONTH,1 );
cal.set(cal.DATE,1);
cal.add(cal.DATE,-1);
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd");
String day_end=df.format(cal.getTime())+" 23:59:59";
return day_end;
}
//距離當(dāng)前月份N個(gè)月的第一天

public static String firstDay(int n)
{
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd");
GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
gc.setTime(new Date());
gc.set(Calendar.MONTH, gc.get(Calendar.MONTH)+n);
gc.set(Calendar.DAY_OF_MONTH, 1);
String day_first = df.format(gc.getTime())+" 00:00:00";
return day_first;
}
//距離當(dāng)前月份N個(gè)月的最后一天

public static String lastDay(int n)
{
Calendar cal=Calendar.getInstance();
cal.add(cal.MONTH,1);
cal.set(cal.MONTH, cal.get(Calendar.MONTH)+n);
cal.set(cal.DATE,1);
cal.add(cal.DATE,-1);
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd");
String day_end=df.format(cal.getTime())+" 23:59:59";
return day_end;
}
}
