Sql batch insert - sql-server

I have a stored procedure usp_GetValues.
EXEC usp_GetValues '123' gives a list of names like :
Names
=======
Joy
Roy
Toy
I have another table, where I want to insert record like :
Insert into NewNameTable
Values ('HighSchool', Names, 'true')
Where name list will be coming from the stored procedure execution.
Is there any way to do this bulk insert?

Try this ...
CREATE TABLE #TestTable ([Names] NVARCHAR(256))
INSERT INTO #TestTable
EXEC usp_GetValues '123'
Insert into NewNameTable Select ('HighSchool', Names, 'true') from #TestTable

First store name values from executing stored procedure in temporary table and then insert into target table with default values.
DECLARE #tempNameTable table(names varchar(100))
INSERT INTO #tempNameTable
EXEC usp_GetValues '123'
INSERT INTO NewNameTable
SELECT 'High School',names,'true'
FROM #tempNameTable

Related

How can we completely replace the contents of a table with another table in a SQL Server database?

How can we completely replace the contents of a table with another table in a SQL Server database?
Like Truncate. We want to take all the data in one and put the data in the other one into it. How can we do? How do we do it with a script? By doing this automatically.
It happens in Oracle, does it happen in SQL Server? Thanks.
Just make simple insert into statement like this :
Also you can create procedure that will makes like just my simple example
DECLARE #employee1 TABLE(
Emp VARCHAR(100),
DOB datetime
)
INSERT INTO #employee1 SELECT 'ABC','1991-03-01'
INSERT INTO #employee1 SELECT 'XYZ','1992-12-01'
INSERT INTO #employee1 SELECT 'AJM','1992-08-20'
INSERT INTO #employee1 SELECT 'RNM','1991-07-10'
DECLARE #employee2 TABLE(
Emp VARCHAR(100),
DOB datetime
)
INSERT INTO #employee2
select * from #employee1
select '#employee1',* from #employee1
select '#employee2',* from #employee2
SQLFiddleDemo
If i am correct schema is same for both tables. In this case there are many way you can achieve this automatically,
Option 1: Call Stored Procedure from any web page or window service or any api.
Option 2: Create triggers.
In both way you can use following script to copy data from one table to other:
Truncate table <table1>
GO
INSERT <Table1> (column1, column2)
SELECT Column1, column2 FROM <Table2>
GO

Insert into distinct columns from a stored procedure

How to insert into a temp table that is all ready created inside of a stored procedure
ALTER PROCEDURE [dbo].[Report_1]
BEGIN
CREATE TABLE #Temp
(
col1 INT,
col2 INT,
col3 VARCHAR(50)
)
INSERT INTO #Temp
EXEC [spSelection] #ID
..do stuff
..do stuff
..do stuff
SELECT * FROM #temp
END
The problem I am having is, I will use this stored procedure (spSelection) in the future and if I change this stored procedure to get more columns for a different stored procedure, then Report_1 will fail.
So I need a way to dynamically create the table or be able to only select distinct columns from the output of exec [spSelection] #ID or have Report_1 be able to read from a temp table created in spSelection.
I have tried to use a global and that will not work because it can be used by other stored procedure at the same time, if I create a dynamic SQL.
#sql ='
create table #Temp(
col1 int,col2 int,col3 varchar(50)
) ' exec sp_executesql #sql
I can not access the #temp table outside of the quotes
One alternative is to change your SP to make the insert inside the SP:
ALTER PROCEDURE [spSelection]
AS
BEGIN
-- Validate that your temporary table was created (the insert will fail otherwise)
IF OBJECT_ID('tempdb..#Temp') IS NULL
BEGIN
RAISERROR ('The table #Temp must be created before executing this SP', 16, 1)
RETURN
END
..do stuff
..do stuff
..do stuff
INSERT INTO #Temp (
col1,
col2,
col3)
SELECT
/*Columns*/
END
GO
ALTER PROCEDURE [dbo].[Report_1]
BEGIN
CREATE TABLE #Temp
(
col1 INT,
col2 INT,
col3 VARCHAR(50)
)
EXEC [spSelection] #ID -- Will insert into #Temp
..do stuff
..do stuff
..do stuff
SELECT * FROM #temp
END
This approach will fail if you eventually add new columns to the #Temp table and insert them inside the SP without updating the CREATE TABLE in every SP that calls it.
There is no definitive solution here, please read this excellent paper about all possible ways to share data between SP, with pros and cons of each (the solution I posted here is listed as 4. Using a table).
Instead of creating a stored procedure for selecting results, you can create a view and use SELECT INTO clause to dynamically create temp table at run time.
You can not use stored procedure in select statement.

Options besides table valued parameters for passing table variable?

We have many stored procedures that are used for reports. All these procedures follow the following format. In essence, the SP does work, and the final result is inserted into a #table variable:
ALTER procedure dbo.usp_GetComplexData
as
declare #MyTable table
(
Col1 varchar(20),
Col2 varchar(20)
)
-- Here the SP is doing lots of work with lots of tables.
-- The result inserted in #MyTable
SELECT Col1, Col2 from #MyTable
Now I need to send via email (in html format) the results of these stored procedures.
I also have SpCustomTable2HTML (found at Symantec) that converts any table into an html table. It doesn't need the table schema to do its work; it simply takes the table and returns an html table.
So here's the stored procedure:
ALTER procedure usp_sendHtmlReportViaEmail
as
DECLARE #HTML1 NVARCHAR(MAX)
IF OBJECT_ID('tempdb..#Results') IS NOT NULL
drop TABLE #results
select top 50 * into #results From MyTable
EXEC SpCustomTable2HTML '#results', #HTML1 OUTPUT, '', ''
EXEC sp_send_dbmail #profile_name='My profile',
#recipients='test#Example.com',
#subject='Test message',
#body_format = 'HTML',
#body=#HTML1
I would like to somehow call usp_sendHtmlReportViaEmail from usp_GetComplexData by sending it #MyTable as parameter. I was reading about table valued parameters, but that requires to create a TVP for each table that I would pass. I don't want to create a specific TVP for each table that will be passed to usp_sendHtmlReportViaEmail.
Are there any other options?
Thanks.
If you're determined to use SQL, then you should look into using a global temporary table. You have to make sure you clean up after your code executes to avoid using too many resources, but it might be a valid approach for you.
At the end of your usp_GetComplexData procedure, just insert the data into a ##TemporaryTable and use that as the parameter to usp_sendHtmlReportViaEmail. Since I don't know what exactly you do with the table variable, I won't replace it, but you could potentially replace it with the temporary table instead.
ALTER PROCEDURE usp_GetComplexData
AS BEGIN
DECLARE #MyTable TABLE
(/*... Columns ...*/);
-- Do complex data stuff...
SELECT
*
INTO
##MyTempTable
FROM
#MyTable;
EXECUTE usp_sendHtmlReportViaEmail '##MyTempTable';
SELECT
*
FROM
#MyTable;
END

Truncate existing table within a stored procedure then insert fresh data

I have a stored procedure that returns a result set. After that I insert this result set into created real table. And then I am using that real table create SSRS reports.
So, something like this:
CREATE PROCEDURE Test
AS
DECLARE #TempTable TABLE(..)
INSERT INTO #TempTable
SELECT...
FROM ...
WHERE ...
SELECT * FROM #TempTable
--============================
INSERT INTO RealTable EXEC [dbo].[Test]
How can I modify this stored procedure so every time it executed it will truncate table with existing data and then insert a fresh one?
So I need something like that:
create procedure Test
as
TRUNCATE RealTable
DECLARE #TempTable TABLE(..)
INSERT INTO #TempTable
SELECT...
FROM...
WHERE...
SELECT * FROM #TempTable INTO RealTable
Or should I just create agent job that would run command something like:
Truncate Table RealTable
INSERT INTO RealTable EXEC [dbo].[Test]
Am I on a right way in terms of logic?
Dont TRUNCATE. Use a MERGE Statement.
CREATE PROCEDURE Test
AS
MERGE RealTable TRGT
USING SourceTable SRCE
ON SRCE.[Column] = TRGT.Column --use columns that can be joined together
WHEN MATCHED THEN UPDATE
SET TRGT.Column1 = SRCE.Column1,
TRGT.Column2 = SRCE.Column2
....................
WHEN NOT MATCHED BY TARGET THEN INSERT
VALUES
(
SRCE.Column1,
SRCE.Column2,
.....................
)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
What's the purpose of the truncate if you are inserting the same data?
What should happen if you have more then 1 concurrent user?
another thing you can do:
1.
insert into TargetTable
select * from SourceTable
2.
rebuild indexes on TargetTable
3.
exec sp_rename SourceTable, SourceTable_Old
exec sp_rename TargetTable, SourceTable
drop table SourceTable_Old
this is an old way of entire table data refresh without much impact, when table variable was not an option.
this is what you probably need as you are directly inserting from #TempTable to RealTable.
create procedure Test
as
BEGIN
TRUNCATE TABLE RealTable
INSERT INTO RealTable
SELECT...
FROM someothertable
WHERE...
END

Can I insert into temp table from SP without declaring table?

Here is my code:
alter procedure test1 as
select DeptID,DeptName from Department
go
alter procedure test2 as
--Create Table #tab (DeptID INT, DeptName VARCHAR(255))
INSERT INTO #tab
exec test1
select * from #tab
drop table #tab
go
exec test2
I am getting an error like "Invalid object name #tab"
If I add at the begining Create Table #tab (DeptID INT, DeptName VARCHAR(255)) then I do not get any error.
What is wrong in my code? Can I populate a temp table from the results of a stored procedure without declaring the temp table and its column definitions?
When loading a temp table from a stored procedure, then you have to CREATE the table first.
There is no straightforward equivalent of
SELECT * INTO #temptable FROM AnotherTable
The non-straightforward version (read all about the bad stuff on "How to Share Data Between Stored Procedures". And simpler) would be
SELECT * INTO #temptable FROM OPENQUERY(Loopback, 'exec test1')
It's because the Local Temporary table #tab which you are expecting does not existing in the session.
So the table creation should not be commented line.
Create Table #tab (DeptID INT, DeptName VARCHAR(255))
Moreover, if you want to do without creating the table then it should be like below
Alter procedure test2
As
Set NoCount ON
IF OBJECT_ID('tempdb..#tab') IS NOT NULL
Begin
Drop table #temp
End
SELECT DeptID, DeptName INTO #tab from Department
Select * from #tab
Drop table #tab
Go

Resources