「存儲過程通常用於數據驗證或 封裝組合若干SQL查詢大型,複雜的處理指令。」sql:如何通過存儲過程完成數據驗證?
說這個Oracle reference。那麼有人可以幫助我理解存儲過程如何用於數據驗證?因爲將數據傳遞到存儲過程中,它的經由其被明確設置爲Oracle數據類型(或用戶定義的類型,其也基於Oracle數據類型)參數進行發生
「存儲過程通常用於數據驗證或 封裝組合若干SQL查詢大型,複雜的處理指令。」sql:如何通過存儲過程完成數據驗證?
說這個Oracle reference。那麼有人可以幫助我理解存儲過程如何用於數據驗證?因爲將數據傳遞到存儲過程中,它的經由其被明確設置爲Oracle數據類型(或用戶定義的類型,其也基於Oracle數據類型)參數進行發生
數據驗證。只發生數據類型驗證 - 必要時可以構建更深入的驗證(IE:檢查NUMBER數據類型中的小數)。參數化查詢通常對於SQL注入來說更安全,但它確實取決於參數是什麼以及查詢的內容。
CREATE OR REPLACE PROCEDURE example (IN_VALUE NUMBER) IS
BEGIN
SELECT t.*
FROM TABLE t
WHERE t.column = IN_VALUE;
END;
在這個例子中,提交VARCHAR /字符串將導致錯誤 - 比將導致一個錯誤編號支持其他任何東西。如果IN_VALUE數據類型不能隱式轉換爲TABLE.column的數據類型,你會得到一個錯誤。
存儲過程封裝了一個交易,這是允許複雜的處理指令(意思是,一個以上的SQL查詢)。事務處理(IE:必須明確指定「COMMIT」或「ROLLBACK」)取決於設置。
驗證可能意味着一些東西,可以以各種方式的數據庫中進行:
然而,存在不能由任何上述的強制執行更復雜的驗證規則,例如: - SALARY < = (SELECT max_sal FROM config_table) - emp.start_date BETWEEN start_date和它們被分配到
部門END_DATE有各種各樣的方式執行這些規則,包括數據庫觸發器,但經常優選的方法是創建一個存儲PR流程,通常稱爲「API」以執行驗證和動作,例如
PROCEDURE insert_emp (...) IS
...
BEGIN
-- Validate
-- 1) Salary less than max
SELECT max_sal
INTO l_max_sal
FROM config;
IF p_sal > l_max_sal THEN
error_pkg.raise_error ('Salary is too high');
END IF;
...
-- Insert
INSERT INTO emp (...) VALUES (...);
END;
然後,應用程序可以調用此過程,而不是直接執行更新,並且將執行所有必要的驗證。事實上,應用程序可能會有調用此過程 - 直接插入到表中可能會被禁用。
在一個理想的世界中,您選擇的DBMS將是關係完整的,允許您編寫任意複雜度的約束並支持多個賦值,以便您的數據庫隨時更新(即不需要推遲或禁用約束)聲明。在現實世界中,我們擁有SQL。
理想的SQL的產品將是完整的SQL-92標準兼容:支持CREATE ASSERTION
(架構級約束),允許在CHECK
約束子查詢,並支持事務中的約束的管理延遲,使您的數據庫沒有禁用的約束進行更新。可悲的是,甲骨文還沒有達到這個水平的功能。因此,在現實世界中,我們必須訴諸程序代碼來「管理」更新,同時保持數據的完整性。
例如,考慮一個真實的一對一的關係,是普通不過,隨着業務規則如下:
數據庫包含三個 relvars的 員工和項目的詳細信息:EMP,PROJ和EMP_PROJ。每個 項目必須至少有一個 僱員,每個項目附件 必須參考現有項目。 當創建一個項目時,至少有一個員工必須同時連接 。
在Oracle中,你不能寫一個ASSERTION
或CHECK
執行臺間的限制,所以推遲約束的能力是無關緊要的在這種情況下。
一種方法可以編寫具有適當參數的PROCEDURE
以創建項目並將一個員工分配給項目。這樣的程序將按照以下順序(僞代碼):
1)開始交易;
2)插入PROJ
;
3)插入EMP_PROJ
;
4)測試不符合名義約束條件的數據
EXISTS (
SELECT *
FROM PROJ
WHERE NOT EXISTS (
SELECT *
FROM EMP_PROJ
WHERE EMP_PROJ.project_code = PROJ.project_code
)
);
5)如果測試發現非法數據,則回滾否則提交事務。
如果約束咬那麼事務回滾和數據的完整性一直維持(儘管你也許會想處理更優雅此類驗證失敗:)
類似的程序將需要刪除的員工從項目中防止將最後剩餘分配的員工從項目中移除時的情形(應該防止員工搬遷還是應該刪除項目?請問您的設計師:)
由於數據完整性只能由執行這樣的程序代碼,每個人都可以方便地將它封裝在數據庫中的一個PROCEDURE
對象中n向用戶授予對PROCEDURE
的'執行'權限(而不是授予對基礎表的增強權限)。強制一組用戶(例如,最終用戶應用程序)只能使用PROCEDURE
來更新數據,因此應撤銷其在基礎表上的更新權限。這可能需要進一步的「輔助」功能,例如,將員工分配到項目並刪除項目。如果你購買了「通過存儲特效庫訪問所有數據庫」學派,那麼無論如何你都會這樣做。
+1,即使步驟1和5不屬於存儲過程,但在呼叫環境中,在我看來。 – 2011-04-19 10:44:30
好吧,我當然不是專家,這就是爲什麼我寧願留下評論。是不是真的,你可以在存儲過程中編寫你的業務邏輯作爲你的表的主要訪問點,通過這個你可以在實際持久化之前驗證數據? – 2011-04-18 05:47:34