Selecting top 10 data from one table and inserting into other table - sql

PSeudo Code:
Create Procedure SP_GetAllData
(#Count,#EmailID)
Create table #tempTable
(
Id Int Not Null Identity (1,1)
Message nvarchar (max)
)
Insert into SecondTable
(EmailID,Message,Subject,MessageID,)
(#EmailID,'Select Message from #tempTable','Message Subjest','Select ID from #tempTable')
How to insert the data into temptable and then into second table?
Here in the above statement i want to insert both the records from FirstTable into SecondTable along with its existing columns

I think this is something what you need, you do not need a temp table for this operation anyway, but you do need to order by some column otherwise TOP Clause without an ORDER BY is pretty meaningless.
Create Procedure SP_GetAllData
#Count INT
,#EmailID INT
AS
BEGIN
SET NOCOUNT ON;
Insert into SecondTable (EmailID,[Message], [Subject] ,MessageID)
Select top (#Count) #EmailID,[Message], [Subject] ,ID
from FirstTable
-- ORDER BY SomeColumn
END

Related

How to return NULL for Identity when no INSERT is performed

I have two tables
CREATE TABLE Temp_1
(
ID Int IDENTITY(1,1),
Name Varchar(500)
)
CREATE TABLE Temp_2
(
ID Int IDENTITY(1,1),
Name Varchar(500)
)
INSERT INTO Temp_1
SELECT 'CC'
INSERT INTO Temp_2
SELECT Name
FROM Temp_1
WHERE 2 = 1
There is no insertion into the table Temp_2.So my expected output for the SCOPE_IDENTITY () for the table Temp_2 is NULL.
How can i get the Identity Value of the Temp_2 as null?
If we use the SCOPE_IDENTITY() OR ##IDENTITY, the identity value we are getting is only of the table Temp_1. We need to get the identity value of table Temp_2 which is "null" as there is no insertion in the table Temp_2 .
Neither. You want to use the output clause:
DECLARE #ids TABLE (id INT);
INSERT INTO Temp_1
OUTPUT inserted.id INTO #ids
SELECT 'CC' ;
This is session-safe, statement-safe, multi-threaded safe. And it allows you to handle multiple row inserts. And it allows you to return additional columns.
There is no reason to use any other method.

Handling bulk insert on a table with multiple input sources in SQL

I am performing bulk insert on a table in sql server 2012, at the same time i am picking the last inserted row with max() function and inserting it into another table , how to perform this when my table is getting data from multiple sources because while performing insertion into secondary table there is time delay while insertions are still happening in primary table so next time max() will pick up last updated row and i will loose some rows which are not max() but still inserted into primary table meanwhile.
create table dbo.emp
(
id int primary key identity(1,1),
emp_id int,
name varchar(255),
address varchar(255)
)
create table dbo.empx
(
id int primary key,
emp_id int foreign key references dbo.emp(id),
)
declare #temp int ;
set #temp=1;
while #temp<1000
begin
insert into dbo.emp(emp_id,name,address)values (100+#temp,'Ename'+LTRIM(STR(#temp)),'123 Sample Address'+LTRIM(STR(#temp)));
set #temp=#temp+1;
insert into dbo.empx select max(dbo.emp.id),max(dbo.emp.emp_id) from dbo.emp
end
Use OUTPUT Clause...
CREATE TABLE #empx
(Id INT ,emp_id VARCHAR(50))
DECLARE #temp INT ;
SET #temp=1;
WHILE #temp<1000
BEGIN
INSERT INTO dbo.emp(emp_id,name,address)
OUTPUT INSERTED.Id,INSERTED.emp_id INTO #empx(Id,emp_id)
VALUES (100+#temp,'Ename'+LTRIM(STR(#temp)),'123 Sample Address'+LTRIM(STR(#temp)));
SET #temp=#temp+1;
END
INSERT INTO dbo.empx(Id,emp_id)
SELECT Id,emp_id FROM #empx
Or Use a trigger
CREATE TRIGGER EmpLog
ON dbo.emp
AFTER Insert
AS
BEGIN
SET NOCOUNT ON;
Insert into dbo.empx (id,emp_id) Select id,emp_id from inserted;
END
GO

For each inserted row create row in other table with foreign key constrain

I have 2 tables with foreign key constraint:
Table A:
[id] int identity(1, 1) PK,
[b_id] INT
and
Table B:
[id] int identity(1, 1) PK
where [b_id] refers to [id] column of Table B.
The task is:
On each insert into table A, and new record into table B and update [b_id].
Sql Server 2008 r2 is used.
Any help is appreciated.
Having misread this the first time, I am posting a totally different answer.
First if table B is the parent table, you insert into it first. Then you grab the id value and insert into table A.
It is best to do this is one transaction. Depending on what the other fields are, you can populate table A with a trigger from table B or you might need to write straight SQL code or a stored procedure to do the work.
It would be easier to describe what to do if you have a table schema for both tables. However, assuming table B only has one column and table A only has ID and B_id, this is the way the code could work (you would want to add explicit transactions for production code). The example is for a single record insert which would not happen from a trigger. Triggers should always handle multiple record inserts and it would have to be written differently then. But without knowing what the columns in the tables are it is hard to provide a good example of this.
create table #temp (id int identity)
create table #temp2 (Id int identity, b_id int)
declare #b_id int
insert into #temp default values
select #B_id = scope_identity()
insert into #temp2 (B_id)
values(#B_id)
select * from #temp2
Now the problem gets more complex if there are other columns, as you would have to provide values for them as well.
Without removing identity specification you can use the following option:
SET IDENTITY_INSERT B ON
Try this:
CREATE TRIGGER trgAfterInsert ON [dbo].[A]
FOR INSERT
AS
IF ##ROWCOUNT = 0 RETURN;
SET NOCOUNT ON;
SET IDENTITY_INSERT B ON
DECLARE #B_Id INT
SELECT #B_Id = ISNULL(MAX(Id), 0) FROM B;
WITH RES (ID, BIDS)
AS
(SELECT Id, #B_Id + ROW_NUMBER() OVER (ORDER BY Id) FROM INSERTED)
UPDATE A SET [b_Id] = BIDS
FROM A
INNER JOIN RES ON A.ID = RES.ID
INSERT INTO B (Id)
SELECT #B_Id + ROW_NUMBER() OVER (ORDER BY Id) FROM INSERTED
SET IDENTITY_INSERT B OFF
GO
Though Nadeem's answer is on the right track, his trigger for some reason takes max.id instead of NEW.id and doesn't update A accordingly.
For what you ask to be usable by trigger, you need the FK in table A to be nulleable, else you have a race condition between the tables.
EDIT: As SpectralGhost pointed out, my original code didn't support multiple rows, this one will do:
CREATE TRIGGER trgAfterInsertA ON TableA
FOR INSERT
AS
DECLARE db_cursor CURSOR FOR
SELECT id FROM INSERTED
DECLARE #an_id int
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #an_id
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO TableB VALUES(VALUE_PLACEHOLDER)
UPDATE TableA
SET b_id = SCOPE_IDENTITY()
WHERE id = #an_id
FETCH NEXT FROM db_cursor INTO #an_id
END
GO
The VALUE_PLACEHOLDER are the values you initialize TableB with.

INSERT ONLY SPECIFIC COLUMN FROM A STORED PROCEDURE RESULT

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

insert data into several tables

Let us say I have a table (everything is very much simplified):
create table OriginalData (
ItemName NVARCHAR(255) not null
)
And I would like to insert its data (set based!) into two tables which model inheritance
create table Statements (
Id int IDENTITY NOT NULL,
ProposalDateTime DATETIME null
)
create table Items (
StatementFk INT not null,
ItemName NVARCHAR(255) null,
primary key (StatementFk)
)
Statements is the parent table and Items is the child table. I have no problem doing this with one row which involves the use of IDENT_CURRENT but I have no idea how to do this set based (i.e. enter several rows into both tables).
Thanks.
Best wishes,
Christian
Another possible method that would prevent the use of cursors, which is generally not a best practice for SQL, is listed below... It uses the OUTPUT clause to capture the insert results from the one table to be used in the insert to the second table.
Note this example makes one assumption in the fact that I moved your IDENTITY column to the Items table. I believe that would be acceptable, atleast based on your original table layout, since the primary key of that table is the StatementFK column.
Note this example code was tested via SQL 2005...
IF OBJECT_ID('tempdb..#OriginalData') IS NOT NULL
DROP TABLE #OriginalData
IF OBJECT_ID('tempdb..#Statements') IS NOT NULL
DROP TABLE #Statements
IF OBJECT_ID('tempdb..#Items') IS NOT NULL
DROP TABLE #Items
create table #OriginalData
( ItemName NVARCHAR(255) not null )
create table #Statements
( Id int NOT NULL,
ProposalDateTime DATETIME null )
create table #Items
( StatementFk INT IDENTITY not null,
ItemName NVARCHAR(255) null,
primary key (StatementFk) )
INSERT INTO #OriginalData
( ItemName )
SELECT 'Shirt'
UNION ALL SELECT 'Pants'
UNION ALL SELECT 'Socks'
UNION ALL SELECT 'Shoes'
UNION ALL SELECT 'Hat'
DECLARE #myTableVar table
( StatementFk int,
ItemName nvarchar(255) )
INSERT INTO #Items
( ItemName )
OUTPUT INSERTED.StatementFk, INSERTED.ItemName
INTO #myTableVar
SELECT ItemName
FROM #OriginalData
INSERT INTO #Statements
( ID, ProposalDateTime )
SELECT
StatementFK, getdate()
FROM #myTableVar
You will need to write an ETL process to do this. You may want to look into SSIS.
This also can be done with t-sql and possibly temp tables. You may need to store unique key from OriginalTable in Statements table and then when you are inserting Items - join OriginalTable with Statements on that unique key to get the ID.
I don't think you could do it in one chunk but you could certainly do it with a cursor loop
DECLARE #bla char(10)
DECLARE #ID int
DECLARE c1 CURSOR
FOR
SELECT bla
FROM OriginalData
OPEN c1
FETCH NEXT FROM c1
INTO #bla
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO Statements(ProposalDateTime) VALUES('SomeDate')
SET #ID = SCOPE_IDENTITY()
INSERT INTO Items(StateMentFK,ItemNAme) VALUES(#ID,#bla)
FETCH NEXT FROM c1
INTO #bla
END
CLOSE c1
DEALLOCATE c1