What i wana do is actually process some data then insert the processed data into a new table..
but first i need to check the target table ;if empty then delete everything in the table then only insert the fresh processed data..
i'm using sql server 2008...
anyone can give me the sample sql code to create the stored procedure??
create procedure SprocName
AS
BEGIN
DECLARE #ProcessedData AS TABLE (IntColumn int, CharColumn varchar(MAX))
-- get processed data
INSERT INTO #ProcessedData (IntColumn, CharColumn)
SELECT IntValue, CharValue FROM SourceTable -- WHERE your condition
-- check target and delete
IF EXISTS (SELECT * FROM TargetTable)
BEGIN
DELETE FROM TargetTable -- WHERE your condition
END
-- insert fresh
INSERT INTO TargetTable (IntColumn, CharColumn)
SELECT IntColumn, CharColumn FROM #ProcessedData
END
Sorry code not tested ;)
Syntax for create stored procedure is here: http://msdn.microsoft.com/en-us/library/ms187926.aspx
Then you need to do a select, syntax is here: http://msdn.microsoft.com/en-us/library/ms189499.aspx
Next is an if, see: http://msdn.microsoft.com/en-us/library/ms182717.aspx
And finally an insert http://msdn.microsoft.com/en-us/library/ms174335.aspx
Related
I'm trying to run a stored procedure that creates a local table - #table1
The stored procedure is supposed to look for values and create the table and insert the values into it...
INSERT INTO #table1
I execute the stored procedure and it shows that 1 row() affected, however, I am unable to find this table in the list of my tables. Why am I not able to see it or access it?
EDIT: I'm running the stored procedure inside SQL Server against a database. At the end of the stored procedure, the last line is:
Select * from #table1
Thanks.
The #table is a local temp table. It does not exist as a permanent table that you can look for outside the scope of the stored proc. Once the stored proc is run, the temp table is dropped because it is no longer in scope. Temp tables are stored temporarily in the tempdb database but with a different name because two people running the stored procedure at the same time would each have a table that can be referenced in the proc as #table but it would be two separate tables in the tempdb.
Now if what you are doing is looking to see what is in #table at a point in the stored proc in order to troubleshoot the proc, then you need to set thing up in the proc so that you can see the results at different stages or when you hit a certain state such as an error.
This could be something like adding a #debug variable to the proc so that when you are in debug mode, you can select the results to the screen when you are running something like:
CREATE PROC test_proc (#Id INT, #debug BIT = 0)
AS
CREATE TABLE #temp(id INT)
INSERT INTO #temp
VALUES (#Id), (1), (2)
IF #debug = 1
BEGIN
SELECT * FROM #temp
END
UPDATE #temp
SET Id = id-1
IF #debug = 1
BEGIN
SELECT * FROM #temp
END
GO
You would then execute the proc without debugging as so (note that since I am not returning something or inserting to permanent tables, this proc will insert to #temp but you can't see anything. I just didn't want to get complicated here, the steps of the proc will vary depending on what you want to do, the concept I am trying to show is how to use the debug variable):
EXEC test_proc #Id= 5
and with debugging as
EXEC test_proc #Id= 5, #debug= 1
Or it might involved using a table variable instead (because they don't get rolled back on error) and then inserting the data from that table variable into a logging table after the rollback occurs in the Catch block, so that you can see the values at the time the error occurred.
Without knowing more about why you are looking for #temp and what the data means and is used for, it is hard to say what you need to do.
Did you tried refreshing the tables after exceuting Stored procedure
I have created a stored procedure that returns the id of last inserted row of a table based on one condition.
Condition is such that if the row being inserted already exists then it takes identity column of the row otherwise it inserts a new row into the table.
To do this, I have written the following code in a stored procedure
ALTER PROCEDURE [dbo].[Test_Procedure]
#description nvarchar(max)
AS
BEGIN
DECLARE #tempId int;
SELECT CommentId
INTO tempId
FROM TestTable
WHERE description = #description;
IF #tempId IS NULL
BEGIN
INSERT INTO TestTable
VALUES (#description);
SELECT scope_identity();
END
ELSE
BEGIN
SELECT #tempId FROM dual;
END
DROP TABLE tempId;
END
When I run the above stored procedure, first time it ran successfully and then on wards it started throwing the following error message
Msg 2714, Level 16, State 6, Procedure Test_Procedure, Line 15
There is already an object named 'tempId' in the database.
The bit I'm not understanding is tempId is used as a variable not as a table. I have seen people with the similar problem but in their case they used temporary tables
I really appreciate your help in resolving the above issue.
Try this syntax for setting your variable.
SELECT #tempId = CommentId from TestTable where description = #description;
Currently your 'select into' is creating a table 'tempId' on the database.
I did a search over the net but I couldnt find my answer
in oracle , if we to specify for the trigere if its insert or update , we write like this :
create or replace trigger TRG_LOGS
after INSERT or update or delete
ON TABOE_LOGS
FOR EACH ROW
DECLARE
V_USERNAME VARCHAR2(100);
BEGIN
if inserting then
insert into long_log(NAME) VALUE (:new.NAME)
ELSE if UPDATING THEN
insert into long_log(NAME) VALUE (:OLD.NAME)
END;
END;
Is throwing an error on Incorrect syntax near the keyword 'insert'.
For Sybase, each action is a seperate trigger:
create trigger TRG_LOGS_INS on TABOE_LOGS
for INSERT
as
DECLARE #V_USERNAME varchar(100)
BEGIN
insert into long_log
select NAME from INSERTED
END
....
create trigger TRG_LOGS_UPD on TABOE_LOGS
for UPDATE
as
DECLARE #V_USERNAME varchar(100)
BEGIN
insert into long_log
select NAME from DELETED
END
Not sure if my syntax is exactly right, but should get you pointed in the right direction. The INSERTED table (similar to Oracles new) stores the new records on either an insert or update action. The DELETED table (similar to Oracles old) stores the old records on either an update or delete action.
More information and examples can be found in the Sybase T-SQL Users Guide: Triggers
The code is like this
INSERT INTO TABLE (VAL1,VAL2,VAL3) VALUES (X,Y,Z)
GetLastInsertID #tablename='TABLE'
GetLastInsertID is this Stored Procedure:
SELECT ##IDENTITY AS LastID FROM TABLE
How do I get the stored procedure to return the 'LastID' as requested in the Select ##IDENTITY statement above?
I get the following error:
Incorrect syntax near 'GetLastInsertId'.
...but this works fine when executed by itself:
GetLastInsertID #tablename='TABLE'
Okay, thanks i updated it to Scope_Identity(). But you're saying not to put it in a different SP, to put it in the same SP as the Insert?
Again, i still am getting an error when i combine an insert with this:
SELECT SCOPE_IDENTITY() AS LastID FROM TABLE
Here is the new error message:
There is already an object named 'TABLE' in the database.
It's a bad idea to separate this into a stored procedure at all, because a stored procedure creates a new scope/context. That leaves you open to grabbing the wrong ID number. If one user in a session inserts many rows together, you might get the wrong result.
Instead, you almost always want the scope_identity() function, and you want to call it in the same context as the statement that created the new record.
In the first place you do not ever want to use ##identity as it can break if someone adds a trigger.
What you want to use is the OUTPUT clause or scope_identity. See Books online for examples of how to use OUTPUT.
your error is in your failure to include the EXECUTE command, try this:
INSERT INTO TABLE (VAL1,VAL2,VAL3) VALUES (X,Y,Z)
EXEC GetLastInsertID #tablename='TABLE'
the EXEC is assumed when you attempt to run a procedure with no other commands, however when you include the INSERT it makes the EXEC required.
Now, you really need to determine if what you are trying to do is a good design.
try this:
DECLARE #LastId int
INSERT INTO TABLE (VAL1,VAL2,VAL3) VALUES (X,Y,Z)
SELECT #LastID=SCOPE_IDENTITY()
Here is my sample code that does this. (But the stored proc doesn't add any value.)
--First create a test table.
create table test
(id int identity,
name varchar(30))
go
--A stored proc that returns the scope_identity()
create proc dbo.spTest
as
insert into test(name)
values ('test')
return scope_identity()
go
-- Sample call
declare #newId int
exec #newId = spTest
print #newId
I have 2 stored procedures usp_SP1 and usp_SP2. Both of them make use of insert into #tt exec sp_somesp. I wanted to create a 3rd stored procedure which will decide which stored proc to call. Something like:
create proc usp_Decision
(
#value int
)
as
begin
if (#value = 1)
exec usp_SP1 -- this proc already has insert into #tt exec usp_somestoredproc
else
exec usp_SP2 -- this proc too has insert into #tt exec usp_somestoredproc
end
Later, I realized I needed some structure defined for the return value from usp_Decision so that I can populate the SSRS dataset field. So here is what I tried:
Within usp_Decision created a temp table and tried to do "insert into #tt exec usp_SP1". This didn't work out. error "insert exec cannot be nested"
Within usp_Decision tried passing table variable to each of the stored proc and update the table within the stored procs and do "select * from ". That didn't work out as well. Table variable passed as parameter cannot be modified within the stored proc.
Please suggest what can be done.
Can you modify usp_SP1 and usp_SP2?
If so, in usp_Decision, create a local temporary table with the proper schema to insert the results:
create table #results (....)
Then, in the called procedure, test for the existence of this temporary table. If it exists, insert into the temporary table. If not, return the result set as usual. This helps preserve existing behavior, if the nested procedures are called from elsewhere.
if object_id('tempdb..#results') is not null begin
insert #results (....)
select .....
end
else begin
select ....
end
When control returns to the calling procedure, #results will have been populated by the nested proc, whichever one was called.
If the result sets don't share the same schema, you may need to create two temporary tables in usp_Decision.
Have you had a look at table-valued user-defined functions (either inline or multi-statement)? Similar to HLGEM's suggestion, this will return a set which you may not have to insert any where.
Not a fan of global temp tables in any event (other processes can read these table and may interfere with the data in them).
Why not have each proc use a local temp table and select * from that table as the last step.
Then you can insert into a local temp table in the calling proc.
esimple example
create proc usp_mytest1
as
select top 1 id into #test1
from MYDATABASE..MYTABLE (nolock)
select * from #test1
go
--drop table #test
create proc usp_mytest2
as
select top 10 MYTABLE_id into #test2
from MYDATABASE..MYTABLE (nolock)
select * from #test2
go
create proc usp_mytest3 (#myvalue int)
as
create table #test3 (MYTABLE_id int)
if #myvalue = 1
Begin
insert #test3
exec ap2work..usp_mytest1
end
else
begin
insert #test3
exec ap2work..usp_mytest2
end
select * from #test3
go
exec ap2work..usp_mytest3 1
exec ap2work..usp_mytest3 0
See this blog article for one wortkaround (uses OPENROWSET to essentially create a loopback connection on which one of the INSERT EXEC calls happens)