using SqlBulkCopy to copy results of stored proc which returns multiple datasets












0















I have a stored proc which returns two distinct sets of results (header and detail). I then want to take these result sets, and write them independently into two destination tables. The format of each result set is identical to the appropriate destination table, so SqlBulkCopy seemed like the ideal solution. Code is as follows:



Try
Using connection As SqlConnection = New SqlConnection(My.Settings.MyConnectionString)
Dim sqlQuery As String = "exec sp_get_order_batch @BatchSize, @NewBatchId"
connection.Open()

Using comm As SqlCommand = New SqlCommand(sqlQuery, connection)
comm.Parameters.Add("@BatchSize", SqlDbType.Int).Value = Me.Config.BatchSize
comm.Parameters.Add("@NewBatchId", SqlDbType.Int).Value = Me.Config.GetNewBatchNumber()

Dim rs As SqlDataReader = comm.ExecuteReader
Dim dtHeader As DataTable = New DataTable
dtHeader.Load(rs)

If dtHeader.Rows.Count >= 1 Then
'We've got some data back - yippee.

'Write the header data out to the holding table
Using sqlBulkCopyHeader As New SqlBulkCopy(connection)
sqlBulkCopyHeader.DestinationTableName = "dbo.web_order_header"
Try
sqlBulkCopyHeader.WriteToServer(rs)
Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try
End Using

'Grab the line data out as well...
rs.NextResult()
Dim dtLines As DataTable = New DataTable
dtLines.Load(rs)

'Write the line data out to the holding table
Using sqlBulkCopyLines As New SqlBulkCopy(connection)
sqlBulkCopyLines.DestinationTableName = "dbo.web_order_lines"
Try
sqlBulkCopyLines.WriteToServer(rs)
Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try
End Using

End If

End Using
End Using

Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try


However, what is actually happening is the first call to SqlBulkCopy is actually trying to write the seconf result set into the destination table, rather than the first.



Is there a way to achieve what I want without having to resort to iterating the lines from each dataset and writing them in one at a time??










share|improve this question




















  • 1





    Shouldn't you be passing dtHeader and dtLines as arguments to WriteToServer rather than rs?

    – jmcilhinney
    Nov 13 '18 at 12:03











  • Ok, note to self - check the overloads before posting on SO!!! All the examples I found just sent the SqlDataReader object as the parameter, not the DataTable!

    – Si Stone
    Nov 13 '18 at 12:15











  • Almost there now. However the above code (when I send a DataTable rather than the SqlDataReader) results in an empty second datatable. I assume this is because the Reader is sequential so doesn't actually know where the second result set starts... tried all kinds of different solutions without success... Any thoughts?

    – Si Stone
    Nov 13 '18 at 14:43











  • A data reader knows exactly where each result set starts. When you call NextResult it takes you directly to the start of the next result set. If you're not getting any data after that then I would suggest that your second result set is empty. Maybe you should do some actual testing and debugging rather than just reading code and looking at final results. Maybe you should try using a data adapter to fill a DataSet with the same query and see what you get that way. There's lots you can do to diagnose the issue.

    – jmcilhinney
    Nov 13 '18 at 22:19











  • Do you have your connection string setup to support multiple active result sets?

    – Chris Dunaway
    Nov 15 '18 at 19:34
















0















I have a stored proc which returns two distinct sets of results (header and detail). I then want to take these result sets, and write them independently into two destination tables. The format of each result set is identical to the appropriate destination table, so SqlBulkCopy seemed like the ideal solution. Code is as follows:



Try
Using connection As SqlConnection = New SqlConnection(My.Settings.MyConnectionString)
Dim sqlQuery As String = "exec sp_get_order_batch @BatchSize, @NewBatchId"
connection.Open()

Using comm As SqlCommand = New SqlCommand(sqlQuery, connection)
comm.Parameters.Add("@BatchSize", SqlDbType.Int).Value = Me.Config.BatchSize
comm.Parameters.Add("@NewBatchId", SqlDbType.Int).Value = Me.Config.GetNewBatchNumber()

Dim rs As SqlDataReader = comm.ExecuteReader
Dim dtHeader As DataTable = New DataTable
dtHeader.Load(rs)

If dtHeader.Rows.Count >= 1 Then
'We've got some data back - yippee.

'Write the header data out to the holding table
Using sqlBulkCopyHeader As New SqlBulkCopy(connection)
sqlBulkCopyHeader.DestinationTableName = "dbo.web_order_header"
Try
sqlBulkCopyHeader.WriteToServer(rs)
Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try
End Using

'Grab the line data out as well...
rs.NextResult()
Dim dtLines As DataTable = New DataTable
dtLines.Load(rs)

'Write the line data out to the holding table
Using sqlBulkCopyLines As New SqlBulkCopy(connection)
sqlBulkCopyLines.DestinationTableName = "dbo.web_order_lines"
Try
sqlBulkCopyLines.WriteToServer(rs)
Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try
End Using

End If

End Using
End Using

Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try


However, what is actually happening is the first call to SqlBulkCopy is actually trying to write the seconf result set into the destination table, rather than the first.



Is there a way to achieve what I want without having to resort to iterating the lines from each dataset and writing them in one at a time??










share|improve this question




















  • 1





    Shouldn't you be passing dtHeader and dtLines as arguments to WriteToServer rather than rs?

    – jmcilhinney
    Nov 13 '18 at 12:03











  • Ok, note to self - check the overloads before posting on SO!!! All the examples I found just sent the SqlDataReader object as the parameter, not the DataTable!

    – Si Stone
    Nov 13 '18 at 12:15











  • Almost there now. However the above code (when I send a DataTable rather than the SqlDataReader) results in an empty second datatable. I assume this is because the Reader is sequential so doesn't actually know where the second result set starts... tried all kinds of different solutions without success... Any thoughts?

    – Si Stone
    Nov 13 '18 at 14:43











  • A data reader knows exactly where each result set starts. When you call NextResult it takes you directly to the start of the next result set. If you're not getting any data after that then I would suggest that your second result set is empty. Maybe you should do some actual testing and debugging rather than just reading code and looking at final results. Maybe you should try using a data adapter to fill a DataSet with the same query and see what you get that way. There's lots you can do to diagnose the issue.

    – jmcilhinney
    Nov 13 '18 at 22:19











  • Do you have your connection string setup to support multiple active result sets?

    – Chris Dunaway
    Nov 15 '18 at 19:34














0












0








0








I have a stored proc which returns two distinct sets of results (header and detail). I then want to take these result sets, and write them independently into two destination tables. The format of each result set is identical to the appropriate destination table, so SqlBulkCopy seemed like the ideal solution. Code is as follows:



Try
Using connection As SqlConnection = New SqlConnection(My.Settings.MyConnectionString)
Dim sqlQuery As String = "exec sp_get_order_batch @BatchSize, @NewBatchId"
connection.Open()

Using comm As SqlCommand = New SqlCommand(sqlQuery, connection)
comm.Parameters.Add("@BatchSize", SqlDbType.Int).Value = Me.Config.BatchSize
comm.Parameters.Add("@NewBatchId", SqlDbType.Int).Value = Me.Config.GetNewBatchNumber()

Dim rs As SqlDataReader = comm.ExecuteReader
Dim dtHeader As DataTable = New DataTable
dtHeader.Load(rs)

If dtHeader.Rows.Count >= 1 Then
'We've got some data back - yippee.

'Write the header data out to the holding table
Using sqlBulkCopyHeader As New SqlBulkCopy(connection)
sqlBulkCopyHeader.DestinationTableName = "dbo.web_order_header"
Try
sqlBulkCopyHeader.WriteToServer(rs)
Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try
End Using

'Grab the line data out as well...
rs.NextResult()
Dim dtLines As DataTable = New DataTable
dtLines.Load(rs)

'Write the line data out to the holding table
Using sqlBulkCopyLines As New SqlBulkCopy(connection)
sqlBulkCopyLines.DestinationTableName = "dbo.web_order_lines"
Try
sqlBulkCopyLines.WriteToServer(rs)
Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try
End Using

End If

End Using
End Using

Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try


However, what is actually happening is the first call to SqlBulkCopy is actually trying to write the seconf result set into the destination table, rather than the first.



Is there a way to achieve what I want without having to resort to iterating the lines from each dataset and writing them in one at a time??










share|improve this question
















I have a stored proc which returns two distinct sets of results (header and detail). I then want to take these result sets, and write them independently into two destination tables. The format of each result set is identical to the appropriate destination table, so SqlBulkCopy seemed like the ideal solution. Code is as follows:



Try
Using connection As SqlConnection = New SqlConnection(My.Settings.MyConnectionString)
Dim sqlQuery As String = "exec sp_get_order_batch @BatchSize, @NewBatchId"
connection.Open()

Using comm As SqlCommand = New SqlCommand(sqlQuery, connection)
comm.Parameters.Add("@BatchSize", SqlDbType.Int).Value = Me.Config.BatchSize
comm.Parameters.Add("@NewBatchId", SqlDbType.Int).Value = Me.Config.GetNewBatchNumber()

Dim rs As SqlDataReader = comm.ExecuteReader
Dim dtHeader As DataTable = New DataTable
dtHeader.Load(rs)

If dtHeader.Rows.Count >= 1 Then
'We've got some data back - yippee.

'Write the header data out to the holding table
Using sqlBulkCopyHeader As New SqlBulkCopy(connection)
sqlBulkCopyHeader.DestinationTableName = "dbo.web_order_header"
Try
sqlBulkCopyHeader.WriteToServer(rs)
Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try
End Using

'Grab the line data out as well...
rs.NextResult()
Dim dtLines As DataTable = New DataTable
dtLines.Load(rs)

'Write the line data out to the holding table
Using sqlBulkCopyLines As New SqlBulkCopy(connection)
sqlBulkCopyLines.DestinationTableName = "dbo.web_order_lines"
Try
sqlBulkCopyLines.WriteToServer(rs)
Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try
End Using

End If

End Using
End Using

Catch ex As Exception
Me.EventLog1.WriteEntry(ex.Message)
End Try


However, what is actually happening is the first call to SqlBulkCopy is actually trying to write the seconf result set into the destination table, rather than the first.



Is there a way to achieve what I want without having to resort to iterating the lines from each dataset and writing them in one at a time??







sql vb.net






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 12:00









jmcilhinney

25.4k21932




25.4k21932










asked Nov 13 '18 at 11:27









Si StoneSi Stone

5410




5410








  • 1





    Shouldn't you be passing dtHeader and dtLines as arguments to WriteToServer rather than rs?

    – jmcilhinney
    Nov 13 '18 at 12:03











  • Ok, note to self - check the overloads before posting on SO!!! All the examples I found just sent the SqlDataReader object as the parameter, not the DataTable!

    – Si Stone
    Nov 13 '18 at 12:15











  • Almost there now. However the above code (when I send a DataTable rather than the SqlDataReader) results in an empty second datatable. I assume this is because the Reader is sequential so doesn't actually know where the second result set starts... tried all kinds of different solutions without success... Any thoughts?

    – Si Stone
    Nov 13 '18 at 14:43











  • A data reader knows exactly where each result set starts. When you call NextResult it takes you directly to the start of the next result set. If you're not getting any data after that then I would suggest that your second result set is empty. Maybe you should do some actual testing and debugging rather than just reading code and looking at final results. Maybe you should try using a data adapter to fill a DataSet with the same query and see what you get that way. There's lots you can do to diagnose the issue.

    – jmcilhinney
    Nov 13 '18 at 22:19











  • Do you have your connection string setup to support multiple active result sets?

    – Chris Dunaway
    Nov 15 '18 at 19:34














  • 1





    Shouldn't you be passing dtHeader and dtLines as arguments to WriteToServer rather than rs?

    – jmcilhinney
    Nov 13 '18 at 12:03











  • Ok, note to self - check the overloads before posting on SO!!! All the examples I found just sent the SqlDataReader object as the parameter, not the DataTable!

    – Si Stone
    Nov 13 '18 at 12:15











  • Almost there now. However the above code (when I send a DataTable rather than the SqlDataReader) results in an empty second datatable. I assume this is because the Reader is sequential so doesn't actually know where the second result set starts... tried all kinds of different solutions without success... Any thoughts?

    – Si Stone
    Nov 13 '18 at 14:43











  • A data reader knows exactly where each result set starts. When you call NextResult it takes you directly to the start of the next result set. If you're not getting any data after that then I would suggest that your second result set is empty. Maybe you should do some actual testing and debugging rather than just reading code and looking at final results. Maybe you should try using a data adapter to fill a DataSet with the same query and see what you get that way. There's lots you can do to diagnose the issue.

    – jmcilhinney
    Nov 13 '18 at 22:19











  • Do you have your connection string setup to support multiple active result sets?

    – Chris Dunaway
    Nov 15 '18 at 19:34








1




1





Shouldn't you be passing dtHeader and dtLines as arguments to WriteToServer rather than rs?

– jmcilhinney
Nov 13 '18 at 12:03





Shouldn't you be passing dtHeader and dtLines as arguments to WriteToServer rather than rs?

– jmcilhinney
Nov 13 '18 at 12:03













Ok, note to self - check the overloads before posting on SO!!! All the examples I found just sent the SqlDataReader object as the parameter, not the DataTable!

– Si Stone
Nov 13 '18 at 12:15





Ok, note to self - check the overloads before posting on SO!!! All the examples I found just sent the SqlDataReader object as the parameter, not the DataTable!

– Si Stone
Nov 13 '18 at 12:15













Almost there now. However the above code (when I send a DataTable rather than the SqlDataReader) results in an empty second datatable. I assume this is because the Reader is sequential so doesn't actually know where the second result set starts... tried all kinds of different solutions without success... Any thoughts?

– Si Stone
Nov 13 '18 at 14:43





Almost there now. However the above code (when I send a DataTable rather than the SqlDataReader) results in an empty second datatable. I assume this is because the Reader is sequential so doesn't actually know where the second result set starts... tried all kinds of different solutions without success... Any thoughts?

– Si Stone
Nov 13 '18 at 14:43













A data reader knows exactly where each result set starts. When you call NextResult it takes you directly to the start of the next result set. If you're not getting any data after that then I would suggest that your second result set is empty. Maybe you should do some actual testing and debugging rather than just reading code and looking at final results. Maybe you should try using a data adapter to fill a DataSet with the same query and see what you get that way. There's lots you can do to diagnose the issue.

– jmcilhinney
Nov 13 '18 at 22:19





A data reader knows exactly where each result set starts. When you call NextResult it takes you directly to the start of the next result set. If you're not getting any data after that then I would suggest that your second result set is empty. Maybe you should do some actual testing and debugging rather than just reading code and looking at final results. Maybe you should try using a data adapter to fill a DataSet with the same query and see what you get that way. There's lots you can do to diagnose the issue.

– jmcilhinney
Nov 13 '18 at 22:19













Do you have your connection string setup to support multiple active result sets?

– Chris Dunaway
Nov 15 '18 at 19:34





Do you have your connection string setup to support multiple active result sets?

– Chris Dunaway
Nov 15 '18 at 19:34












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53280036%2fusing-sqlbulkcopy-to-copy-results-of-stored-proc-which-returns-multiple-datasets%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53280036%2fusing-sqlbulkcopy-to-copy-results-of-stored-proc-which-returns-multiple-datasets%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Bressuire

Vorschmack

Quarantine