Delete and Insert Into - sql

I'm looking to execute a stored procedure everyday where it will firstly delete the data within a specified table and then insert the new data in.
My stored procedure looks roughly like this
ALTER PROCEDURE [dbo].[SP_Name]
AS BEGIN
WITH CTE_Name as
( select
Title,
First_Name,
Surname
From table
)
DELETE [dbo].[NEW_TABLE]
INSERT INTO [dbo].[NEW_TABLE]
Select * from CTE_NAME
END
When I execute the query I get the error invalid object name 'CTE_NAME'
I have tried removing the 'DELETE [dbo].[NEW_TABLE]' line and upon doing this the stored procedure does run and does insert the data into the table.
I'm using SQl Management Studio 2012

I think you need to separate your With by adding a semicolon in front of it
below code should work
DECLARE #TABLE TABLE (
id VARCHAR(100)
)
DELETE FROM #TABLE
;WITH CTE_Name AS
(
SELECT id FROM OtherTable
)
INSERT INTO #TABLE
SELECT id FROM CTE_Name

You could try this code:
ALTER PROCEDURE [dbo].[SP_Name] AS
BEGIN
DECLARE #helperTbl TABLE (Title varchar(100), First_Name varchar(100), Surname varchar(100))
INSERT INTO #helperTbl
SELECT Title,
First_Name,
Surname
FROM [table]
DELETE FROM [dbo].[NEW_TABLE]
INSERT INTO [dbo].[NEW_TABLE]
SELECT * FROM #helperTbl
END

Related

Why do I get an invalid column name error when using a temp table twice?

If I run each of these batches separately, it works. However, if they are combined into one script (like what is done when a DACPAC script runs, or putting them both into one tab in SSMS), I get an Invalid column name error on the second insert. Why is that? If I need these to run in one script, do I need to use a different name for the temp table for the second batch? Or am I missing something that would allow me to use the same name?
IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source
SELECT FirstName, LastName INTO #source FROM Musician WHERE 1 = 0; -- set up temp table schema
INSERT INTO #source ( FirstName, LastName )
VALUES
('Geddy', 'Lee'),
('Alex', 'Lifeson')
SELECT * FROM #source
GO
IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source
SELECT [Name], Genre INTO #source FROM Band WHERE 1 = 0; -- set up temp table schema
INSERT INTO #source ( [Name], Genre )
VALUES
('Rush', 'Rock'),
('Ratt', 'Rock')
SELECT * FROM #source
GO
Each batch is parsed independently. So it works when you use GO because they are in different batches.
When you put everything in the same batch, SQL Server parses what it sees, and it is blind to logic like DROP commands hidden behind IF conditionals. Try the following and you'll find the same:
IF (1=0) DROP TABLE IF EXISTS #x; CREATE TABLE #x(i int);
IF (1=1) DROP TABLE IF EXISTS #x; CREATE TABLE #x(j date);
You and I both know that only one of those will ever execute, but the parser spots the redundant table name before it ever gets to execution (or evaluating any conditionals).
This works because, again, each batch is now parsed in isolation:
IF (1=0) DROP TABLE IF EXISTS #x; CREATE TABLE #x(i int);
GO
IF (1=1) DROP TABLE IF EXISTS #x; CREATE TABLE #x(j date);
This will in fact fail even though it passes parsing (highlight and select Parse instead of Execute), so the blindness goes both ways:
IF (1=0) DROP TABLE IF EXISTS #x; CREATE TABLE #x(i int);
GO
IF (1=1) CREATE TABLE #x(j date);
Using go after dropping the tables in both block will do the trick.
IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source
go
SELECT FirstName, LastName INTO #source FROM Musician WHERE 1 = 0; -- set up temp table schema
INSERT INTO #source ( FirstName, LastName )
VALUES
('Geddy', 'Lee'),
('Alex', 'Lifeson')
SELECT * FROM #source
GO
IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source
go
SELECT [Name], Genre INTO #source FROM Band WHERE 1 = 0; -- set up temp table schema
INSERT INTO #source ( [Name], Genre )
VALUES
('Rush', 'Rock'),
('Ratt', 'Rock')
SELECT * FROM #source
GO

Return AutoIncremeting ID upon insert

I have a stored procedure that inserts into a table that has two values, id and username. The id field is autoincremeting so my stored procedure looks like:
CREATE PROCEDURE [dbo].[sp_test]
#username varchar(50)
AS
BEGIN
INSERT INTO dbo.testtable(username)
SELECT
#username
FROM
tbl.test2
WHERE
username IS NOT NULL
How can I return the id even when there it is not explicitly stated? I attempted the SCOPE_IDENTITY(); keyword but I was receiving blanks and nulls.
Taking a guess as to what you want I think it would be something more like this.
CREATE PROCEDURE [dbo].[Insert_test]
(
#username varchar(50)
) AS
BEGIN
INSERT INTO dbo.testtable
(
username
)
VALUES
(
#username
)
select SCOPE_IDENTITY()
END
If you're really inserting several rows from a table, you can get the ids this way:
INSERT INTO dbo.testtable(username)
output inserted.id
SELECT username
FROM dbo.test2
where username is not null

How to get one data table from Stored procedure that has multiple select statements using sql server

I have two select statements in my stored procedure:
alter proc multiple
select * from table-one
select * from table-two
Now how to get the data of table-one only by executing the stored procedure?
You can pass input variable and use if statment. For example:
ALTER PROCEDURE multiple
#choice INT
AS
BEGIN
IF (#choice = 1)
BEGIN
SELECT * FROM Table1
END
IF (#choice = 2)
BEGIN
SELECT * FROM Table2
END
IF (#choice = 3)
BEGIN
SELECT * FROM Table1
SELECT * FROM Table2
END
END
And execution of procedure:
EXECUTE multiple #choice = 1 -- to use 1st select
EXECUTE multiple #choice = 2 -- to use 2st select
EXECUTE multiple #choice = 3 -- to use both selects
You can use TEMP table to fill all result in the temp table.
if you have 3 table name tab_1,tab_2,tab_3 then create a temp table with column maximum from these table(tab_1,tab_2,tab_3) and add a extra column to temp table to identify data from tables.
tab_1(id bigint,name varchar(50))
tab_2(id bigint,email varchar(50))
tab_3(id bigint,address varchar(50),phone varchar(50))
then your temp table should be like this
#tmp(col1 bigint(),col2 varchar(50),col3 varchar(50),from_table varchar(50))
e.g
create table tab_1
(
id bigint identity(1,1),
name varchar(50),
email varchar(50)
)
insert into tab_1(name,email) values
('a','a#mail.com'), ('b','c#mail.com'),
('a1','a1#mail.com'), ('a2','a2#mail.com'),
('a3','a3#mail.com'), ('a4','a4#mail.com'),
('b1','b1#mail.com'),('b2','b2#mail.com')
create table tab_2
(
id bigint identity(1,1),
name varchar(50),
email varchar(50),
amount decimal(18,2)
)
insert into tab_2(name,email,amount) values
('a','a#mail.com',12.5), ('b','c#mail.com',11.6),
('a1','a1#mail.com',11.7), ('a2','a2#mail.com',88.9),
('a3','a3#mail.com',90), ('a4','a4#mail.com',45),
('b1','b1#mail.com',78),('b2','b2#mail.com',88)
and the Sp should be like
create table #tab(col1 bigint,
col2 varchar(50),
col3 varchar(50),col4 varchar(50),table_from varchar(50))
insert into #tab(col1,col2,col3,table_from)
select id,name,email,'table_1' from tab_1
insert into #tab(col1,col2,col3,col4,table_from)
select id,name,email,amount,'table_2' from tab_2
select * from #tab
FIDDLE DEMO

Select only few columns from procedure and insert into table

I have a stored procedure that returns 6 columns. But I want to take only 2 columns and insert them into my table variable.
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #CategoryTable EXEC [GetAllTenantCategories] #TenantId
When I run this
Column name or number of supplied values does not match table
definition
How to insert only specified columns from a stored procedure?
I do not want to use SELECT INTO as it is not supported by SQL Azure
Tried below and got Invalid object name '#Temp'
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #Temp EXEC [GetAllTenantCategories] 1
INSERT INTO #CategoryTable (CategoryId, Name)
SELECT CategoryId, Name from #Temp
DROP TABLE #Temp
You can create a temp table first and the INSERT the required columns in your table variable.
CREATE TABLE #temp
(
your columns and datatype
)
INSERT INTO #temp
EXEC [GetAllTenantCategories] #TenantId
Then you can,
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #CategoryTable (CategoryId, Name)
select CategoryId, Name from #temp
Also drop the #temp table,
DROP TABLE #temp
Refer the points taken from https://www.simple-talk.com/sql/performance/execution-plan-basics/
When the Estimated Plan is Invalid
In some instances, the estimated plan won't work at all. For example, try generating an estimated plan for this simple bit of code:
CREATE TABLE TempTable
(
Id INT IDENTITY (1 , 1 )
,Dsc NVARCHAR (50 )
);
INSERT INTO TempTable ( Dsc )
SELECT [Name]
FROM [Sales] .[Store] ;
SELECT *
FROM TempTable ;
DROP TABLE TempTable ;
You will get this error:
Invalid object name 'TempTable'.
The optimizer, which is what is used to generate Estimated Execution plans, doesn't execute T-SQL.
It does run the stateĀ­ments through the algebrizer , the process outlined earlier that is responsible for verifying the names of database objects. Since the query has not yet been executed, the temporary table does not yet exist. This is the cause of the error.
Running this same bit of code through the Actual execution plan will work perfectly fine.
Hope you got why your temp table approach not worked :) Because you might tried as T-SQL
We can use OPENQUERY
SELECT EmployeeID,CurrentSalary INTO #tempEmp
FROM OPENQUERY(LOCALSERVER,'Exec TestDB.dbo.spEmployee')

i am trying to execute the before insert trigger , but i m getting the sql errors

what i want to achieve is i have a table called orders.
i want to perform the before insert trigger on my orders table.i want to capture the
username of person performing INSERT into table.
one table called info which contain the user.
this is my code
create table orders
(
order_id int,
quantity int,
cost int,
total_cost int,
created_date datetime,
created_by varchar(20)
)
create trigger beforeInsertdata
before insert
on orders
for each row
declare
v_username varchar2(10);
begin
-- Find username of person performing INSERT into table
SELECT user INTO v_username
FROM info;
-- Update create_date field to current system date
:new.create_date := sysdate;
-- Update created_by field to the username of the person performing the INSERT
:new.created_by := v_username;
END;
--user information--
create table info
(
userid int ,
user_name varchar(10)
)
insert into info values(1,'vivek')
select * from info
Basically, triggers are classified into two main types:-
1)After Triggers (For Triggers)
2)Instead Of Triggers
and the syntax for trigger is
CREATE TRIGGER trigger_name ON table_name
[FOR|AFTER|INSTEAD OF] [INSERT|UPDATE|DELETE]
AS
//your code goes here
GO
NOTE : FOR keyword used for INSERT |UPDATE Command where as AFTER USED FOR DELETE Command.
It's hard to tell what you're really trying to do. I've modified your code sample so that it will work on SQL2K5 and made some assumptions about how you're wanting to use the connected user account.
CREATE TABLE orders (
order_id int,
quantity int,
cost int,
total_cost int,
created_date datetime,
created_by varchar(20)
);
CREATE TABLE info (
userid int,
user_name varchar(10)
);
INSERT INTO info
VALUES (1, 'vivek');
SELECT *
FROM info;
CREATE TRIGGER orders_InsteadOfInsert ON orders
INSTEAD OF INSERT AS BEGIN
SET NOCOUNT ON;
-- varchar(10) is to match your table, but probably should be larger
DECLARE #CurrentUser VarChar(10);
SELECT #CurrentUser = SYSTEM_USER;
IF (#CurrentUser NOT IN (SELECT user_name FROM info)) BEGIN
-- consider using an identity column for the key instead of this
INSERT INTO info (userid, user_name)
SELECT
ISNULL((SELECT MAX(userid) FROM info), 0) + 1,
#CurrentUser;
END;
INSERT INTO orders (order_id, quantity, cost, total_cost, created_date, created_by)
SELECT
INS.order_id,
INS.quantity,
INS.cost,
INS.total_cost,
GETDATE(),
#CurrentUser
FROM INSERTED INS;
END;