- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Windows Server 2008 R2 Enterprise,SQL Server 2008 X64,SP3,开发人员版
我构建并动态执行(通过sp_executesql)一个BULK INSERT命令。通用形式为:
BULK INSERT #HeaderRowCheck
from "\\Server\Share\Develop\PKelley\StressTesting\101\DataSet.csv"
with
(
lastrow = 1
,rowterminator = '\n'
,tablock
,maxerrors = 0
,errorfile = 'C:\SQL_Packages\TempFiles\#HeaderRowCheck_257626FB-A5CD-41B8-B862-FAF8C591C7A9.log'
)
Error #4861 encountered while loading header information from file "DataSet.csv": Cannot bulk load because the file "C:\SQL_Packages\TempFiles\#HeaderRowCheck_D0070742-76A5-4175-A1A7-16494103EF25.log" could not be opened. Operating system error code 80(The file exists.).
最佳答案
我与Microsoft技术支持一起开了一个案子,经过反复的反复,Pradeep M.M. (SQL Server支持技术负责人)全力以赴。
一般过程:读取文件夹中的文件列表,然后一个个地对这些文件执行一系列批量插入操作(首先读取第一行,我们将其解析为列,然后读取第二行以上的数据) )。所有批量插入均使用“ ErrorFile”选项,以便为用户提供错误格式的数据时我们可以提供的信息。流程已经运行了3年以上,但是在最近的压力测试条件下(单个SQL Server实例最多执行8个同时运行,并且所有文件的格式正确),我们得到了上面列出的错误。
最初,尽管由于产生了“已经打开”的错误而导致生成GUID时出现了错误,但是最终还是放弃了这个想法-如果newid()无法正常运行,那么将会有更多的人遇到更严重的问题。
根据Pradeep,这是批量插入工作原理的分步过程:
批量插入命令已提交并已分析语法错误
然后编译BULK INSERT命令以生成执行
计划相同
在编译阶段(如果在查询中)是否已指定
ERRORFILE参数,然后我们将创建ErrorFile.log和
ErrorFile.Error.Txt到指定的文件夹位置(重要
这里要了解的是文件大小为0kb)
文件创建完成后,我们将使用删除这两个文件
Windows API调用
一旦执行计划准备就绪,我们进入执行阶段
并尝试执行“批量插入”命令作为其中的一部分
重新创建ErrorFile.log和ErrorFile.Error.Txt到文件夹
指定的位置(根据联机丛书文档中的错误
文件不应放在此位置,否则我们将无法通过
执行http://msdn.microsoft.com/en-us/library/ms188365.aspx
执行完毕后,如果
批量插入各自的错误记录到错误文件中
如果没有错误创建,则这2个文件将被删除。
在失败的运行过程中运行ProcMon(进程监视器)显示ErrorFile在步骤3中成功创建并打开,但在步骤4中未关闭,导致步骤5生成了我们看到的错误。 (为成功运行,已按预期创建并关闭了文件。)
对ProcMon的进一步分析表明,尝试批量插入后,另一个运行CMD.EXE的进程正在对文件发出“关闭句柄”操作。我们使用一个涉及xp_cmdshell的例程来检索要处理的文件列表,这将是CMD.EXE进程的原因。这是踢球者:
…有一些业务逻辑会在SQL Server内部启动CMD.EXE,并且由于CMD.EXE是子进程,因此它继承了由父进程打开的所有句柄(因此,这可能是某种时序问题,其中CMD.EXE中包含句柄对于在启动时打开并且所有句柄都被CMD.EXE继承的文件都是无法删除的,只能在CMD.EXE被销毁后才能释放)
就是这样。单次运行永远不会遇到此问题,因为在发出大容量插入之前,它的xp_cmdshell调用已完成。但是在并行运行中,尤其是在许多并行运行中(我只遇到了5次或更多运行的问题),发生了计时问题,使得:
SSIS包之一执行并调用存储过程
内部使用XP_CMDSHELL并启动CMD.EXE进行枚举
文件
与SQL Server的相同连接完成文件枚举
然后启动批量插入活动,它处于编译状态
BULK INSERT命令的阶段
根据批量插入的设计,我们确实创建了ErrorFile
在编译阶段,然后在编译后将其删除
阶段完成
同时,另一个SSIS包被执行并调用
内部使用XP_CMDSHELL并启动的存储过程
CMD.EXE枚举所有文件
CMD.EXE是在父项下启动的子进程
处理SQLServr.exe,因此默认情况下它将继承所有句柄
由SQLServr.exe创建(因此,此过程将获取
首先由大容量插入创建的ERRORFILE
连接)
现在在“首次连接”中,编译阶段结束,
因此,我们正在尝试删除必须关闭的文件
所有句柄,我们确实看到CMD.EXE持有该句柄
文件,它仍然处于打开状态,因此我们无法删除该文件。所以
在不删除文件的情况下,我们进入执行阶段
在执行阶段,我们正在尝试使用
相同的名称,但是由于文件已经存在,因此我们将失败并显示错误
“操作系统错误代码80(该文件存在。)。”
我的短期变通办法是(1)实现重试循环,生成新的ErrorFile名称,并在放弃之前尝试最多进行三次新的大容量插入,以及(2)在我们的夜间进程中构建另一个例程以删除找到的所有文件在我们的“ ErrorFile文件夹”中。
长期修复是修改我们的代码,使其不通过xp_cmdshell列出文件。这似乎是可行的,因为整个ETL过程都由SSIS程序包包装和管理。或者,可以构建和使用CLR例程。就目前而言,鉴于我们预期的工作量,解决方法已足够(尤其是鉴于我们目前正在处理的所有其他事情),因此在执行最终定稿之前可能要花点时间固定。
为后代发贴,以防万一!
关于sql-server - 使用ErrorFile选项时,同时SQL BULK INSERT生成失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8945130/
我正在开发一些用于计费的数据库项目(PHP/MySQL)。 每当创建新账单时,我想生成一个由年、周和增量编号组成的账单编号。我想用触发器来做到这一点。触发器将使用现有的账单编号来查找增量编号,或者从新
我有一个 MySQL 插入,我正在使用 RAND 生成随机 INT 值问题是它不会插入到数据库中,因为该列接受 TINYINT ,如何将输出转换为 TINYINT。代码示例如下: INSERT INT
如果我想从单个插入中保存主键 (mytable_id),我已完成以下操作: CREATE OR REPLACE FUNCTION myfunct(ownerid text) RETURNS void
为了简单起见,假设我有两个表 用户表(id,email) 用户日志表(id, date) 无论 id 被插入到 user 表中,相同的 id 也应该被插入到 user_log 表中,否则事务应该失败。
为了简单起见,假设我有两个表 用户表(id,email) 用户日志表(id, date) 无论 id 被插入到 user 表中,相同的 id 也应该被插入到 user_log 表中,否则事务应该失败。
我知道在触发器中 - 至少对于 SQL Server - 人们永远不应该假设插入的表只有一行,这意味着触发器中这样的 SQL 通常是不好的: select @UserID = ID from inse
我正在使用 bigquery 对象中的方法 tabledata().insertAll 更新行列表。执行后,返回显示没有错误。但是,我的表仍然继续,没有写入任何数据。 可能是权限问题。如果是这样,为什
这是一个扩展 F# Recursive Tree Validation 的问题,我昨天已经很好地回答了。 这个问题涉及在现有树中插入一个 child 。这是我想使用的更新类型: type Name
我有 2 个表:用户和照片(在 mysql 数据库中)。 在这里你可以看到两个表之间的关系 User Photos -------------
我试图同时在不同的表上插入两行。 子查询INSERT INTO的AUTO_INCRMENT或id的值(如果已经存在)应该写入主查询中。 目前我有这个(仅用 3 个值简化),但它不起作用。我想知道是否有
我有一个 900 万行的表,由于其庞大的规模,我正在努力处理所有这些数据。 我想做的是在不覆盖数据的情况下将 IMPORT 一个 CSV 添加到表中。 在我做这样的事情之前; INSERT if no
我正在写新闻并将其插入到我的数据库中,我在 3 年前构建了代码并且运行良好,但我不能再插入了,我不明白为什么: $insert=mysqli_query($co,"INSERT INTO articl
我正在尝试编写一个简单的 INSERT 语句来将新用户添加到数据库中,但它不起作用,这意味着,我尝试插入到表中的数据都没有被插入。几个小时以来,我一直在尝试解决此问题,但没有成功。我尝试编写插入语句的
所以我有这个表格: http://i.imgur.com/vZYssQy.png 现在 ID、First Name、Last Name、DOB、Address、Phone Number 和 Post
在控制台中运行查询(SELECT 语句)时,从数据库检索到的数据以表格格式显示在数据库控制台工具窗口的结果 Pane 中。 我已经搜索过 datagrip Help我只是想知道是否有任何方法可以用于为
每当使用触发器插入行时,我都试图将另一行插入表中,但收到以下错误消息: The target table 'EDDSDBO.Redaction' of the DML statement cannot
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 6 年前。 Improve
我有以下代码片段: $get_data = mysqli_query ($connect, "SELECT * FROM users WHERE username = '$username'");
情况:需要向 SQLite 数据库中插入大量数据。 问题:我们可以使用两个语句来插入数据 - data = [("111", "222", "333"), ("AAA", "BBB", "CCC"),
我的数据库中有一个表 Teacher: TABLE Teacher ( ID CHAR (7) NOT NULL , name
我是一名优秀的程序员,十分优秀!