Was ist die beste Methode, um zu überprüfen, ob eine file aus einer gespeicherten SQL server 2005-Prozedur existiert?

Wir haben die "undokumentierte" xp_fileexist gespeicherte Prozedur seit Jahren in SQL server 2000 und hatte keine Probleme mit ihm. Im Jahr 2005 scheint es, dass sie das Verhalten leicht geändert haben, um immer eine 0 zurückzugeben, wenn das ausführende Benutzerkonto kein Sysadmin ist. Es scheint auch eine Null zurückzugeben, wenn der SQL server-Dienst unter dem LocalSystem-Konto ausgeführt wird und Sie versuchen, eine file im Netzwerk zu überprüfen.

Ich würde gerne weg von xp_fileexist. Hat jemand einen besseren path, um die Existenz einer file an einem Netzwerk-Ort aus dem Inneren einer gespeicherten Prozedur zu überprüfen?

Vielleicht ist eine CLR gespeicherte Prozedur, was Sie suchen. Diese werden in der Regel verwendet, wenn Sie mit dem System in irgendeiner Weise interagieren müssen.

Sie müssen die CLR als EXTERNAL_ACCESS markieren, um Zugriff auf den System.IO-Namespace zu erhalten, aber wie es geht, ist das nicht ein schlechter path, um darüber zu gehen.

SAFE ist die Standard-Berechtigungsmenge, aber es ist sehr restriktiv. Mit der SAFE-Einstellung können Sie nur data aus einer lokalen database zugreifen, um eine Rechenlogik für diese data auszuführen. EXTERNAL_ACCESS ist der nächste Schritt in der Berechtigungshierarchie. Mit dieser Einstellung können Sie auf externe Ressourcen wie das filesystem, die Windows-Ereignisanzeige und die Webdienste zugreifen. Diese Art von Ressourcenzugriff ist in SQL server 2000 und früher nicht möglich. Diese Berechtigungsmenge beschränkt auch Operationen wie pointerszugriff, die die Robustheit Ihrer Assembly beeinflussen. Der UNSAFE-Berechtigungssatz übernimmt das volle Vertrauen der Versammlung und stellt somit keine Einschränkungen für "Code Access Security" dar. Diese Einstellung ist vergleichbar mit der Art und Weise erweiterte gespeicherte Prozeduren function – Sie übernehmen alle Code ist sicher. Diese Einstellung beschränkt jedoch die Erstellung von unsicheren Assemblies für Benutzer mit sysadmin-permissions. Microsoft empfiehlt, dass Sie vermeiden, unsichere Assemblies so weit wie möglich zu erstellen.

Ich glaube immer noch, dass ein CLR-Verfahren die beste Wette sein könnte. Also, ich akzeptiere diese Antwort. Allerdings bin ich auch nicht so hell oder es ist extrem schwierig zu implementieren. Unser SQL server-Dienst wird unter einem lokalen Konto ausgeführt, da laut Mircosoft der einzige path ist, einen iSeries-verknüpften server zu erhalten, der von einer 64-Bit-SQL server 2005-Instanz arbeitet. Wenn wir den SQL server-Dienst ändern, um mit einem Domänenkonto zu laufen, funktioniert der Befehl xp_fileexist für fileen, die sich im Netzwerk befinden.

Ich habe diese CLR gespeicherte Prozedur erstellt und gebaut mit der Berechtigungsstufe auf External gesetzt und unterschrieben:

using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.Sqlserver.server; using System.Security.Principal; public partial class StoredProcedures { [Microsoft.Sqlserver.server.SqlProcedure] public static void FileExists(SqlString fileName, out SqlInt32 returnValue) { WindowsImpersonationContext originalContext = null; try { WindowsIdentity callerIdentity = SqlContext.WindowsIdentity; originalContext = callerIdentity.Impersonate(); if (System.IO.File.Exists(Convert.ToString(fileName))) { returnValue = 1; } else { returnValue = 0; } } catch (Exception) { returnValue = -1; } finally { if (originalContext != null) { originalContext.Undo(); } } } } 

Dann lief ich diese TSQL-Befehle:

 USE master GO CREATE ASYMMETRIC KEY FileUtilitiesKey FROM EXECUTABLE FILE = 'J:\FileUtilities.dll' CREATE LOGIN CLRLogin FROM ASYMMETRIC KEY FileUtilitiesKey GRANT EXTERNAL ACCESS ASSEMBLY TO CLRLogin ALTER DATABASE database SET TRUSTWORTHY ON; 

Dann habe ich CLR gespeichert Proc auf meine Zieldatenbank von Visual Studio und verwendet diese TSQL ausführen von SSMS angemeldet mit Windows-authentication:

 DECLARE @i INT --EXEC FileExists '\\\\server\\share\\folder\\file.dat', @i OUT EXEC FileExists 'j:\\file.dat', @i OUT SELECT @i 

Ob ich eine lokale file oder eine Netzwerkdatei probiere, bekomme ich immer eine 0. Ich kann es später nochmal versuchen, aber für jetzt werde ich versuchen, einen anderen path hinunterzugehen. Wenn jemand etwas Licht zu vergießen hat, wäre es sehr geschätzt.

@Paul, dieser Code sieht aus wie es funktionieren sollte. Hast du versucht, irgendeine Spur in dieser Methode zu setzen, um sicherzustellen, dass Convert.ToString(fileName) irgendwie den Pfad nicht schlägt?