DTS包在何處運行?
為什么DTS包成了作業(yè)以后就不能正確運行了呢?我們從企業(yè)管理器中運行的時候一切正常,但我們把它當(dāng)成一個作業(yè)的時候就不行了。因為它運行不同的環(huán)境里,這個環(huán)境指的是security context,安全環(huán)境或安全上下文。作為程序員你可以在一臺工作站前運行程序,那DTS所處的環(huán)境就是你面前機器的環(huán)境,但如果作為作業(yè),它始終運行在服務(wù)器上。
作為程序員,你可以希望從一個文本文件中導(dǎo)入數(shù)據(jù),但是DTS中指定的文件必須也存在于服務(wù)器上,而且必須有足夠的權(quán)限支持對這個文件的操作。
那到底是誰運行了DTS包呢?是一個稱為SQL Agent的服務(wù),這個作業(yè)有一個擁有者,這個擁有者可以是一個SQL SERVER登錄也可以是一個NT帳戶。可以通過企業(yè)管理器來直接查看所有者是誰,也可以通過運行msdb.dbo.sp_help_job來獲知誰是擁有者。
對于SQL Server 7.0來說,安全上下文是由作業(yè)的所有者決定的。如果所有者是一個不必于Sysadmin角色的用戶,包就在SQLAgentCmdExec帳戶下運行,當(dāng)然使用的安全上下文也就是這個帳戶的,因此這個帳戶必須擁有足夠的權(quán)限才能夠運行指定的操作。通常而言,SQLAgentCmdExec帳戶不擁有對服務(wù)器以外計算機的權(quán)限,因此對別的機器上文件的訪問當(dāng)然就要失敗了。
對于SQL Server 2000來說,安全上下文也是作業(yè)的擁有者決定。如果所有者是一個不必于Sysadmin角色的用戶,包就在SQL Agent Proxy帳戶下運行,也使用此用戶的權(quán)限。對于SQL Agent Proxy來說,它可以運行與數(shù)據(jù)庫相連的操作,當(dāng)然它也必須擁有相應(yīng)的數(shù)據(jù)庫和NT權(quán)限。對于執(zhí)行DTS包來說,SQL Agent Proxy Account必須擁有對帳戶運行臨時目錄的讀寫權(quán)限,這也目錄是:c:\Documents and Settings\<Account>\Local Settings\Temp
如果作業(yè)是被Sysadmin數(shù)據(jù)庫角色的成員擁有,作業(yè)即在啟動SQL Agent服務(wù)的帳戶下運行。同時,如果作用被NT域用戶擁有,而且包被存儲于數(shù)據(jù)庫,你必須使用在同一域或信任域的用戶啟動SQL Server服務(wù)。例如,如果SQL Agent作業(yè)由USA域用戶所有,那啟動SQL Server服務(wù)的用戶必須是來自USA域或USA域的信任域。如果SQL Server由本地帳戶啟動,包的執(zhí)行將失敗。如果調(diào)度一個DTS包,此時它的擁有者將是誰?此時的擁有者要看登錄企業(yè)管理器時誰進(jìn)行了登錄,如果數(shù)據(jù)庫使用NT認(rèn)證,作業(yè)的主將是啟動SQL Agent服務(wù)的NT帳戶;如果登錄企業(yè)管理器的時候使用SQL Server認(rèn)證(如利用SA登錄),那主將是這個SQL SERVER用戶。如果希望改變包的擁有者,可以在企業(yè)管理中實現(xiàn),直接右鍵一擊,在”通用“下面就是了。而在查詢分析器中則要使用msdb.dbo.sp_update_job來進(jìn)行。
DTS如果通過DTSRUN.exe運行,那安全上下文就是此時登錄計算機的用戶。如果通過xp_cmdshell運行如果DTSRUN.exe,如果此用戶是Sysadmin角色中的用戶,他啟動了SQL Server服務(wù),他就是安全上下文。如果是這個用戶不是Sysadmin角色中的用戶,則DTSRun.exe在SQLAgentCmdExec帳戶中運行。如果SQL SERVER以本地帳戶啟動,DTS包不擁有訪問其它機器資源的權(quán)限。
如果SQL Server服務(wù)在NT帳戶下啟動,它的權(quán)限和NT帳戶的權(quán)限一致。如果此帳戶是一個本地帳戶,DTS包不擁有對其它機器的權(quán)限;如果此帳戶是一個域用戶,包可以訪問域內(nèi)其它計算機的資源。有時在DTS包中我們使用一個NT認(rèn)證連接,此連接的安全上下文與包運行的安全上下文一致。如果在命令行上運行DTSRun.exe,此進(jìn)行獲得的安全證書是當(dāng)前NT登錄用戶的證書。如果包以一個作業(yè)運行,此連接的安全上下文將是啟動SQL Agent的帳戶,我們假設(shè)包的擁有者是Sysadmin的成員。
我們映射驅(qū)動器時包運行會出錯,因為映射的驅(qū)動器不是物理存在的,而SQL Agent是一個NT服務(wù),NT服務(wù)是無法看到映射驅(qū)動器的。映射是用戶腳本的一部分,服務(wù)不會調(diào)用用戶腳本的內(nèi)容,請使用UNC路徑來解決其它機器上資源的調(diào)用。相對路徑也最好不要使用,因為DTS包的運行將由調(diào)試機轉(zhuǎn)移到服務(wù)器,因此相對路徑不好用。至于COM組件的使用,一定要確定服務(wù)器上也有相應(yīng)的COM組件。雖然包本身也有一些密碼要提供,如包擁有者的密碼和用戶密碼,這些東西和運行環(huán)境沒有關(guān)系。SQLAgentCmdExec的權(quán)限如果不足以運行包,會產(chǎn)生下面的錯誤信息:
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足夠的登錄權(quán)利和數(shù)據(jù)庫權(quán)限。