How to use more than one table with OUTPUT clause? [duplicate] - sql

This question already has an answer here:
Insert Into... Merge... Select (SQL Server)
(1 answer)
Closed 6 years ago.
Is it possible to insert columns of different tables in the OUTPUT clause of an INSERT statement, such as:
DECLARE #insertedrecords TABLE (Id int, [Guid] uniqueidentifier);
INSERT INTO mytable
(column names here...)
OUTPUT inserted.id_no, b.[Guid] INTO #insertedrecords
SELECT
column names here...
FROM #myTVP b
Currently, using the above I get the following error:
The multi-part identifier "b.Guid" could not be bound.

Inserted special table will hold the records those are inserted into the Target table not all the data from Source table. When a column from target table is not part of Insert list then in OUTPUT clause it will be NULL
So you need two different Inserts
DECLARE #insertedrecords TABLE (Id int, [Guid] uniqueidentifier);
INSERT INTO mytable
(column names here...)
SELECT
column names here...
FROM #myTVP b
Insert into #insertedrecords(Id,Guid)
select id_no, [Guid]
From #myTVP

Related

Output clause insert result into temp table along with source id value [duplicate]

This question already has answers here:
Using merge..output to get mapping between source.id and target.id
(3 answers)
Closed last month.
I have a table called TreeItemOption.
I need to insert new rows into TreeItemOption table from a temp table and save the mapped values in a different temp table
INSERT INTO ProductSetup.TreeItemOption (TreeItemHeaderId)
OUTPUT INSERTED.TreeItemOptionId, TI.TreeItemOptionId INTO #NewTreeItemOptionIds
SELECT NTI.NewTreeItemHeaderId
FROM #TTreeItem TI
INNER JOIN #NewTreeItemHeaderIds NTI ON NTI.TreeItemHeaderId = TI.TreeItemHeaderId;
I have a #NewTreeItemHeaderIds table from that table I'm inserting the new TreeItemHeaderId into TreeItemOption table and I'm trying output the newly inserted TreeItemOptionId as well as old TreeItemOptionId from TTreeItem table
But I'm getting the error
The multi-part identifier "TI.TreeItemOptionId" could not be bound
In conventional insert and update commands only Magic tables can only be used in the output clause. Try a merge statement instead if you want the value from your source table to also be mapped.
Something like this:
MERGE DestinationTable DEST
USING SourceTable SRC
ON DEST.ID = SRC.ID
WHEN NOT MATCHED THEN
INSERT
(
DestinationColumnName
)
VALUES
(
SRC.SourceColumnName
)OUTPUT inserted.ID,SRC.SOurceID INTO #MyTemp;
One the above has been executed you'll have the records in the Temp table #MyTemp with the SourceID and the respective DestinationID mapped

SQL Server Insert Into Table containing a column "Timestamp (Rowversion)"

I'm creating a C# Winforms application for recipe management in an industrial environment.
I created a SQL Server table with 130 columns. The table contains a column called CheckData (of datatype Timestamp), which I use to detect changes made to a row.
If I insert a new row to that table all works fine. The code I use is:
INSERT INTO tablename (Column1, column2, column3, column4)
VALUES (value1, value2, value3, value4)
I just assign values to major columns, the others get their default value. I do not assign a value to the timestamp field since it's written by the system.
Additionally, I want to copy a row from this table to the same table (duplicate a data record).
I copy the source row to a temporary table, drop the ID (primary key) and the timestamp fields in that temporary table and try to insert that only row in the temporary table into the table. This fails.
Here's the code:
SELECT *
INTO #temptable
FROM tablename
WHERE Recipe_No = 8;
ALTER TABLE #temptable DROP COLUMN ID, CHECKDATA;
ALTER TABLE #temptable REBUILD;
UPDATE #temptable
SET Recipe_No = 9, Recipe_Name = 'Test'
WHERE Recipe_No = 8;
INSERT INTO tablename
SELECT * FROM #temptable;
I don't understand where the difference is between inserting a new row thru INSERT INTO xxx (yyy) VALUES (zzz) and INSERT INTO xxx SELECT * FROM yyy. In both cases I don't try to write the timestamp value in the new row.
Does anybody have an idea what I'm missing here?
I don't understand where the difference is between inserting a new row thru INSERT INTO xxx (yyy) VALUES (zzz) and INSERT INTO xxx SELECT * FROM yyy.
With this,
INSERT INTO xxx SELECT * FROM yyy.
you are failing to specify the column mappings from the SELECT to the target table. You should always use
INSERT INTO xxx (Column1, Column2, . . .)
SELECT (Column1, Column2, . . .)
FROM yyy
Here's a simplified example of what you're attempting:
drop table if exists t
create table t(id int, a int)
insert into t(id,a) values (1,1)
select * into #t from t where id = 1
alter table #t drop column id
insert into t select * from #t
and it will fail with
Msg 213, Level 16, State 1, Line 12
Column name or number of supplied values does not match table definition.
because the temp table doesn't even have the same number of columns. And even if it did, you wouldn't know for sure that the column mappings were correct.
It is failing because essentially your command
INSERT INTO tablename SELECT * FROM #temptable;";
Is telling SQL - "Insert everything into this table from this temp table."
While you can work around this, I would say why don't you just try inserting into only the columns made available in your current table with only the values you would like to include. Instead of needing to drop the columns/values, you just don't import it to begin with.
An alternative - if you can write to a helper table, it may be beneficial to INSERT INTO that helper table, as opposed to a temp table, the values you have. Then transform that helper table, and THEN you can do INSERT INTO final_table SELECT * FROM helper. This should give you the results you're looking for.
I hope this is helpful, and I hope it explains why your current command is failing.

SQL Server: Insert INTO Statement syntax [duplicate]

This question already has answers here:
Why are dot-separated prefixes ignored in the column list for INSERT statements?
(3 answers)
Closed 8 years ago.
Why does not the following INSERT statement give any error?
CREATE TABLE Table1(id INT,name VARCHAR(10))
INSERT INTO Table1(xx.id,yyyy.name) Values (1,'A')
Why does the above statement ignore xx. and yyyy.? What does this imply ?
I checked the below query also.
INSERT INTO Table11(xx.xx.xx.xx.xx.xx.xx.id,yy.yy.yy.yy.yy.yy.yy.yy.name)
Values (1,'A')
It also got worked. Usually we use alias for joins. As I know, For Insert query Using alias near table name is restricted in sql. In the case of column name, the query use only the string next to the last Dot(.).
I conclude it as, The Insert query don't care about the string prefixed to the column name separated by Dot(.).
The only thing I can think of is that the database engine is ignoring the name space as the query's scope is limited to the Table's scope when dealing with INSERT INTO. When it comes to say UPDATE where multiple tables can be part of the scope, the below would fail. Don't know why this happens but if I were to guess, probably all values to the left of the last period'.' is ignored
If you analyze the execution plan for the below query
CREATE TABLE Table1(id INT,name VARCHAR(10))
INSERT INTO Table1(Table2.dbo.id,...................name) Values (1,'A')
AS
INSERT INTO [Table1]([id],[name]) Values(#1,#2)
This implies the namespace of something...
For example:
SELECT object.id, object.name FROM table object WHERE object.name = 'Foo';
/ \
| |
object is the name space for the table.
And if you haven't a namespace created the query fails.
As far as I know, the syntax you are using generally means table.column
So in other words you are trying to insert into Table1 but declaring columns from other tables.
You should do something like this
CREATE TABLE Table1(id INT,name VARCHAR(10))
INSERT INTO Table1(id,name) Values (1,'A')

Insert Multiple Rows into Table from a Table

I have a SQL Server 2008 database. The database has a stored procedure which receives two strings as parameters. One parameter is used to build a temp table which will usually only have 1 or 2 rows but theoretically could have more.
For each row in the temp table, I need to insert a row into a different table that consists of the other parameter and the contents of the temp table. Is there a way to do this without a cursor?
I've tried variations on the following:
Pseudo code:
procedure InsertLinks(#Key varchar(36), #LinkKey varchar(36)
tempLinks Table = getLinks(#LinkKey)
Insert into MyTable (Key, LinksTo) Values (#Key, Select LinksTo From tempLinks)
The VALUES clause is messed up - you have a single value comma a table. That's not valid.
The following should work just fine:
INSERT INTO MyTable (Key, LinksTo)
SELECT #Key, LinksTo
FROM tempLinks

what is the difference between insert statement with into and without into?

I have created table #temp with columns id as int identity(1,1) and name as varchar.
Say suppose I am writing the following 2 different statements for inserting rows:
insert into #temp (name) select ('Vikrant') ;
insert #temp (name) select ('Vikrant')
I want to ask what is the difference between these two types of insert statements?
Is there really any difference in between these insertions?
From the MSDN documentation:
[INTO]
Is an optional keyword that can be used between INSERT and the target table.
There is no difference between the two statements.