消息4834“您无权使用批量加载语句”

时间:2014-01-09 19:13:34

标签: sql sql-server-2008

无论我尝试什么,我都会收到此错误。

我有一个存储过程,执行为:

CREATE PROCEDURE usp_myproc
WITH EXECUTE AS 'myuser'

在此s.p.我有

EXEC('INSERT INTO ' + @tablename + '
            SELECT col1, col2, col3
            FROM OPENROWSET( 
              BULK '''+ @filepath +''',
              FORMATFILE='''+ @formatfile +''',
              FIRSTROW=2
            )as t'
          )

myuser确实具有bulkadmin角色,读/写,创建表,插入,选择,执行,更改权限。其中一些可能不需要,但这是我到目前为止所尝试的。我错过了什么?

谢谢。

2 个答案:

答案 0 :(得分:13)

正如我在评论中所说,服务器级权限在您使用模拟时被剥离。

有两种解决方法:

糟糕而快捷的方式:

将数据库pushworthy设置为ON。它将完成工作。但是如果你不完全理解它的作用,那么我的建议是不要这样做。

但是,这是代码:

ALTER DATABASE [YourDatabase] SET TRUSTWORTHY ON;

良好但较慢的方式

这更精确,并没有任何令人讨厌的安全副作用。

您所做的就是使用证书对存储过程进行签名。您可以在数据库中从该证书创建用户。您为该用户授予对数据库中表的适当权限。您还可以从同一证书创建登录,并为该登录授予批量权限。

因为您使用该证书对存储过程进行签名,所以每次执行sp时,它都会在该用户的上下文中执行,并登录从该证书创建的位置。

步骤是:

  1. 在master中创建证书

  2. 从该证书创建登录

  3. 授予该登录的批量管理员权限

  4. 现在您需要在用户数据库中使用完全相同的证书,因此我们需要执行一些额外的步骤

    1. 将证书导出到磁盘

    2. 将证书导入您的用户数据库

    3. 现在我们可以最终确定

      1. 从证书创建用户
      2. 向该用户授予对表的权限
      3. 从存储过程中删除execute as子句
      4. 使用您的证书签署存储过程
      5. 这是代码:

        USE master
        go
        CREATE CERTIFICATE BulkInsertCert
           ENCRYPTION BY PASSWORD = 'NicePassword!0'
           WITH SUBJECT = 'Gives Bulk Insert Privilegde'
        go
        
        CREATE LOGIN BulkInsert_CertLogin FROM CERTIFICATE BulkInsertCert
        go
        
        
        GRANT ADMINISTER BULK OPERATIONS TO BulkInsert_CertLogin
        go
        
        
        BACKUP CERTIFICATE BulkInsertCert TO FILE = '[your directory]\BulkInsertCert.cer'
        WITH PRIVATE KEY (FILE = '[your directory]\BulkInsertCert.pvk' ,
                          ENCRYPTION BY PASSWORD = 'EvenNicerPassword!0',
                          DECRYPTION BY PASSWORD = 'NicePassword!0')
        go
        
        USE [YourDatabase]
        CREATE CERTIFICATE BulkInsertCert FROM FILE = '[your directory]\BulkInsertCert.cer'
        WITH PRIVATE KEY (FILE = '[your directory]\BulkInsertCert.pvk',
                          DECRYPTION BY PASSWORD = 'EvenNicerPassword!0',
                          ENCRYPTION BY PASSWORD = 'TheVeryBestPasswordThereIs!0')
        go
        --NOW DELETE THE CERTIFICATES FROM DISK
        
        CREATE USER BulkInsert_CertUser FOR CERTIFICATE BulkInsertCert
        go
        GRANT ALTER, INSERT ON [YourTable] TO BulkInsert_CertUser
        go
        
        
        ALTER PROCEDURE usp_myproc
        AS
        EXEC('INSERT INTO ' + @tablename + '
                    SELECT col1, col2, col3
                    FROM OPENROWSET( 
                      BULK '''+ @filepath +''',
                      FORMATFILE='''+ @formatfile +''',
                      FIRSTROW=2
                    )as t'
                  )
        -- Sign the test procedure each time you have changed it.
        ADD SIGNATURE TO usp_myproc BY CERTIFICATE BulkInsertCert
            WITH PASSWORD = 'TheVeryBestPasswordThereIs!0'
        go
        

        最后的说明:

        请将您的目录替换为您确定sql服务帐户有权写入的路径!

        确保在完成设置后删除这些导出的证书。

答案 1 :(得分:3)

尝试授予以下服务器级别权限:

    GRANT ADMINISTER BULK OPERATIONS TO [server_login]

此外,还有另一个SO related just to this,请参阅。