I have one issue, I'm not too sure is it possible by anyway or not.
suppose-
I have a physical table with 4 columns but I have to insert data into it from temp tables with 1000's of records but with less column (i.e. 2 columns) Is it possible by anyway.
I have added a temporary script to describe my problem-
create table A (id int,sal int,name varchar(50),data varchar(50))
create table #B (id int,sal int)
insert into #B values(1,10)
insert into #B values(2,20)
insert into #B values(3,30)
insert into #B values(4,40)
---This will Not work
insert into A select * from #B
Is there any other way we can do this, I have added just a scenario but i have a lot of columns in my physical table
create table A (id int,sal int,name varchar(50),data varchar(50))
create table #B (id int,sal int)
insert into #B values(1,10)
insert into #B values(2,20)
insert into #B values(3,30)
insert into #B values(4,40)
-This will work
insert into A select *,null,null from #B
-- or
insert into A (id,sal) select * from #B
How about specifying the columns during insert i.e.
insert into A(id,sal) select * from #B
Related
Having the following procedure:
CREATE PROCEDURE [dbo].[Gest_Doc_SampleProc]
#Nome nvarchar(255),
#Descritivo nvarchar(255),
#SampleTable AS dbo.IDList READONLY
AS
DECLARE #foo int;
SELECT #foo=a.bar FROM TableA a WHERE a.Nome=#Nome
IF NOT EXISTS (SELECT a.bar FROM TableA a WHERE a.Nome=#Nome)
BEGIN
INSERT INTO TableA VALUES (#Nome,#Descritivo)
INSERT INTO TableB VALUES (scope_identity(),#SampleTable)
END
I am trying, as shown, inserting into TableB all the values of SampleTable, together with the scope_identity.
SampleTable is as:
CREATE TYPE dbo.SampleTable
AS TABLE
(
ID INT
);
GO
How can I correctly achieve this?
The right way to do this type of work is the OUTPUT clause. Although technically not needed for a single row insert, you might as well learn how to do it correctly. And even what looks like a single row insert can have an insert trigger that does unexpected things.
PROCEDURE [dbo].[Gest_Doc_SampleProc] (
#Nome nvarchar(255),
#Descritivo nvarchar(255),
#SampleTable AS dbo.IDList
) READONLY AS
BEGIN
DECLARE #ids TABLE (id int);
DECLARE #foo int;
SELECT #foo = a.bar
FROM TableA a
WHERE a.Nome = #Nome;
IF NOT EXISTS (SELECT 1 FROM TableA a WHERE a.Nome = #Nome)
BEGIN
INSERT INTO TableA (Nome, Descritive)
OUTPUT Inserted.id -- or whatever the id is called
INTO #ids;
VALUES (#Nome,#Descritivo)
INSERT INTO TableB (id, sampletable)
SELECT id, #SampleTable
FROM #ids;
END;
END; -- Gest_Doc_SampleProc
In addition to using OUTPUT, this code also adds column lists to the INSERTs. That is another best practice.
For table1 Inserted 3 records
It should get those three identities and it should insert 3 records in table3 (but it’s not happening- it inserts 3 records with same identity ie.last scope identity)
create table table1(ID INT identity(1,1),Name varchar(50))
insert into table1 values('Ram'),('Sitha'),('Laxman')
create table table1(ID INT identity(1,1),Name varchar(50))
create table table3(ID INT ,Name varchar(50))
insert into table2(Name)
select Name from table1
declare #id int;
set #id= (select scope_Identity())
begin
insert into table3(ID,Name)
select #id,Name from table2
end
select * from table2
select * from table3
How can get all identities to insert do I need to write a loop (or) do I need to Create a trigger.
Please give me a solution I am strugguling from past 4 hours.
Thanks in anvance
Use the OUTPUT clause to handle multi-row inserts:
INSERT INTO dbo.table2(Name)
OUTPUT inserted.ID, inserted.Name INTO table3
SELECT Name FROM dbo.table1;
You can use the OUTPUT clause to get the identity from any number of inserts.
create table table1(ID INT identity(1,1),Name varchar(50))
DECLARE #T1 Table (ID int, name varchar(50))
insert into table1
OUTPUT inserted.ID, Inserted.Name INTO #T1
values('Ram'),('Sitha'),('Laxman')
DECLARE #IdentityId INT,#Count INT=1
DECLARE #temp AS TABLE (Id INT IDENTITY ,Name NVARCHAR(100))
INSERT INTO #temp(Name)
SELECT Name FROM table1
WHILE #Count <=(SELECT COUNT(SId) FROM #temp)
BEGIN
INSERT INTO table2(Name)
SELECT Name FROM #temp
WHERE Id=#Count
SET #IdentityId = SCOPE_IDENTITY()
INSERT INTO tabel3(#IdentityId,Name)
SELECT 3, #IdentityId,1,GETDATE()
SET #Count=#Count+1
END
I have this SQL Server query with a cursor:
DECLARE #ids TABLE(id varchar(50))
INSERT INTO #ids VALUES ('1098264', '1098859', '1098860', '1098267', '1098265')
But when I run the code, I get an error:
Insert Error: Column name or number of supplied values does not match table definition.
You have only one column in table i.e id and you are trying to insert 5 column values in table.
Try this
Create table :
DECLARE #ids TABLE(id varchar(50))
Insert values to table :
INSERT INTO #ids VALUES ('1098264')
INSERT INTO #ids VALUES ('1098859')
INSERT INTO #ids VALUES ('1098860')
INSERT INTO #ids VALUES ('1098267')
INSERT INTO #ids VALUES ('1098265')
You need to use a pair of bracket for each row like below:
INSERT INTO #ids VALUES ('1098264'),('1098859'),('1098860'),('1098267'),('1098265')
There are three ways of inserting multiple rows into a table (other than via a select statement)
INSERT INTO FOO (columna,columnb)
VALUES (1,a)
INSERT INTO FOO (columna,columnb)
VALUES (2,b)
INSERT INTO FOO (columna,columnb)
VALUES (3,c)
The second
INSERT INTO FOO (columna,columnb)
select 1,'a'
UNION ALL
select 2,'b'
UNION ALL
select 3,'c'
Thirdly (only works SQLServer 2008 and up)
INSERT INTO FOO (columna,columnb)
VALUES (1,'a'),(2,'b'),(3,'c')
In the example in your question, you were trying to insert multiple fields into one column, which is why you got the error.
You have only 1 column in the table but are trying to insert 5 values.
First declare 5 different columns in the table to hold 5 values
For Example:-
declare #IDS_1 varchar(50)
,#IDS_2 varchar(50)
,#IDS_3 varchar(50)
,#IDS_4 varchar(50)
,#IDS_5 varchar(50)
INSERT INTO #IDS VALUES ('1098264'
,'1098859'
,'1098860'
,'1098267'
,'1098265')
I want to know if it is possible to insert to a table from a specific column of result from a stored procedure?
Something like:
declare #temp as table(
id int
)
insert #temp
exec getlistofStudents --returns multiple columns
this is an example only, Thanks for the help..
You can take a 2 step approach. First INSERT INTO a #TempTable, then populate the #TempVariable with another INSERT INTO, selecting the single column.
DECLARE #temp AS TABLE
(
ID int
);
CREATE TABLE #tempTable1
(
Column1 int,
Column2 int
);
INSERT INTO #tempTable1
Exec getlistofStudents
INSERT INTO #temp
SELECT Column1 FROM #tempTable1
I would like to INSERT multpile rows (using INSERT SELECT), and OUTPUT all the new and old IDs into a "mapping" table.
How can I get the original ID (or any source values) in the OUTPUT clause? I don't see a way to get any source values there.
Here is a minimal code example:
-- create some test data
declare #t table (id int identity, name nvarchar(max))
insert #t ([name]) values ('item 1')
insert #t ([name]) values ('another item')
-- duplicate items, storing a mapping from src ID => dest ID
declare #mapping table (srcid int, [newid] int)
insert #t ([name])
output ?????, inserted.id into #mapping-- I want to use source.ID but it's unavailable here.
select [name] from #t as source
-- show results
select * from #t
select * from #mapping
My actual scenario is more complex, so for example I cannot create a temp column on the data table in order to store a "original ID" temporarily, and I cannot uniquely identify items by anything other than the 'ID' column.
Interesting question. For your example, a possible cheat is to depend on the fact that you are doubling the number of rows. Assuming that rows are never deleted and the [id] column remains dense:
-- create some test data
declare #t table (id int identity, name nvarchar(max))
insert #t ([name]) values ('item 1')
insert #t ([name]) values ('another item')
-- duplicate items, storing a mapping from src ID => dest ID
declare #mapping table (srcid int, [newid] int)
declare #Rows as Int = ( select Count(42) from #t )
insert #t ([name])
output inserted.id - #Rows, inserted.id into #mapping
select [name] from #t as source order by source.id -- Note 'order by' clause.
-- show results
select * from #t
select * from #mapping