当前位置: 首页 > 面试题库 >

消息4834“渊ou没有使用批量装入语句的权限”。

令狐晟
2023-03-14
问题内容

无论我如何尝试,我都会收到此错误。

我有一个存储的proc,execute为:

CREATE PROCEDURE usp_myproc
WITH EXECUTE AS 'myuser'

在这个sp我有

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

myuser确实有bulkadmin角色,读/写,创建表,插入,选择,执行,修改权限。其中一些可能不是必需的,但这是我到目前为止已经尝试过的方法。我想念什么?

谢谢你。


问题答案:

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

有两种解决方法:

坏而又快的方法:

将您的数据库设置为“开”。它将完成工作。但是,如果您不完全了解它的html" target="_blank">功能,那么我的建议是不要这样做。

但是,这是代码:

ALTER DATABASE [YourDatabase] SET TRUSTWORTHY ON;

好的但较慢的方法

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

您要做的是使用证书对存储过程进行签名。您可以在数据库中使用该证书创建用户。您向该用户授予对数据库中表的适当权限。您还可以从同一证书创建“登录名”,然后授予该登录名大量权限。

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

步骤是:

  1. 在母版中创建证书

  2. 从该证书创建登录名

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

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

  1. 将证书导出到磁盘

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

现在我们可以完成

  1. 从证书创建用户
  2. 向该用户授予表权限
  3. 从存储过程中删除execute as子句
  4. 使用证书签署存储过程

这是代码:

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服务帐户具有写权限的路径替换您的目录!

完成设置后,请确保删除那些导出的证书。



 类似资料:
  • 问题内容: 我试图用大约50,000行10列填充Java中的resultSet,然后使用的方法将它们插入到另一个表中。 为了使过程更快,我进行了一些研究,发现在将数据读入resultSet时,fetchSize起着重要的作用。 如果fetchSize太低,可能会导致到服务器的行程过多,而fetchSize太高则会阻塞网络资源,因此我做了一些尝试,并设置了适合我的基础结构的最佳大小。 我正在阅读此r

  • 我有一个脚本可以插入大量的数据。此数据主要是前一个insert的复制,但至少有一个值不同。因此,我准备语句并绑定参数以执行和重复。 我现在使用的代码(一次全部大容量插入): 我想要实现的是,数据将用像上面这样的准备好的语句插入,但每个批处理的限制是1000(或任何其他数字)。我不能让这件事发生。我尝试使用和其他方法,但无法使其工作。

  • 问题内容: 如何批量更新mysql数据?如何定义这样的事情: 具有一些值,例如: 和其他值: 也许用mysql是不可能的?一个PHP脚本? 问题答案: 在这种情况下,最简单的解决方案是使用构造。它的工作速度非常快,并且可以轻松完成工作。 或使用建筑

  • 问题内容: 使用JDBC(Oracle),我需要在两个表的每一个中插入大约一千行。像这样: 问题在于两个表都是通过公共序列连接的,因此语句的顺序很重要。 如果我只有一张桌子,那会很容易。在这种情况下,我使用了代码: 但是,这种方法只能用一个准备好的语句,因此只能用一个插入。我该如何解决这个问题? 问题答案: 你可以试试 然后

  • 问题内容: 我正在用React构建一些东西,我需要在JSX中插入带有React变量的HTML。有没有办法像这样一个变量: 并像这样将其插入反应中并起作用? 并按预期插入HTML吗?我还没有看到或听到任何有关可以内联执行此操作的react函数的信息,也没有听说过任何可以使之起作用的解析方法。 问题答案: 您可以使用dragonallySetInnerHTML,例如

  • 我们计划有多个Kafka消费者(Java),它们具有相同的组ID..所以如果它从分配的分区中顺序读取,那么我们如何实现高吞吐量..例如,生产者每秒发布40条消息...消费者每秒处理1条消息...虽然我们可以有多个消费者,但不能有40条RT???如果我错了就纠正我... 在我们的情况下,使用者必须提交偏移量,只有在消息处理成功后...否则消息将被重新处理...有没有更好的解决方法???