Sql server 确定SQL Server 2016中存在文件(是/否)

Sql server 确定SQL Server 2016中存在文件(是/否),sql-server,tsql,stored-procedures,Sql Server,Tsql,Stored Procedures,我的客户端刚刚从SQL Server 2000升级到SQL Server 2016。一个每天使用15-20次的存储过程在一个文件名表中运行,并报告每个存储过程是否存在 以前它使用的是xp\u FileExist,但现在似乎需要使用管理员权限。我不能给所有176个用户管理员权限,并保留我的工作 我发现一些文章建议使用grantimpersonate和executeasuser,但无法使其正常工作 -- Old code works only for administrators -- non-ad

我的客户端刚刚从SQL Server 2000升级到SQL Server 2016。一个每天使用15-20次的存储过程在一个文件名表中运行,并报告每个存储过程是否存在

以前它使用的是
xp\u FileExist
,但现在似乎需要使用管理员权限。我不能给所有176个用户管理员权限,并保留我的工作

我发现一些文章建议使用
grantimpersonate
executeasuser
,但无法使其正常工作

-- Old code works only for administrators
-- non-administrators ALWAYS get 0 for result even when file exists

EXEC master.dbo.xp_fileexist @docUNC, @FileExists OUTPUT

-- code run using admin account

SELECT SUSER_NAME() LOGIN_Name, USER_NAME() username;  
结果

LOGIN_Name                   username
--------------------------------------
DomainName\potomcandice      dbo

-- attempted new code for grant impersonate (want to let maronj impersonate potomcandice)

GRANT IMPERSONATE ON USER:: maronj TO potomcandice

-- New code

EXECUTE AS USER='potomcandice' 

EXEC master.dbo.xp_fileexist @docUNC, @FileExists OUTPUT
即使文件确实存在,结果仍然为0

希望得到关于这两个方面的建议 a) 如何使用“授权模拟”和“以用户/登录身份执行”或
b) xp_文件的替代方案不涉及xp_commandshell。

在对象资源管理器中找到您的SP,转到SP属性。在打开的窗口中转到权限 然后单击SP名称下的“搜索”。 点击“浏览”查找对象名称并标记“公共”。单击“确定”。 然后将Grant标记为“Execute”,并尝试是否有效


这应该可以做到

我在一个函数中使用了
xp\u fileexist
,在这个函数中,我发现并遇到了相同的问题,它没有向非管理员返回正确的结果。在我的环境中,解决方案是简单地将
和EXECUTE AS OWNER
添加到函数定义中,如下所示

CREATE OR ALTER FUNCTION dbo.fnFileExists(@Path VARCHAR(8000)) RETURNS BIT WITH EXECUTE AS OWNER AS 

/*  Returns 1 if a file exists at the suppied Path.  Returns 0 if it doesn't.  
    Uses WITH EXECUTE AS OWNER to enable use by non-admins.

    Source: https://www.tech-recipes.com/rx/30527/sql-server-how-to-check-if-a-file-exists-in-a-directory/
*/

BEGIN
     DECLARE @Result INT
     EXEC master.dbo.xp_fileexist @Path, @Result OUTPUT
     RETURN @Result
END

已标记为授予角色“公共”执行权限。用户可以执行存储过程,但不能得到准确的结果。EXEC master.dbo.xp_fileexist'c:\test.txt'返回0(即未找到文件)。我需要了解存储过程的详细信息,以便提供进一步的建议。在解决问题之前,了解SP的操作将很有帮助。问题不是存储过程。问题在于EXEC master.dbo.xp_fileexist仅在用户是管理员时返回有效结果。所有其他人都得到0,表示即使文件存在也找不到匹配项。在不知道系统存储过程权限的作用或含义的情况下修改它们是不明智的。它们受到限制是有原因的。除了管理脚本之外,不需要它们,除非用户完全了解结果,否则不应启用它们。您是否确认服务帐户有权访问相关文件夹?(它可能会抛出一个错误,但值得检查)是的。服务帐户具有权限。当windows用户具有SQL管理员权限时,EXEC master.dbo.xp\u fileexist将返回准确的结果。否则,即使文件存在,也返回0。这是一个未记录的函数,除了管理脚本外,不应使用它。数据库不需要查看本地文件系统。
从SQL Server 2000升级而来
在这16年中,发生了很多变化,尤其是在安全方面。SQL Server 2005或2008禁用了最敏感的功能,如
xp\u cmd
。无论如何,这些功能都不是必需的——SQL Server代理可以很好地执行外部程序。任何powershell脚本都可以处理文件,甚至代理作业也可以包含powershell步骤。您使用
xp\u fileexist
的目的是什么?不管是什么,都有更好的方法