SQL 代理作業位于用戶級別之上,需要將登錄名分配給所有者。但它不會將組登錄作為可接受的引數。我需要使用 Windows AD 組作為所有者,因為我有不同的 SQL 用戶,其中一些應該只看到特定的作業。現在我已經使用 SQLAgentUserRole 為每個用戶創建了單獨的作業,這肯定不好,并且資料庫充滿了 1:1 的作業,每個作業都有不同的所有者,以避免看到其他作業。
整體情況:假設我在資料庫中有 10 個不同的作業。其中一項作業名為 UserJob。我希望在連接到資料庫時使用特定用戶并展開作業部分以僅查看名為“UserJob”的作業并能夠啟動它。我不需要通過存盤程序等。我只需要通過 SSMS 啟動作業(右鍵單擊,啟動作業,如果需要,輸入引數)。謝謝。
uj5u.com熱心網友回復:
根據檔案SSMS 檢查以下資料庫角色中的用戶成員身份以顯示 SQL Server 代理樹節點:
- SQLAgent 用戶角色
- SQLAgentReader角色
- SQLAgentOperator角色
我使用 SQL Server Profiler 來查找當您第一次在物件瀏覽器中連接到資料庫并展開各種節點時執行的查詢。
對于 SQL Server 代理,它使用SELECT * FROM msdb.dbo.sysjobs_view視圖來列出作業。可以修改此視圖。
變化
- 在 msdb 資料庫中創建一個新的資料庫角色。我稱之為“CustomJobRole”。
- 然后我創建了一個名為“TestJob”的新作業(我假設你已經有一個作業)
- 創建一個應該只能看到和運行“TestJob”的低權限用戶。
- 將此用戶添加到“CustomJobRole”和“SQLAgentReaderRole”和/或“SQLAgentOperatorRole”(有關詳細資訊,請參閱上面的鏈接檔案)
- 修改
sysjobs_view如下:
(見代碼注釋)
ALTER VIEW sysjobs_view
AS
SELECT jobs.job_id,
svr.originating_server,
jobs.name,
jobs.enabled,
jobs.description,
jobs.start_step_id,
jobs.category_id,
jobs.owner_sid,
jobs.notify_level_eventlog,
jobs.notify_level_email,
jobs.notify_level_netsend,
jobs.notify_level_page,
jobs.notify_email_operator_id,
jobs.notify_netsend_operator_id,
jobs.notify_page_operator_id,
jobs.delete_level,
jobs.date_created,
jobs.date_modified,
jobs.version_number,
jobs.originating_server_id,
svr.master_server
FROM msdb.dbo.sysjobs as jobs
JOIN msdb.dbo.sysoriginatingservers_view as svr
ON jobs.originating_server_id = svr.originating_server_id
--LEFT JOIN msdb.dbo.sysjobservers js ON jobs.job_id = js.job_id
WHERE
-- Custom: Add Condition for your Custom Role and Job Name
( (ISNULL(IS_MEMBER(N'CustomJobRole'), 0) = 1) AND jobs.name = 'TestJob' )
OR (owner_sid = SUSER_SID())
OR (ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0) = 1)
-- Custom: In order for users to be able to see and start Jobs they have to be members of SQLAgentReaderRole/SQLAgentOperatorRole
-- but these roles gives them ability to see all jobs so add an exclusion
OR ( ISNULL(IS_MEMBER(N'SQLAgentReaderRole'), 0) = 1 AND ISNULL( IS_MEMBER(N'CustomJobRole'), 0 ) = 0 )
OR ( (ISNULL(IS_MEMBER(N'TargetServersRole'), 0) = 1) AND
(EXISTS(SELECT * FROM msdb.dbo.sysjobservers js
WHERE js.server_id <> 0 AND js.job_id = jobs.job_id))) -- filter out local jobs
注:注釋掉的LEFT JOIN是原代碼,與解決方案無關。
概括
這種方法是“hacky”,因為它只修改某些用戶的作業串列,實際上并沒有阻止他們通過代碼運行其他作業,換句話說,這不提供任何安全性,只是為了干凈的 UI 提供便利。實作很簡單,但顯然不可擴展:作業名稱是硬編碼的,并且使用了負面的成員身份(即AND ISNULL( IS_MEMBER(N'CustomJobRole'), 0 ) = 0)。IMO,雖然它是最簡單和最可靠(副作用最少)的方法。
經過測驗
SSMS v18.9.2 SQL Server 2014 SP3
編輯作業步驟解決方法
除非您是作業所有者或系統管理員,否則無法修改作業步驟。一種更“hacky”的解決這個問題的方法是創建一個表,該表將保存所有輸入引數并為用戶提供對該表的插入/更新訪問權限。然后,您的 SP 可以從該表中讀取引數。用戶應該很容易在表上單擊滑鼠右鍵 -> 編輯并修改資料。
對于表結構,我建議如下:
- 假設您的引數相對較少,我建議您為每個引數創建一列。這樣您就可以為每個引數提供正確的資料型別。
- 向表中添加 After Insert/Delete 觸發器,以確保表始終只有一行資料。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/390536.html
標籤:sql-server sql-server-2012 短信 sql代理
下一篇:根據日期列計算開始日期結束日期
