2009-01-28 100 views
4

我們有一個在SQL 2005上運行的數據庫。其中一個存儲過程使用鏈接服務器從Active Directory查找用戶的電子郵件地址。對鏈接服務器的調用發生在數據庫函數中。SQL 2005鏈接服務器查詢定期失敗

我能叫成功是從我的Asp.Net應用程序中的第一次,但在此之後定期時,出現以下錯誤:

{「請求的操作不能因爲OLE DB進行提供程序\「ADsDSOObject \」對於鏈接服務器\「ADSI \」不支持所需的交易接口。「}

看起來,調用函數之間的時間量會影響鏈接服務器查詢是否正常工作。我沒有使用任何交易。當我嘗試在快速轉換SQL腳本中調用函數時,它每次都運行正常(即使在快速連續測試時也是如此)。

如果我不嘗試再次調用該過程,是否有某種事務會自然死亡?我在這裏不知所措。

這裏是存儲過程的簡單調用:

DECLARE @email varchar(50) 


SELECT @email = LEFT(mail, 50) 
FROM OPENQUERY (
    ADSI, 
    'SELECT mail, sAMAccountName FROM ''LDAP://DC=Katz,DC=COM'' WHERE objectCategory = ''Person'' AND objectClass = ''User''' 
) 
WHERE sAMAccountName = CAST(@LoginName AS varchar(35)) 

RETURN @email 

回答

3

我與SQL Server linkservers經常工作,雖然很少LDAP查詢......但我得到了好奇並閱讀Ric Tokyo上一篇文章中鏈接的微軟支持頁面。向底部記載:

It is typical for a directory server to enforce a server limitation on the number of objects that will be returned for a given query. This is to prevent denial-of-service attacks and network overloading. To properly query the directory server, large queries should be broken up into many smaller ones. One way to do this is through a process called paging. While paging is available through ADSI's OLEDB provider, there is currently no way available to perform it from a SQL distributed query. This means that the total number of objects that can be returned for a query is the server limit. In the Windows 2000 Active Directory, the default server limit is 1,000 objects.

我想它,你(或沒有),取決於是否從應用程序或從「快速化妝移SQL腳本」調用它失敗(因爲你的原因把它)可能與操作正在執行的安全上下文有關。根據鏈接服務器連接的設置方式,可能會根據您啓動查詢的方式,在各種可能的憑據下執行該操作。

我不知道,但這是我最好的猜測。我會看看linkserver配置,特別是關於什麼樣的證書集被用作安全上下文的鏈接服務器設置,在這個安全上下文下運行linkserver。

+0

我的LDAP查詢一次只返回1個對象,所以我不認爲返回對象的數量是一個問題。 我可以看看安全上下文,但我有點懷疑,因爲有時它有效,有時它不。但整個過程中,安全環境保持不變。 – anschoewe 2009-01-28 02:56:19

2

然後,通過鏈接服務器查詢Active Directory,最好將AD數據緩存到SQL數據庫中,然後查詢。

SELECT physicalDeliveryOfficeName, department, company, title, displayName, SN, 
    givenName, sAMAccountName, manager, mail, telephoneNumber, mobile 
    FROM 'LDAP://DC=SOMECO,DC=COM' 
    WHERE objectClass='User' and objectCategory = 'Person' 
    order by mail 

使用這種方法,你仍然會運行到1000行限制:您可以通過創建使用「OLE DB提供程序的Microsoft目錄服務」一個OLE DB連接,並與像查詢一個DataReader源使用集成服務對於來自AD查詢的結果(注意不建議嘗試在AD中增加此限制,這是爲了防止域控制器過載)。有時可能使用查詢組合返回完整的數據集,例如名稱A - L和M - Z

或者,您可以使用Windows Server中的CSVDE命令行實用程序將目錄信息導出到CSV文件,然後將其導入到SQL數據庫中(有關導出AD的更多信息,請參見http://computerperformance.co.uk/Logon/Logon_CSVDE_Export.htm數據與CSVDE)。

1

我懷疑它可能是緩存的查詢計劃,因爲您的聲明是「當我嘗試在快速轉換SQL腳本中調用函數時,它每次都運行良好(即使在快速連續測試時)。「

你能嘗試執行存儲過程像這樣:

EXEC usp_MyProcedure WITH RECOMPILE 
0

這個問題出現在第一谷歌頁面的頂部時尋找錯誤字符串,但還沒有有效的答案

這錯誤發生intermitently當.NET代碼也不在存儲過程未指定的隔離級別。

此錯誤也發生在SQL Server 2008中

此修復程序強制爲SET TRANSACTION ISOLATION LEVEL READ (UN)COMMITTED,因爲Active Directory不支持隔離級別更高且SQL Server嘗試使用SERIALIZABLE

現在,這個錯誤是錯誤的。爲什麼ADO.NET或SQLServer有時會將其默認隔離切換爲SERIALIZABLE,有時甚至不會?什麼觸發了這種轉換?