Use INSERT w/OUTPUT Instead of INSERT+SELECT
See original GitHub issueEntity Framework Core’s SQL Server provider (at least, as of v. 1.1.0) follows each INSERT statement with a SELECT statement that fetches database-generated values and verifies the inserted row count.
Proposal
Eliminate the SELECT statement. Instead:
- Fetch database-generated values using an OUTPUT clause on the INSERT statement.
- Rely on the database provider to throw an exception of the INSERT fails instead of verifying inserted row count (looks like was supposed to have been implemented per #2131).
Examples
Currently (EF Core 1.1.0)
-- Table w/identity column:
SET NOCOUNT ON;
INSERT INTO [TestTable1] ([Data])
VALUES (@p0);
SELECT [Id]
FROM [TestTable1]
WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
-- Table w/identity and default value (`DEFAULT(GETDATE())`) columns:
SET NOCOUNT ON;
INSERT INTO [TestTable2] ([Data])
VALUES (@p0);
SELECT [Id], [HasDefaultValue]
FROM [TestTable2]
WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
Proposed Simplification
-- Table w/identity column:
SET NOCOUNT ON;
INSERT INTO [TestTable1] ([Data])
OUTPUT INSERTED.[Id]
VALUES (@p0);
-- Table w/identity and default value (`DEFAULT(GETDATE())`) columns:
SET NOCOUNT ON;
INSERT INTO [TestTable2] ([Data])
OUTPUT INSERTED.[Id], INSERTED.[HasDefaultValue]
VALUES (@p0);
Example Code
Further technical details
EF Core version: 1.1.0 Operating system: Windows 10 Visual Studio version: VS 2015
Issue Analytics
- State:
- Created 7 years ago
- Comments:11 (7 by maintainers)
Top Results From Across the Web
INSERT INTO with SELECT using OUTPUT
I want to store the pt_id into my temporary table by using OUTPUT , however I'm not inserting pt_id into ct_tarf , what...
Read more >OUTPUT clause (Transact-SQL) - SQL Server
Returns information from, or expressions based on, each row affected by an INSERT, UPDATE, DELETE, or MERGE statement.
Read more >Using source columns in OUTPUT INTO clause of an ...
I am writing a batch processing insert statement and would like to use a temp table to keep track of inserted ID's instead...
Read more >How to Insert Rows and Get Their Identity Values with the ...
Instead, use the OUTPUT clause. SELECT * FROM #RowsInserted; The OUTPUT clause is kinda like the virtual INSERTED/DELETED tables: it lets you ...
Read more >The OUTPUT Clause for INSERT and DELETE Statements
Using the OUTPUT clause, we can display the rows inserted into a table in the output window by selecting the column names with...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I am getting heavy deadlocking issues from the 2 step approach, and this is when I am only doing 2 simultaneous inserts into a table. If EF were using the output clause to get the identity, instead of a separate query, I do not think I would have the deadlock issues. Would it make sense to add an option for developers to choose how the insert is handled for folks that are not concerned about triggers?
@roji Be careful out there: https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/