批量插入在ssms中工作,但在其他应用程序中不起作用

时间:2014-04-08 14:53:24

标签: sql sql-server reporting-services

上下文:SQL Server 2005

我有一个简单的proc,它从外部文件执行批量加载。

ALTER proc [dbo].[usp_test] 
AS 
   IF OBJECT_ID('tempdb..#promo') is not null BEGIN
      DROP TABLE #promo
   END

   CREATE TABLE #promo (promo VARCHAR(1000))

   BULK INSERT #promo
   FROM '\\server\c$\file.txt'
   WITH
   (
      --FIELDTERMINATOR = '',
      ROWTERMINATOR = '\n'
   )

   select * from #promo

我可以在SSMS中运行它。但是,当我从另一个应用程序(Reporting Service 2005)调用它时,它会抛出此错误:

  

无法批量加载,因为文件" \ server \ c $ \ file.txt"不能打开。操作系统错误代码5(访问被拒绝。)。

这很复杂,因为它可能与报告服务使用的帐户或某些Windows安全问题有关。

但我认为我可以冒充我用来创建proc的登录,因为登录可以在SSMS中运行。因此尝试将proc更改为'使用execute as self',它编译好了,但是当我尝试在SSMS中运行它时,我得到了:

  

Msg 4834,Level 16,State 4,Procedure usp_test,Line 12
  您无权使用批量加载语句。

我仍在同一个会话中,所以当我运行它时,它实际上是作为自我执行的,这是我现在使用的登录,那么为什么我收到此错误?我该怎么办?

我知道它有点不清楚所以只列出事实。

======更新

我刚尝试使用SSIS将文件加载到表中,以便报告可以使用。该程序包在BIDS中运行正常,但是当在sql代理程序作业中运行时,它获得了对该文件的相同访问权限被拒绝错误。然后我设置了一个代理,让包在该帐户下运行,并且该作业没有问题。

所以我在想,使用的帐户是否可以访问该文件? ssrs使用什么帐户?可以将ssrs设置为像sql代理一样在代理下运行吗?

==============再次更新 最后得到它排序

我创建了一个SSIS包,将包放在一个作业中(在代理帐户下运行以访问该文件),并在proc中执行该作业。虽然很棘手(需要判断作业是否在proc中完成),但这确实有效。这太难以维护,因此只需创建作为概念证明,不会投入生产。

http://social.msdn.microsoft.com/Forums/sqlserver/en-US/761b3c62-c636-407d-99b5-5928e42f3cd8/execute-as-problem?forum=transactsql

1 个答案:

答案 0 :(得分:2)

1)您获得"您无权使用批量加载声明的原因。"是因为(当然)您没有权限使用批量加载语句。

您必须是服务器级别的 sysadmin bulkadmin 才能运行BULK命令。

2)是,"访问被拒绝"通常表示您在SSRS中运行sproc时使用的任何凭据都没有该文件的权限。所以:

  • 让所有人都可以使用该文件。
  • 将对文件具有完全访问权限的已知凭据设置为运行sproc的数据源。

3)哎呀,老兄。

  • 为什么不直接将文本文件用作SSRS中的数据源?
  • 如果不可能,为什么不在SSRS之外的一个sproc中执行所有ETL,然后只使用一个简单的" select * from table" SSRS声明?
  • 每次有人想要报告时,请不要运行BULK INSERT 。如果他们需要对文件进行最新读取,请将该文件用作数据源。如果他们可以接受10分钟的数据延迟,那么创建一个批处理作业或ETL进程来挑选文件并每隔10分钟将其放入数据库表中,然后从中读取。 写一次,读很多。