标签: bulk-insert

依赖 INSERT 的 OUTPUT 子句的顺序是否安全?

鉴于此表:

CREATE TABLE dbo.Target (
   TargetId int identity(1, 1) NOT NULL,
   Color varchar(20) NOT NULL,
   Action varchar(10) NOT NULL, -- of course this should be normalized
   Code int NOT NULL,
   CONSTRAINT PK_Target PRIMARY KEY CLUSTERED (TargetId)
);
Run Code Online (Sandbox Code Playgroud)

在两个稍微不同的场景中,我想插入行并从标识列返回值。

场景一

INSERT dbo.Target (Color, Action, Code)
OUTPUT inserted.TargetId
SELECT t.Color, t.Action, t.Code
FROM
   (VALUES
      ('Blue', 'New', 1234),
      ('Blue', 'Cancel', 4567),
      ('Red', 'New', 5678)
   ) t (Color, Action, Code)
;
Run Code Online (Sandbox Code Playgroud)

场景二

CREATE TABLE #Target (
   Color varchar(20) NOT NULL,
   Action varchar(10) NOT NULL, …
Run Code Online (Sandbox Code Playgroud)

sql-server insert identity sql-server-2012 bulk-insert

22
推荐指数
1
解决办法
3430
查看次数

为什么 BULK INSERT 被认为是危险的?

我想了解为什么一般的网络安全团队(我接触过的不止一个组织)坚决反对BULK INSERT向应用程序和数据库程序员授予(例如 TSQL)权限?我无法相信“填补磁盘滥用”的借口,除非我遗漏了一些东西,因为最终结果与执行以下操作的应用程序没有什么不同:

for (long i = 0; i < LONG_MAX; ++i)
    executeSQL("INSERT INTO table VALUES(...)");
Run Code Online (Sandbox Code Playgroud)

并且INSERT是一种常见的DML命令,任何人都基本写权限才能执行。

为了应用程序的利益,BULK INSERT它更高效、更快,并且使程序员无需解析 SQL 之外的文件。

编辑:我最初在信息安全站点上问这个问题是有原因的 - 不是 DBA 反对使用 BULK INSERT,而是“信息保证”(简称 IA - 网络安全人员)迫使这个问题。我会让这个问题再讨论一两天,但如果批量操作确实绕过约束或触发器,我可以看到这是一个问题。

sql-server permissions import bulk-insert

22
推荐指数
3
解决办法
2万
查看次数

从一个 MySQL 表复制到同一数据库的另一个 MySQL 表

我在 MySQL 表中有大约 4000 万行,我想将此表复制到同一数据库中的另一个表。这样做的最有效方法是什么?需要多少时间(大约)?

mysql insert bulk-insert

15
推荐指数
1
解决办法
5万
查看次数

通过网络批量插入

有人可以帮我解决这些问题吗?

BULK INSERT DATABESE01.dbo.TABLE01
FROM '\\COMPUTER01\FOLDER01\TextFile.txt'
WITH
(
    FIELDTERMINATOR = ' ',
    rowterminator = '\n',
    tablock
)
Run Code Online (Sandbox Code Playgroud)

错误显示,无法打开:

无法批量插入,因为无法打开文件“\SERVERNAME\FOLDERNAME\textFile.txt”。操作系统错误代码 5(访问被拒绝。)

该路径位于网络上的另一台计算机上。

sql-server bulk-insert

13
推荐指数
1
解决办法
6万
查看次数

为 BULK INSERT 配置无约束委派

我在 Always On 可用性组中有一对 Microsoft SQL Server 2016 节点。我正在尝试对BULK INSERT位于 Windows Server 2016 文件服务器故障转移群集上的文件执行(使用 SQL Server 2016 Management Studio 查询),但出现以下错误:

消息 4861,级别 16,状态 1
无法批量加载,因为无法打开文件“\nas2.my.domain\Microsoft SQL Server 2016 Enterprise\test.txt”。操作系统错误代码 5(访问被拒绝。)。

无论我使用活动节点名称 ( nas2.my.domain) 还是故障转移群集侦听器 ( nas.my.domain),都会发生这种情况。

环顾四周后,我发现这是由于 SQL Server 由于与BULK INSERT.

如果您使用 Windows 身份验证连接到 SQL Server,则 SQL Server 服务帐户在连接到文件服务器时会尝试模拟您的用户帐户。如果您使用 SQL Server 身份验证进行连接,它将以 SQL Server 服务帐户的身份连接到文件服务器。

如果委派和模拟配置不正确(默认状态),SQL Server 服务将无法模拟您的用户帐户,并将退回尝试以匿名用户身份连接到文件服务器。

这可以通过查看文件服务器上的安全事件日志来确认。这些事实以及有关配置无约束和约束委派的指南记录在以下链接中:

我已经尝试按照thesqldude的指南中的说明进行操作,但它仍然无法正常工作。

我尝试使用的数据库BULK INSERT不是可用性组的一部分,因此只有 MSSQL1 节点应该相关。文件服务器在 …

authentication sql-server availability-groups sql-server-2016 bulk-insert

12
推荐指数
1
解决办法
2367
查看次数

如何调查 BULK INSERT 语句的性能?

我主要是使用实体框架 ORM 的 .NET 开发人员。但是,因为我不想在使用 ORM失败,所以我试图了解数据层(数据库)中发生了什么。基本上,在开发过程中,我启动分析器并检查代码的某些部分根据查询生成了什么。

如果我发现一些非常复杂的事情(ORM 甚至可以从相当简单的 LINQ 语句中生成糟糕的查询,如果编写不仔细)和/或繁重(持续时间、CPU、页面读取),我会将它放入 SSMS 并检查其执行计划。

它适用于我的数据库知识水平。但是, BULK INSERT 似乎是一种特殊的生物,因为它似乎不会产生 SHOWPLAN

我将尝试说明一个非常简单的例子:

表定义

CREATE TABLE dbo.ImportingSystemFileLoadInfo
(
    ImportingSystemFileLoadInfoId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_ImportingSystemFileLoadInfo PRIMARY KEY CLUSTERED,
    EnvironmentId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo REFERENCES dbo.Environment,
    ImportingSystemId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo_ImportingSystem REFERENCES dbo.ImportingSystem,
    FileName NVARCHAR(64) NOT NULL,
FileImportTime DATETIME2 NOT NULL,
    CONSTRAINT UQ_ImportingSystemImportInfo_EnvXIs_TableName UNIQUE (EnvironmentId, ImportingSystemId, FileName, FileImportTime)
)
Run Code Online (Sandbox Code Playgroud)

注意:表上没有定义其他索引

批量插入 (我在探查器中捕获的内容,仅一批)

insert bulk [dbo].[ImportingSystemFileLoadInfo] ([EnvironmentId] …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan sql-server-2014 bulk-insert

12
推荐指数
2
解决办法
1万
查看次数

批量插入后外键变得不可信

在 SQL 2014 版服务器(12.0.2430.0 - 还没有 SP1)中,数据库处于 2012 兼容模式(正在努力将其切换到 2014...)我有一些外键对象,它们始终标记为not trusted在数据库中. 我在没有NOCHECK选项的情况下删除并重新创建了它们,但在 5-10 分钟内它们再次变得不受信任,如果我生成一个CREATE脚本,它会显示为:

ALTER TABLE [dbo].[Points]  WITH NOCHECK 
ADD  CONSTRAINT [FK_BadgeId] FOREIGN KEY([BadgeId])
REFERENCES [dbo].[Badge] ([Id])
GO
Run Code Online (Sandbox Code Playgroud)

正在使用的创建脚本是:

ALTER TABLE [dbo].[Points]
ADD  CONSTRAINT [FK_BadgeId] FOREIGN KEY([BadgeId])
REFERENCES [dbo].[Badge] ([Id])
GO

ALTER TABLE [dbo].[Points] CHECK CONSTRAINT [FK_BadgeId]
GO
Run Code Online (Sandbox Code Playgroud)

没有复制,没有第三方工具,我正在监视数据库上的所有 DDL 语句,因此它不是另一个用户。

我能够很好地检查约束(WITH CHECK CHECK在每个约束上使用),但不久之后它们仍然不受信任。只有在凌晨运行的维护作业是 Ola 的,而且这种情况全天都在发生。

更新:

因此,经过几次跟踪以缩小可能性之后,似乎 aBULK INSERT可能会导致FK不可信。这个 msdn 问题指出这是密钥变得不受信任的有效途径,这是我第一次听说它。

所以我现在的问题是,是否有替代策略BULK INSERT可以保持外键 …

foreign-key sql-server sql-server-2014 bulk-insert

11
推荐指数
1
解决办法
4148
查看次数

Tablock 提示触发死锁

我通过两个并行运行的执行 SQL 任务和以下形式的 SQL,使用最少的日志记录将两个数据集插入到一个空的堆表中。

INSERT INTO Table (TABLOCK) SELECT FROM ...
Run Code Online (Sandbox Code Playgroud)

在作业挂起一段时间后,其中一个 SQL 任务成为死锁受害者。下面是死锁图的 XML 输出。

有人能解释一下幕后发生了什么吗?

  <resource-list>
   <objectlock lockPartition="0" objid="1586156746" subresource="FULL" dbid="7" objectname="dbo.TargetTable" id="lock7374a00" mode="IX" associatedObjectId="1586156746">
    <owner-list>
     <owner id="process9609dc8" mode="Sch-S"/>
     <owner id="process9609dc8" mode="IX"/>
    </owner-list>
    <waiter-list>
     <waiter id="process5e13048" mode="X" requestType="convert"/>
    </waiter-list>
   </objectlock>
   <objectlock lockPartition="0" objid="1586156746" subresource="FULL" dbid="7" objectname="dbo.TargetTable" id="lock7374a00" mode="IX" associatedObjectId="1586156746">
    <owner-list>
     <owner id="process5e13048" mode="Sch-S"/>
     <owner id="process5e13048" mode="IX"/>
    </owner-list>
    <waiter-list>
     <waiter id="process9609dc8" mode="X" requestType="convert"/>
    </waiter-list>
   </objectlock>
  </resource-list>
Run Code Online (Sandbox Code Playgroud)

事情变得更加棘手,因为我发现在大多数情况下,两个执行 SQL 任务可以成功并行运行。试试下面:

Create table dbo.TablockInsert (c1 int, c2 int, c3 int)

--then …
Run Code Online (Sandbox Code Playgroud)

sql-server deadlock ssis sql-server-2008-r2 bulk-insert

10
推荐指数
2
解决办法
2881
查看次数

SQL 中的最小日志记录条件

我已经编写了一个脚本来测试在这个页面http://technet.microsoft.com/en-us/library/dd425070(v=sql.100).aspx中标题为 Summarizing Minimal Logging conditions about when最小日志记录发生或不发生。

使用此脚本,我发现每种不同类型插入的日志记录长度总和如下:

  • 堆为空 没有块 60000
  • 堆为空,带有 tabblock 56000
  • Heap non empty no tabblock 60000
  • 堆非空,带有 tabblock 56000
  • 堆加索引为空 无标签块 126188
  • 堆加索引为空,带有 tabblock 114188
  • 堆加索引非空无标签块 138696
  • 堆加索引非空,带有 Tablock 112000
  • 集群空有序无标签 64168
  • 簇为空,用 tabblock 56168 排序
  • 集群空无序无标签块 73388
  • 集群空无序,带有 tabblock 65388
  • 集群非空无标签块 63912
  • 集群非空,带有 tabblock 55944
  • 簇加索引为空 无标签块 124336
  • 簇加索引为空,带有 tabblock 108336
  • 集群加索引非空无标签块 123876
  • 带有标签块的集群加索引非空 107924

其中一些数字似乎与 technet 页面上的表格不符。特别是:

  • 插入空表和非空表之间的日志记录似乎没有区别,但是该页面声称在插入到没有 tabblock 的非空集群时应该有完整的日志记录
  • 使用 Tablock 插入带有和索引的堆或集群似乎确实减少了日志记录,但该页面声称应该有完整的日志记录。
  • 使用insert的SELECT INTO方法时,fn_dblog中没有行是insert操作,但是页面把这个方法列为批量加载操作,应该有表中描述的行为

作为参考,这是在 SQL express 数据库上运行的,当我运行 DBCC TRACESTATUS (610) …

sql-server-2008 sql-server bulk-insert

9
推荐指数
1
解决办法
946
查看次数

插入表 select * from table vs 批量插入

我只是想知道 SQL 语句INSERT INTO TABLE1 SELECT * FROM TABLE2,会像批量插入一样工作吗?

如果没有,有没有办法在插入记录时排除索引。进程在一次执行中插入 1.5 亿条数据。

我们计划创建阶段表(不会有任何索引Table1),然后将其从阶段表转移到目标表(会有索引Table2

我们不是在从过程中创建平面文件的情况。

但是当我们将数据从Table1(未编入索引)传输到Table2(编入索引)时,我们正在寻找可以加快处理速度的方法。

任何方式使用BulkInsertTable1Table2

sql-server insert select bulk-insert

9
推荐指数
1
解决办法
6万
查看次数