How to use scope identity with update query - sql

I have an id as primary key and I am setting that id=scope identity() in the insert procedure.
But I am unable to use that id with update procedure.
I want to write a procedure that will update the table with the id in the where condition, i.e.,
UPDATE TABLE [table name]
SET col = #col, col2 = #col2
WHERE id = #id
but my id is autogenerated i.e., id int identity(1,1)
How should I write update procedure?

You need to have #id as an in parameter to your stored procedure.
Your stored procedure should probably look something like:
CREATE PROCEDURE <Procedure name>
(
#id INT,
#col1 <datatype>,
#col1 <datatype>
)
AS
UPDATE TABLE [table name]
SET col = #col, col2 = #col2
WHERE id = #id

What I could understand is that you want to update the Table with the recent inserted row using #id = scope_identity(). Please see below the code to achieve this:
create proc abc
#col1 int,
#col2 int,
#id int
as
begin
set #id = ident_insert('TableA')
UPDATE TABLE [table name]
SET col = #col, col2 = #col2
WHERE id = #id
end
Let me know if this helps..

Related

Procedure to rename a list of procedure, only renames the last procedure in the list

I created a procedure where I could pass a list of procedure names separated by a comma, and then I would like to rename all the procedures from the list by adding a custom suffix in the end.
But I am facing an issue where it would only rename the last item from the list and ignore all the rest. I don't know why it would not rename each one from table variable list since I am calling sp_rename on each item in the list.
Also, I was able to print each loop with raiseerror()
Here's the complete procedure that I written.
CREATE PROCEDURE [dbo].[Util_ProcRename]
#ProcNameListWithComma VARCHAR(MAX)
AS
BEGIN
DECLARE #ID INT
SET #ID = 1;
DECLARE #oldname varchar(200)
DECLARE #newname varchar(200);
DECLARE #NOTUSED VARCHAR(20)
SET #NOTUSED = '_NOTUSED_'+REPLACE(CONVERT(varchar(20), GETDATE(), 101),'/','')
DECLARE #ProList AS TABLE (
ID INT IDENTITY,
ProcName VARCHAR(200),
NewProcName VARCHAR(200)
);
--Get proc names from a list into a table with ID to use in While loop
INSERT INTO #ProList (ProcName)
SELECT P AS ProcName
FROM dbo.SplitText(#ProcNameListWithComma,',')
WHILE (#id <= (SELECT MAX(ID) FROM #ProList))
BEGIN
SET #oldname = (SELECT ProcName FROM #ProList WHERE ID = #ID)
SET #newname = #oldname + #NOTUSED
EXEC p_rename #oldname, #newname
SET #ID = #ID + 1
END
UPDATE p
SET NewProcName = p.ProcName+#NOTUSED
FROM #ProList p
WHERE ID = ID
--TO see the list that got renamed
SELECT
a.Name AS [NewName],
a.type
FROM
dbo.sysobjects a
WHERE
name IN (SELECT NewProcName FROM #ProList)
END
GO
Despite the indentation, you are doing the update after the loop. So, it is only called once.
Move the END to after the UPDATE.

SQL Server stored procedure: verify CRUD operation success/failure using output variable

I am trying to create a SQL Server stored procedure to handle updates to a table using some dynamic SQL. The table name required for the update is stored in a table that correlates a table id to a category id. Once the table name is retrieved and the table id is not null, I update the table using a dynamic SQL query as shown below:
CREATE PROCEDURE [dbo].[SP_EBS_CustomForms_SetCategoryData]
(#flag int output,
#cat_id int,
#sort int,
#value varchar(50),
#active int,
#enum int)
AS
BEGIN
DECLARE #tbl as varchar(50)
DECLARE #tbl_id as int
DECLARE #sql nvarchar(max)
BEGIN TRY
SET #tbl_id = (SELECT [tbl_id]
FROM [demodata].[dbo].[ebscustomforms_cattable]
WHERE cat_id = #cat_id)
IF #tbl_id IS NOT NULL
BEGIN
SET #tbl = (SELECT table_name
FROM ebscustomforms_enumtable
WHERE tbl_id = #tbl_id)
SET #sql = 'UPDATE ' + #tbl + ' SET [sort_order] = #sort, [value] = #value, [active] = #active WHERE [enum_id] = #enum'
EXECUTE sp_executesql #sql, N'#sort int, #value varchar(50), #active int, #enum int', #sort, #value, #active, #enum
SET #flag = 0
RETURN #flag
END
END TRY
BEGIN CATCH
IF ##ERROR <> 0
BEGIN
SET #flag = 1;
RETURN #flag
END
END CATCH
END
I want this stored procedure to return an int value indicating whether the stored procedure was successful (0) or failed (1) updating the table.
Points of error are as follows:
#tbl_id variable is null
#tbl is either null or an empty varchar
The table to be updated does not have a record where [enum_id] = #enum
I have noticed that when I try to update a record that does not exist, the procedure seems to return as successful i.e. #flag = 0. However, I would imagine that an error should be thrown because the record does not exist.

Sql Server Stored Procedure Case When in Update

I am new in stored procedures.
ALTER PROCEDURE [dbo].[SP_MY_STORE_PROCEDURED]
(
#ID INT,
#NAME VARCHAR(50)
)
AS
BEGIN
UPDATE MY_TABLE
SET
WHEN
(( ID ) > 1)
THEN
ID=#ID
,
NAME = #NAME
END
I try to use when then for update my ID and Name
If Id is greater than 1 i want to update otherwise no update.
How can i do it ms sql?
Any help will be appreciated.
Thanks.
I think this is what you are after:
ALTER PROCEDURE [dbo].[SP_MY_STORE_PROCEDURED]
(
#ID INT,
#NAME VARCHAR(50)
)
AS
BEGIN
UPDATE MY_TABLE
SET NAME = #NAME
WHERE ID = #ID
END
You do not need to check ID>1 since you are checking the equality with #ID. If you want to be sure that this doesn't happen if #ID <=1 then you may try the following:
ALTER PROCEDURE [dbo].[SP_MY_STORE_PROCEDURED]
(
#ID INT,
#NAME VARCHAR(50)
)
AS
BEGIN
IF #ID > 1
UPDATE MY_TABLE
SET NAME = #NAME
WHERE ID = #ID
END
I'm not sure exactly what you're trying to update. Are you trying to change the name on a user record with id = #ID?
ALTER PROCEDURE [dbo].[SP_MY_STORE_PROCEDURED]
(
#ID INT,
#NAME VARCHAR(50)
)
AS
BEGIN
UPDATE MY_TABLE
SET Name = #Name
WHERE Id = #ID and #ID > 1
END
This should do it.
ALTER PROCEDURE [dbo].[SP_MY_STORED_PROCEDURE] ( #ID INT, #NAME VARCHAR(50) )
AS
BEGIN
IF #ID > 1
UPDATE MY_TABLE
SET Name = #Name
WHERE Id = #ID
END

Iterate through a temp table

I did try looping through a temp table, but of no use end up with so many errors only.
Please help me on how can I work this one out..
My need is like :
I need to fetch an ID column from a table, and store it in one temp table.
Then iterate through each ID, and execute a stored procedure which takes that ID as an parameter.
Insert the return value (= one column) of that stored procedure in another table.
Please guide me on how to do this.
I did search a lot..and got confused with cursor and set based join.
IMHO in your case you don't need a temp table.
Let's say you have following two tables. First is source table and the other is destination table.
CREATE TABLE mytable(id INT IDENTITY PRIMARY KEY, col1 nvarchar(10));
CREATE TABLE mytable2(id INT, value INT);
mytable has following sample data in it:
id col1
----------------
1 row1
2 row2
3 row3
4 row4
And you have some SP that calculates something based on id, something like this
CREATE PROCEDURE getValue (#id INT, #value INT OUT)
AS
SET NOCOUNT ON;
SET #value = #id * 2;
Then you can create an SP that will do the job like this
CREATE PROCEDURE proccessData
AS
SET NOCOUNT ON;
DECLARE #id INT, #value INT;
DECLARE id_cursor CURSOR FOR
SELECT id FROM mytable WHERE id > 1 AND id < 4;
OPEN id_cursor;
FETCH NEXT FROM id_cursor INTO #id;
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC getValue #id, #value OUTPUT;
INSERT INTO mytable2 VALUES(#id, #value);
-- Or use update if you already have id's in mytable2
-- UPDATE mytable2 SET value = #value WHERE id = #id;
FETCH NEXT FROM id_cursor INTO #id;
END
CLOSE id_cursor;
DEALLOCATE id_cursor;
After you call that SP
EXEC proccessData
you'll get in mytable2
id value
----------- -----------
2 4
3 6
And here is working sqlfiddle

Sql Server 2005 Swap ID Numbers

I have a table that has two columns "name" and "ID". where ID is not null.
I am trying to create a stored prcedure to swap the IDs around for two names when imputed here is what i have so far.
CREATE PROCEDURE dbo.procName
#OldName NVARCHAR(128),
#NewName NVARCHAR(128)
AS
DECLARE #NewId0 INT,
#NewId1 INT,
#OldId0 INT,
#OldId1 INT,
#Number INT
SELECT #NewId0 = ID FROM Table1 WHERE [Name] = #NewName
SELECT #NewId1 = ID FROM Table1 WHERE [Name] = #NewName
SELECT #OldId0 = ID FROM Table1 WHERE [Name] = #OldName
SELECT #OldId1 = ID FROM Table1 WHERE [Name] = #OldName
SELECT #Number = 0
UPDATE Table1 SET ID = #Number WHERE ID = #NewId0
UPDATE Table1 SET ID = #NewId1 WHERE ID = #OldId0
UPDATE Table1 SET ID = #OldID1 WHERE ID = #NewID0
Go
All I get is the first name to have the value 0.
I think my logic is correct but it doesn't seem to be working is there something that I am missing?
Try something like
UPDATE Table1
SET ID = CASE
WHEN ID = #NewId
THEN #OldId
ELSE #NewId
END
WHERE ID IN (#NewId, #OldId)
Here is a full example
DECLARE #Table TABLE(
ID INT,
Name VARCHAR(20)
)
INSERT INTO #Table SELECT 1,'A'
INSERT INTO #Table SELECT 2,'B'
DECLARE #NewName VARCHAR(20),
#OldName VARCHAR(20)
SELECT #NewName = 'A',
#OldName = 'B'
DECLARE #NewId INT,
#OldId INT
SELECT #NewId = ID FROM #Table WHERE [Name] = #NewName
SELECT #OldId = ID FROM #Table WHERE [Name] = #OldName
SELECT *
FROM #Table
UPDATE #Table
SET ID = CASE
WHEN ID = #NewId
THEN #OldId
ELSE #NewId
END
WHERE ID IN (#NewId, #OldId)
SELECT *
FROM #Table
This script works if the ID is not a primary Key
CREATE PROCEDURE dbo.procName
#OldName NVARCHAR(128),
#NewName NVARCHAR(128)
As
DECLARE #NewId INT,
#OldId INT
SELECT #NewId = ID FROM Table1 WHERE [Name] = #NewName
SELECT #OldId = ID FROM Table1 WHERE [Name] = #OldName
UPDATE Table1
SET ID = CASE
WHEN ID = #NewId
THEN #OldId
ELSE #NewId
END
WHERE ID IN (#NewId, #OldId)
SELECT *
FROM Table1
go
Your current code fails because:
You Look for #NewId0, and set it to #Number (which is 0)
You then look for #OldId0, and set it to #NewId1
You then look for #NewId0 again... but two lines back, you set it to 0, so it's not in the table any more
I like #astander's solution (upvoted), saved me writing it out myself.
BUT... your comment, "...ID is a Primary Key", raises all kinds of red flags. You really, really don't want to change primary key values [insert long discussion from past classes about primary keys and relational integrity here]. Figure out why you think you need to do it, and then figure out another way to implement that business requirement, such as:
Don't change the IDs, change everything else (name, description, cost, whatever)
Create completely new entries and drop (or mark as completed, discareded, or junk) the old ones
Implement some clever logic based on the underlying business requirements.
under stand the concerns with changing PKs but it has to be done as it would take too long to change all the other stuff. That said I have come up with an answer. This is only the first part of a long script so again its not perfect:
CREATE PROCEDURE dbo.ID #OldName NVARCHAR(128),
#NewName NVARCHAR(128)
AS
DECLARE #NewId INT,
#OldId INT
CREATE TABLE TmpTable (ID INT,Name NVARCHAR(128))
INSERT INTO TmpTable (Name,ID)
VALUES (#NewName,(SELECT ID FROM Table1 WHERE [Name] = #NewName));
INSERT INTO TmpTable (Name,ID)
VALUES(#OldName,(SELECT ID FROM Table1 WHERE [Name] = #OldName))
UPDATE Table1 SET ID = 11 WHERE [NAME] = #NewName
UPDATE Table1 SET ID = 10 WHERE [NAME] = #OldName
UPDATE Table1 SET ID = (SELECT ID FROM TmpTable where Name = #NewName)WHERE [Name] = #OldName
UPDATE Table1 SET ID = (SELECT ID FROM TmpTable where Name = #OldName) WHERE [Name] = #NewName
DROP TABLE TmpTable
go
"11" and "10" were selected as they are not in the table my next mission will be to query table1 and for a random number that dosent exist then use that number to temprary repplace the ID before updating the new ones.
Thanks