DTS包在何處運行?
為什么DTS包成了作業以后就不能正確運行了呢?我們從企業管理器中運行的時候一切正常,但我們把它當成一個作業的時候就不行了。因為它運行不同的環境里,這個環境指的是security context,安全環境或安全上下文。作為程序員你可以在一臺工作站前運行程序,那DTS所處的環境就是你面前機器的環境,但如果作為作業,它始終運行在服務器上。
作為程序員,你可以希望從一個文本文件中導入數據,但是DTS中指定的文件必須也存在于服務器上,而且必須有足夠的權限支持對這個文件的操作。
那到底是誰運行了DTS包呢?是一個稱為SQL Agent的服務,這個作業有一個擁有者,這個擁有者可以是一個SQL SERVER登錄也可以是一個NT帳戶。可以通過企業管理器來直接查看所有者是誰,也可以通過運行msdb.dbo.sp_help_job來獲知誰是擁有者。
對于SQL Server 7.0來說,安全上下文是由作業的所有者決定的。如果所有者是一個不必于Sysadmin角色的用戶,包就在SQLAgentCmdExec帳戶下運行,當然使用的安全上下文也就是這個帳戶的,因此這個帳戶必須擁有足夠的權限才能夠運行指定的操作。通常而言,SQLAgentCmdExec帳戶不擁有對服務器以外計算機的權限,因此對別的機器上文件的訪問當然就要失敗了。
對于SQL Server 2000來說,安全上下文也是作業的擁有者決定。如果所有者是一個不必于Sysadmin角色的用戶,包就在SQL Agent Proxy帳戶下運行,也使用此用戶的權限。對于SQL Agent Proxy來說,它可以運行與數據庫相連的操作,當然它也必須擁有相應的數據庫和NT權限。對于執行DTS包來說,SQL Agent Proxy Account必須擁有對帳戶運行臨時目錄的讀寫權限,這也目錄是:c:\Documents and Settings\<Account>\Local Settings\Temp
如果作業是被Sysadmin數據庫角色的成員擁有,作業即在啟動SQL Agent服務的帳戶下運行。同時,如果作用被NT域用戶擁有,而且包被存儲于數據庫,你必須使用在同一域或信任域的用戶啟動SQL Server服務。例如,如果SQL Agent作業由USA域用戶所有,那啟動SQL Server服務的用戶必須是來自USA域或USA域的信任域。如果SQL Server由本地帳戶啟動,包的執行將失敗。如果調度一個DTS包,此時它的擁有者將是誰?此時的擁有者要看登錄企業管理器時誰進行了登錄,如果數據庫使用NT認證,作業的主將是啟動SQL Agent服務的NT帳戶;如果登錄企業管理器的時候使用SQL Server認證(如利用SA登錄),那主將是這個SQL SERVER用戶。如果希望改變包的擁有者,可以在企業管理中實現,直接右鍵一擊,在”通用“下面就是了。而在查詢分析器中則要使用msdb.dbo.sp_update_job來進行。
DTS如果通過DTSRUN.exe運行,那安全上下文就是此時登錄計算機的用戶。如果通過xp_cmdshell運行如果DTSRUN.exe,如果此用戶是Sysadmin角色中的用戶,他啟動了SQL Server服務,他就是安全上下文。如果是這個用戶不是Sysadmin角色中的用戶,則DTSRun.exe在SQLAgentCmdExec帳戶中運行。如果SQL SERVER以本地帳戶啟動,DTS包不擁有訪問其它機器資源的權限。
如果SQL Server服務在NT帳戶下啟動,它的權限和NT帳戶的權限一致。如果此帳戶是一個本地帳戶,DTS包不擁有對其它機器的權限;如果此帳戶是一個域用戶,包可以訪問域內其它計算機的資源。有時在DTS包中我們使用一個NT認證連接,此連接的安全上下文與包運行的安全上下文一致。如果在命令行上運行DTSRun.exe,此進行獲得的安全證書是當前NT登錄用戶的證書。如果包以一個作業運行,此連接的安全上下文將是啟動SQL Agent的帳戶,我們假設包的擁有者是Sysadmin的成員。
我們映射驅動器時包運行會出錯,因為映射的驅動器不是物理存在的,而SQL Agent是一個NT服務,NT服務是無法看到映射驅動器的。映射是用戶腳本的一部分,服務不會調用用戶腳本的內容,請使用UNC路徑來解決其它機器上資源的調用。相對路徑也最好不要使用,因為DTS包的運行將由調試機轉移到服務器,因此相對路徑不好用。至于COM組件的使用,一定要確定服務器上也有相應的COM組件。雖然包本身也有一些密碼要提供,如包擁有者的密碼和用戶密碼,這些東西和運行環境沒有關系。SQLAgentCmdExec的權限如果不足以運行包,會產生下面的錯誤信息:
DTSRun: Loading... DTSRun: Executing... DTSRun OnStart: DTSStep_DTSExecuteSQLTask_1 DTSRun OnError: DTSStep_DTSExecuteSQLTask_1, Error = -2147217843 (80040E4D) Error string: Login failed for user 'NT_name\SQLAgentCmdExec'. Error source: Microsoft OLE DB Provider for SQL Server Help file: Help context: 0 Error Detail Records: Error: -2147217843 (80040E4D); Provider Error: 18456 (4818) Error string: Login failed for user 'NT_name\SQLAgentCmdExec'. Error source: Microsoft OLE DB Provider for SQL Server Help file: Help context: 0 DTSRun OnFinish: DTSStep_DTSExecuteSQLTask_1 DTSRun: Package execution complete. Process Exit Code 1. The step failed.
你必須給SQLAgentCmdExec足夠的登錄權利和數據庫權限。