带有OUTPUT子句的SQL Server BULK INSERT

本文关键字:Server BULK INSERT SQL OUTPUT 子句 带有 | 更新日期: 2023-09-27 18:00:35

我正在做一个宠物项目,该项目将允许我将游戏收藏存储在数据库中,并为这些游戏写笔记。通过将所需变量插入我的game_information表并从该表输出新创建的行的PK(标识),对游戏的单个条目进行了编码,因此我可以将其与注释一起插入到我的game_notes表中。

var id = db.QueryValue("INSERT INTO Game_Information (gamePrice, name, edition) output Inserted.gameId VALUES (@0, @1, @2)", gamePrice, name, edition); 
db.Execute("INSERT INTO Game_Notes(gameId, notes, noteDate) VALUES (@0, @1, @2)", id, notes, noteDate);

我现在正在尝试通过csv批量上传数据,但我如何编写一个BULK INSERT来输出新创建的行的所有PK,以便将它们与一个名为notes的变量一起插入到我的第二个表(game_notes)中?

目前我有以下内容:

  • 读取.csv并使用BULK INSERT将信息转储到游戏信息视图中的存储过程

    @FileName nvarchar(200)
    AS
    BEGIN
        DECLARE @sql nvarchar(MAX);
        SET @sql = 'BULK INSERT myview
                    FROM ''mycsv.csv''
                    WITH
                    (
                        FIELDTERMINATOR = '','',
                        ROWTERMINATOR = '''n'',
                        FIRSTROW = 2
                    )'
        EXEC(@sql)
    END
    

在WebMatrix 中创建设置的C#代码

if ((IsPost) && (Request.Files[0].FileName!=" "))
{
                var fileSavePath = "";
                var uploadedFile = Request.Files[0];
                fileName = Path.GetFileName(uploadedFile.FileName);
                uploadedFile.SaveAs(//path +filename); 
                var command = "EXEC Procedure1 @FileName = @0"; 
                db.Execute(command, //path +filename); 
                File.Delete(//path +filename); 
}

这允许csv记录插入game_information

如果这在BULK INSERT中不可行,那么类似的方法会是一个有效的解决方案吗?

BULK INSERT into a temp_table
INSERT from temp_table to my game_information table
OUTPUT the game_Ids from the INSERT as an array(?)
then INSERT the Ids along with note into game_notes. 

我也一直在研究OPENROWSET,但我不确定这是否能实现我想要实现的目标。非常感谢对此的反馈。

带有OUTPUT子句的SQL Server BULK INSERT

感谢您的输入。我能够通过如下修改我的BULK INSERT来获得期望的结果:

BEGIN
DECLARE @sql nvarchar(MAX);
SET @sql=   
'CREATE TABLE #Temp (--define table--)
 BULK INSERT #Temp   --Bulk into my temp table--
 FROM '+char(39)+@FileName+char(39)+' 
 WITH
(
  FIELDTERMINATOR = '','',
  ROWTERMINATOR = '''n'',
  FIRSTROW = 2
)
    INSERT myDB.dbo.game_information(gamePrice, name, edition, date)
    OUTPUT INSERTED.gameId, INSERTED.Date INTO myDB.dbo.game_notes(gameId, noteDate)
    SELECT gamePrice, name, edition, date
    FROM #Temp'
EXEC(@sql)
END    

这将正确的id放入game_notes中,并将表的Note列保留为这些条目的Null。这意味着我可以运行一个简单的

"UPDATE game_notes SET Notes = @0 WHERE Notes IS NULL";

将所需的音符推入正确的行。我在同一个If (IsPost)中执行这个和存储的批量过程,所以我觉得我受到了保护,不会出现错误的意外注释更新。

您有几个不同的选项。

  1. 大容量插入临时表,然后将信息复制到永久表中,这绝对是一个有效的解决方案。然而,根据您的尝试,我认为不需要临时表。只需批量导入到game_info中,将ID选择到应用程序中,然后更新game_notes。

  2. 另一种选择是插入钥匙。您可以允许表启用IDENTITY_INSERT,并且只将键作为CSV文件的一部分。请参见此处:https://msdn.microsoft.com/en-ca/library/ms188059.aspx?f=255&MSPPError=-2147217396。如果你这样做了,那么你可以在Game_information表中进行BULK INSERT,然后使用不同的CSV文件在辅助表中进行第二次BULK INSERT。请确保重新启用键约束,并在完成后关闭IDENTITY_INSERT。

如果你需要对从CSV文件中选择的数据进行更具体的控制,那么你可以使用OPENROWSET,但你的帖子中没有足够的细节来进一步评论。