2008-10-23 32 views
2

我正在考慮即時創建存儲過程。即時創建存儲過程。有什麼風險/問題?

即運行CREATE PROCEDURE ...當(web)應用程序正在運行時。

它可能導致什麼風險或問題?

  • 我知道數據庫帳戶需要額外的權限。
  • 它不會每天都發生。只是不時。
  • 我使用的是sql server,對mysql和postgres也很感興趣。

UPDATE1:

感謝您的意見,我正在考慮創建存儲過程的新版本和切換,而不是改變SP。例如:SP1 - > SP2 - > SP3

UPDATE2:

的原因:由於自定義字段的

我的架構更改(未知數和列型) 我試圖動態SQL和sp_executesql的第一。當然,它的作品。動態sql的工作原理爲1,2,3簡單更新,插入。

但它太難看了,很多工作,它不能很好地與存儲過程混合,因爲在存儲過程中使用sql參數化的問題,並且編譯時不知道參數的數量和類型(很長的故事)。

至少這個解決方案的基本情況並不複雜。 sp的邏輯不會改變。對於每個自定義字段,我必須爲sp添加一個新參數並添加一列以更新,插入等。

我還考慮過使存儲過程參數動態化,如接受任何數量和類型的參數但無法找到的sp_executesql一種方式。

+0

如果你不介意我問,你能詳細說明一些你考慮這個選項的「很好的理由」嗎? – ninesided 2008-10-23 07:25:24

+0

由於自定義字段,模式正在更改。我可以去動態SQL,但缺點是性能問題,並使其他事情變得困難。動態sql在簡單的情況下運行良好,但對於一些複雜的存儲過程並不適用。有很多細節... – user30683 2008-10-23 07:33:50

回答

0

首先,這個問題的答案實際上取決於這個存儲過程的目的是做什麼。如果只是讀取數據或創建報告結果集,並且不介意是否有點不一致,那麼您可能沒有問題。如果它對你的數據做了任何有趣的事情,那麼這是一件非常冒險的事情。您應該考慮兩個用戶用戶(或同一個用戶兩次)是否有可能(以及會發生什麼情況)同時運行同一存儲過程的多個版本。聞起來像一列火車撞向我。一種選擇是隻允許在沒有其他用戶登錄到系統時進行此過程更改,或者如果這些更改是強制將其從數據庫引導的話。另一種選擇是創建名稱略有不同的新存儲過程,並在您認爲安全的情況下將它們交換。

+0

邏輯不會改變。只有列被添加到更新,插入。 簡單地說,使用新的sp代替動態sql。 我不知道是否可以同時運行sp的兩個版本,但如果發生它不會是一個問題。它就像運行動態sql(具有不同列)的變體 – user30683 2008-10-23 07:43:35

0

另一個問題是存儲過程的一個主要優點是執行計劃被緩存,這意味着它的執行速度會更快。如果您在飛行中創建它們,則會失去該優勢。

+0

我提到它不是每天發生。只有一次在 – user30683 2008-10-23 08:30:22

0

如果您確實需要這樣做,那麼您應該隨機輸入程序的名稱以避免與其他用戶衝突。請記住,其他用戶可能會同時做自己的事情 - 大多數數據庫系統不會爲存儲過程提供事務隔離(Postgres是我所知的唯一一個)。

這將是非常罕見的,這將是一個理想的事情要做 - 你能詳細說明是什麼讓你選擇這種方法?

0

我不會那樣做。

如上所述,您將需要額外的權限來授予對創建/更改數據庫對象的訪問權限。這可能會造成嚴重的安全風險,因爲如果有人在其中發現安全漏洞,則無法阻止應用程序創建惡意存儲過程。

如果您的模式更改,請使用模式更改存儲過程。

0

如果一個或多個用戶正在運行該過程或引用您的過程的其他過程,您將無法更改過程。你會阻止,直到所有的依賴程序和你想編譯的程序(我認爲你從程序中調用的程序,但我不確定)沒有被使用。在繁忙的生產系統上這可能會很長時間,如果您不幸運,您可能會超時等待所有依賴項不被使用(Oracle上爲5分鐘)。
你也可以進入非常醜陋的情況(我有)。以存儲過程B和C爲例,它們都調用A,您正試圖編譯的過程。當沒有人運行B時,系統鎖定B.現在任何試圖運行B的用戶都將停止運行。然後系統嘗試鎖定C,但是C正在生成一個非常冗長的報告,而這個報告不會再持續10分鐘。您將超時等待鎖定,並且您的某些用戶在5分鐘內會出現無響應的系統。我的經驗是與甲骨文,我會確保你的目標數據庫管理系統不以相同的方式行事,或有更快的失敗或更好的鎖定獲取策略。
我想我警告說,在繁忙的生產系統上看起來像在開發服務器上工作可能會失敗。

0

我不知道該由託尼BanBrahim討論的鎖定是SQL Server 2005確實

我有一些長時間運行的SP(約30分過程的3小時批量處理),和我已經能夠在SP仍在運行的時候改變它。 (我不相信這些更改會在下一次運行之前生效,但它不會導致任何阻塞或任何錯誤)。現在,外部長時間運行的SP既用EXEC動態地調用SP,又靜態地調用SP,但在運行時沒有錯誤消息或塊,我更改了根和嵌套SP。

WRT你原來的問題,我認爲你的策略是好的,如果以可控的方式使用。

1

您提到您將在添加和/或更改存儲過程的調用配置文件時進行此更改。你如何鎖定新的呼叫配置文件與調用此應用程序?如果您需要恢復所做的更改,那麼您的回滾計劃是什麼?

過去我所做的只是在新的調用配置文件中爲存儲過程名添加遞增的數字後綴 - 然後您可以修改SP的舊版本以調用具有默認值的新版本爲參數,然後您可以釋放您的軟件調用新版本。

如果新版本中出現問題並且需要回滾,調用舊的存儲過程仍然可以正常工作,只需使用默認值填充自定義字段即可。

0

我不知道是肯定的,但它聽起來像是一個或兩個:

  • 一個結構問題
  • 是現有的代碼鎖定從應用架構表?

我想看看哪些代碼鎖定模式表並重寫該代碼。你有第三方的東西或其他鎖定這些表的東西嗎?