Sql server 检查SQL Server 2005存储过程中是否存在文件的最佳方法是什么?

Sql server 检查SQL Server 2005存储过程中是否存在文件的最佳方法是什么?,sql-server,sql-server-2005,Sql Server,Sql Server 2005,我们在SQLServer2000中使用了“未记录”的xp_fileexist存储过程多年,没有遇到任何问题。在2005年,他们似乎稍微修改了行为,如果执行的用户帐户不是sysadmin,则总是返回0。如果SQL Server服务在LocalSystem帐户下运行,并且您试图检查网络上的文件,那么它似乎也会返回零 我想远离xp_文件存在。是否有人有更好的方法从存储过程内部检查网络位置是否存在文件?也许您正在寻找的是CLR存储过程。当您需要以某种方式与系统进行交互时,通常会使用这些方法。您必须将CL

我们在SQLServer2000中使用了“未记录”的xp_fileexist存储过程多年,没有遇到任何问题。在2005年,他们似乎稍微修改了行为,如果执行的用户帐户不是sysadmin,则总是返回0。如果SQL Server服务在LocalSystem帐户下运行,并且您试图检查网络上的文件,那么它似乎也会返回零


我想远离xp_文件存在。是否有人有更好的方法从存储过程内部检查网络位置是否存在文件?

也许您正在寻找的是CLR存储过程。当您需要以某种方式与系统进行交互时,通常会使用这些方法。

您必须将CLR标记为外部访问,以便访问system.IO命名空间,但随着时间的推移,这并不是一种不好的方法

SAFE是默认的权限集,但限制性很强。使用安全设置,您只能访问本地数据库中的数据,以对该数据执行计算逻辑。 外部访问是权限层次结构中的下一步。此设置允许您访问外部资源,如文件系统、Windows事件查看器和Web服务。这种类型的资源访问在SQL Server 2000及更早版本中是不可能的。此权限集还限制影响程序集健壮性的操作,如指针访问。 不安全权限集假定程序集完全信任,因此不施加“代码访问安全性”限制。此设置类似于您假定所有代码都是安全的扩展存储过程的工作方式。但是,此设置将不安全程序集的创建限制为具有sysadmin权限的用户。Microsoft建议您尽可能避免创建不安全的程序集


我仍然相信CLR程序可能是最好的选择。所以,我接受这个答案。然而,要么我不是那么聪明,要么实施起来非常困难。我们的SQL Server服务在本地帐户下运行,因为根据Mircosoft的说法,这是从64位SQL Server 2005实例获得iSeries链接服务器的唯一方法。当我们将SQL Server服务更改为使用域帐户运行时,xp_fileexist命令对位于网络上的文件运行良好

我创建了此CLR存储过程,并在将权限级别设置为External的情况下构建了它,并对其进行了签名:

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();
            }
        }
    }
}
然后我运行了以下TSQL命令:

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;
然后,我从Visual Studio将CLR存储过程部署到目标数据库,并使用此TSQL从使用windows身份验证登录的SSM执行:

DECLARE @i INT
--EXEC FileExists '\\\\server\\share\\folder\\file.dat', @i OUT
EXEC FileExists 'j:\\file.dat', @i OUT
SELECT @i
无论我尝试本地文件还是网络文件,我总是得到一个0。我可能稍后再试,但现在,我将尝试走另一条路。如果有人有一些线索,我们将不胜感激