Is there any way to retrieve inserted rows of a command - sql-server-2005

We probably all know SCOPE_IDENTITY() to retrieve the identity generated by a single insert. Currently I'm in the need of some kind of magic variable or function to retrieve all the rows generated by a statement, eg:
INSERT INTO [dbo].[myMagicTable]
(
[name]
)
SELECT [name]
FROM [dbo].[myMagicSource]
WHERE /* some weird where-clauses with several subselects ... */;
INSERT INTO [dbo].[myMagicBackupTable]
(
[id],
[name]
)
SELECT
[id],
[name]
FROM ???
An insert trigger is no option, as this will perform a single insert which is a problem for a batch of 10.000 rows...
So, is there any way to achieve this?
We are using mssql2005<

For SQL Server 2005+, you can use the OUTPUT clause.
DECLARE #InsertedIDs table(ID int);
INSERT INTO [dbo].[myMagicTable]
OUTPUT INSERTED.ID
INTO #InsertedIDs
SELECT ...

You could define a temporary table (possibly a table variable) and make use of the OUTPUT clause on your INSERT (you can make use of the Inserted pseudo-table, like in a trigger):
DECLARE #NewIDs TABLE (MagicID INT, Name VARCHAR(50))
INSERT INTO [dbo].[myMagicTable]([name])
OUTPUT Inserted.MagicID, Inserted.Name INTO #NewIDs(MagicID, Name)
SELECT [name]
FROM [dbo].[myMagicSource]
WHERE /
and then use that table variable after the INSERT:
INSERT INTO
[dbo].[myMagicBackupTable]([id], [name])
SELECT MagicID, [name]
FROM #NewIDs
and go from there.

Related

Using OUTPUT INTO with from_table_name in an INSERT statement [duplicate]

This question already has answers here:
Is it possible to for SQL Output clause to return a column not being inserted?
(2 answers)
Closed 2 years ago.
Microsoft's OUTPUT Clause documentation says that you are allowed to use from_table_name in the OUTPUT clause's column name.
There are two examples of this:
Using OUTPUT INTO with from_table_name in an UPDATE statement
Using OUTPUT INTO with from_table_name in a DELETE statement
Is it possible to also use it in an INSERT statement?
INSERT INTO T ( [Name] )
OUTPUT S.Code, inserted.Id INTO #TMP -- The multi-part identifier "S.Code" could not be bound.
SELECT [Name] FROM S;
Failing example using table variables
-- A table to insert into.
DECLARE #Item TABLE (
[Id] [int] IDENTITY(1,1),
[Name] varchar(100)
);
-- A table variable to store inserted Ids and related Codes
DECLARE #T TABLE (
Code varchar(10),
ItemId int
);
-- Insert some new items
WITH S ([Name], Code) AS (
SELECT 'First', 'foo'
UNION ALL SELECT 'Second', 'bar'
-- Etc.
)
INSERT INTO #Item ( [Name] )
OUTPUT S.Code, inserted.Id INTO #T -- The multi-part identifier "S.Code" could not be bound.
SELECT [Name] FROM S;
No, because an INSERT doesn't have a FROM; it has a set of values that are prepared either by the VALUES keyword, or from a query (and even though that query has a FROM, you should conceive that it's already been run and turned into a block of values by the time the insert is done; there is no s.code any more)
If you want to output something from the table that drove the insert you'll need to use a merge statement that never matches any records (so it's only inserting) instead, or perhaps insert all your data into #tmp and then insert from #tmp into the real table - #tmp will thus still be the record of rows that were inserted, it's just that it was created to drive the insert rather than as a consequence of it (caveats that it wouldn't contain calculated columns)

Insert data into the table from the finished procedure

How can I insert data into the table from the finished procedure, which was created using other scripts (data are on the rows in the results). This solutions was necessarily because I must concatenate coordinates.
One of the finishing step is:
select concat ('insert into table_shop ([IU], [ODD]) values ', data1)as PasteDat
from #tmp_07
In value data1 I have upload data.
When finished scripts I have result a lot of rows.
For example:
insert into table_shop ([IU], [ODD]) values ('A0001', 'D08')
insert into table_shop ([IU], [ODD]) values ('Agw44', 'D10')
insert into table_shop ([IU], [ODD]) values ('A5888', 'D18')
.
.
.
Now what I do is copying rows and paste on the other new query. Is there a more elegant way to do it in bulk?
Hope this helps
Use AdventureWorks2012
GO
Create Table #temp --table into which we need to insert
(
[DepartmentID] int,
[Name] varchar(50)
)
GO
Create PROCEDURE SP_ResultSet --SP which returns a result set
as
Select [DepartmentID]
,[Name]
from [HumanResources].[Department]
GO
Insert into #temp EXEC SP_ResultSet -- serves the purpose
GO
Select * from #temp order by [DepartmentID]

sql query to create a table at runtime and insert the values in it from the select statement from the database

what i am tryin to do is make a table(#tbl) runtime and insert the data from the select statement from the database,as what i have done so far is
declare #tbl TABLE (
Item int
)
begin
insert into #tbl values select cid from tbl_custumer where cus_ph like '%'+'987'+'%'
select * from #tbl
end
as "select cid" statement returns multiple records
I think you might want the code to look like this:
begin
declare #tbl TABLE (
Item int
);
insert into #tbl(Item)
select cid
from tbl_custumer
where cus_ph like '%'+'987'+'%';
select *
from #tbl;
end;
Notes:
The begin/end block is not really necessary, but I'm guessing you want it for other reasons (a stored procedure, if, or something similar).
The values keyword is not needed when using insert . . . select.
Use semicolons at the end of each SQL statement. Although they are optional, they make the code easier to follow.

Inserting "bad" data into a SQL database?

I'm writing a query that inserts customer data into a MSSQL database. Very basic.
Unfortunately, I ran into a problem when trying to do the following:
INSERT INTO USERS(newid(),'BOB''S SELECT MARKETING')
I made sure to escape my quotes, but the server is still seeing SELECT as a reserved keyword. I don't want to have to wrap a bunch of reserved words in brackets. Is there a cleaner way of getting my data in the database intact and not mangled by brackets?
I appreciate your help.
Thank you!
You are missing the Key word VALUES:
INSERT INTO USERS VALUES (NEWID(),'BOB''S SELECT MARKETING');
You have several choices of syntax here. Using the one in your code sample, you forgot the VALUES keyword. For example:
declare #users table
(
id uniqueidentifier,
name varchar(50)
)
insert into #users values (newid(), 'BOB''S SELECT MARKETING')
You can also use the insert into / select statement like below if you are inserting a value into each one of the table's columns:
declare #users table
(
id uniqueidentifier,
name varchar(50)
)
insert into #users
select newid(), 'BOB''S SELECT MARKETING'
Or you can use the insert into / select statement and specify the columns you are inserting:
declare #users table
(
id uniqueidentifier,
name varchar(50)
)
insert into #users (id, name)
select newid(), 'BOB''S SELECT MARKETING'

How do I return a new IDENTITY column value from an SQLServer SELECT statement?

I'm inserting into an SQLServer table with an autoincrementing key field. (I believe this is called an IDENTITY column in SQLServer.)
In Oracle, I can use the RETURNING keyword to give my INSERT statement a results set like a SELECT query that will return the generated value:
INSERT INTO table
(foreign_key1, value)
VALUES
(9, 'text')
RETURNING key_field INTO :var;
How do I accomplish this in SQLServer?
Bonus: Okay, nice answers so far, but how do I put it into a single statement, if possible? :)
In general, it can't be done in a single statement.
But the SELECT SCOPE_IDENTITY() can (and should) be placed directly after the INSERT statement, so it's all done in the same database call.
Example:
mydb.ExecuteSql("INSERT INTO table(foreign_key1, value) VALUES(9, 'text'); SELECT SCOPE_IDENTITY();");
You can use OUTPUT, but it has some limitations you should be aware of:
http://msdn.microsoft.com/en-us/library/ms177564.aspx
SELECT SCOPE_IDENTITY()
Edit: Having a play...
If only the OUTPUT clause supported local variables.
Anyway, to get a range of IDs rather than a singleton
DECLARE #Mytable TABLE (keycol int IDENTITY (1, 1), valuecol varchar(50))
INSERT #Mytable (valuecol)
OUTPUT Inserted.keycol
SELECT 'harry'
UNION ALL
SELECT 'dick'
UNION ALL
SELECT 'tom'
Edit 2: In one call. I've never had occasion to use this construct.
DECLARE #Mytable TABLE (keycol int IDENTITY (1, 1), valuecol varchar(50))
INSERT #Mytable (valuecol)
OUTPUT Inserted.keycol
VALUES('foobar')
In addition to ##IDENTITY, you should also look into SCOPE_IDENTITY() and IDENT_CURRENT(). You most likely want SCOPE_IDENTITY(). ##IDENTITY has a problem in that it might return an identity value created in a trigger on the actual table that you're trying to track.
Also, these are single-value functions. I don't know how the Oracle RETURNING keyword works.
SCOPE_IDENTITY
It depends on your calling context.
If you're calling this from client code, you can use OUTPUT and then read the value returned.
DECLARE #t TABLE (ColID int IDENTITY, ColStr varchar(20))
INSERT INTO #t (ColStr)
OUTPUT Inserted.ColID
VALUES ('Hello World')
Result:
ColID
-----------
1
If you're wrapping this in a stored procedure, using OUTPUT is more work. There, you'll want to use SCOPE_IDENTITY(), but you can't do it in a single statement. Sure, you can put multiple statements on a single line with a ';' separator, but that's not a single statement.
DECLARE #idValue int
DECLARE #t TABLE (ColID int IDENTITY, ColStr varchar(20))
INSERT INTO #t (ColStr) VALUES ('Hello World')
SELECT #idValue = SCOPE_IDENTITY()
Result: #idValue variable contains identity value. Use an OUTPUT parameter to return the value.
You can use OUTPUT INTO, which has the additional benefits of being able to capture multiple identities inserted.
INSERT INTO table(foreign_key1, value)VALUES(9, 'text');SELECT ##IDENTITY;