How do I write a stored procedure that requires an id to be created and then used later in the same procedure? - sql

I am trying to write a stored procedure that writes the details of a new user (NonMembers table) to a data base and then uses the auto generated id for that user in the next part of the code to register that user to a competition (registration table). My attempt at doing this is as follows but clearly my SQL skills are a long way from where they need to be?
All help would be greatly appreciated.
ALTER PROCEDURE [dbo].[RegisterNonMember]
#CompetitionId INTEGER,
#IsMember BIT,
#FirstName NVARCHAR(50),
#Surname NVARCHAR(50),
#Handicap INTEGER,
#Club NVARCHAR(50),
#CountyId INTEGER,
#CountryId INTEGER,
#PlayersStartTime TIME
AS
BEGIN
DECLARE #NonMember TABLE
(NonMemberId INTEGER,
FirstName NVARCHAR(50),
Surname NVARCHAR(50),
Handicap INTEGER,
Club NVARCHAR(50),
CountyId INTEGER,
CountryId INTEGER
)
INSERT INTO [dbo].[NonMembers]
(
FirstName
,Surname
,[Handicap]
,[Club]
,CountyId
,CountryId
)
VALUES
(#FirstName
,#Surname
,#Handicap
,#Club
,#CountyId
,#CountryId
)
--UPDATE #NonMember
--SET [#NonMember].NonMemberId = [dbo].[NonMembers].[NonMemberId]
--FROM [dbo].[NonMembers]
--JOIN #NonMember ON [#NonMember].NonMemberId = [dbo].[NonMembers].[NonMemberId]
--WHERE #NonMember.FirstName = [dbo].[NonMembers].[FirstName]
--AND #NonMember.Surname = [dbo].[NonMembers].[Surname]
--AND #NonMember.Handicap = [dbo].[NonMembers].[Handicap]
--AND #NonMember.Club = [dbo].[NonMembers].[Club]
DECLARE #Registration TABLE
(CompetitionId INTEGER,
IsMember BIT,
NonMemberId INTEGER,
PlayersStartTime TIME
)
INSERT INTO [dbo].[Registration]
(
[CompetitionId]
,[IsMember]
,[NonMemberId]
,[PlayersStartTime])
VALUES
(#CompetitionId
,#IsMember
,#NonMemberId
,#PlayersStartTime)
END

After your INSERT add:
DECLARE #UserID INT
SELECT #UserID = SCOPE_IDENTITY()

Related

Trouble with creating a trigger to print a statement after insert

I am working on a project where I need to create a trigger that prints a statement each time an insert is performed on a table called enrolled.
This trigger is expected to print the faculty name, meeting location, time, student name after an insert is performed but when I run this trigger, it completes but after an insert is performed on the enrolled table, it does not print any information but the insert does complete and populates the table with the values. this is the test code I created below, along with the tables required to pull each value and a sample insert statement. any help is greatly appreciated.
USE test
GO
CREATE TRIGGER afterinsertprint on test.dbo.enrolled
AFTER INSERT
AS
BEGIN
DECLARE #studentname VARCHAR(30), #meetat varchar(30), #facultyname VARCHAR (30), #location NVARCHAR(10), #studentnumber int, #coursename NVARCHAR(12)
SELECT #studentnumber = snum, #coursename = cname FROM INSERTED;
SET #studentname = (SELECT sname from test.dbo.student WHERE snum = #studentnumber)
SELECT #facultyname = FNAME from test.dbo.faculty f join test.dbo.student s ON s.DEPT_ID = f.DEPT_ID where s.snum in
(SELECT snum FROM test.dbo.enrolled WHERE snum = #studentnumber and CNAME = #coursename);
SELECT #meetat = meets_at, #location = room FROM test.dbo.class WHERE cname IN (SELECT cname FROM test.dbo.enrolled
WHERE snum = #studentnumber and cname = #coursename);
IF (#studentnumber IS NOT NULL and #coursename IS NOT NULL)
BEGIN
PRINT (#studentname + #facultyname + #meetat + #location)
END;
END;
Below are the DML/DLL for table creation/insert
CREATE TABLE dbo.STUDENT
(snum int,
sname nvarchar(12),
MAJOR nvarchar(12),
DEPT_ID int,
slevel nvarchar(12),
AGE int,
CONSTRAINT STUDENT_SNUM_pk PRIMARY KEY (SNUM));
--
CREATE TABLE dbo.CLASS
(CNAME nvarchar(12),
MEETS_AT time,
ROOM nvarchar(10),
FID int,
CONSTRAINT CLASS_CNAME_pk PRIMARY KEY (CNAME));
--
CREATE TABLE dbo.ENROLLED
(SNUM int,
CNAME nvarchar(12));
--
CREATE TABLE dbo.FACULTY
(FID int,
FNAME nvarchar(40),
DEPT_ID int,
CONSTRAINT FACULTY_FID_pk PRIMARY KEY (FID));
--
CREATE TABLE dbo.DEPARTMENT
(DEPTid int,
DNAME nvarchar(100),
LOCATION nvarchar(100),
CONSTRAINT DEPARTMENT_DEPTID_pk PRIMARY KEY (DEPTID));
insert into dbo.STUDENT values (1234,'T.Banks','ME',3,'SR',19);
insert into dbo.DEPARTMENT values (1,'Computer Sciences','West Lafayette');
insert into dbo.FACULTY values (107,'Y.Walton',1);
insert into dbo.CLASS values ('ENG400',cast('08:30' as time),'U003',107);
insert into dbo.ENROLLED values (1234,'ENG400');

Is there any way to exec a stored procedure for all selected data rows?

I'm setting up a storekeeping program in which I have 2 tables, one for products and another for materials.
In the products table, each product has several materials. Is there any way to select these rows and decrement materials availability?
I tried to use a foreach loop but I couldn't implement it and store each rows data
CREATE TABLE materials
(
materialID INT PRIMARY KEY IDENTITY,
materialName NVARCHAR(100) NULL,
materialAmount INT NULL,
)
CREATE TABLE productStack
(
ID INT PRIMARY KEY IDENTITY,
productsID INT NULL,
materialID INT NULL,
amount INT NULL
)
GO;
CREATE PROCEDURE updateMaterials
(#ID INT,
#AMOUNT INT)
AS
BEGIN
UPDATE materials
SET materialAmount = (materialAmount - #AMOUNT)
WHERE materialID = #ID
END
You could use a temp table and while loop such as :
SELECT * INTO #TEMP_A FROM PRODUCTSTACK
DECLARE #ID INT,#AMOUNT INT
WHILE EXISTS(SELECT * FROM #TEMP_A)
BEGIN
SET #ID = (SELECT TOP 1 ID FROM PRODUCTSTACK)
SET #AMOUNT = (SELECT TOP 1 AMOUNT FROM PRODUCTSTACK WHERE ID = #ID)
EXEC UPDATEMATERIALS #ID,#AMOUNT
DELETE FROM #TEMP_A WHERE ID = #ID
END
As we have no sample to base this on, this is a guess. Like I said, however, seems like a table-type parameter would do this:
CREATE TYPE dbo.MaterialAmount AS table (ID int, Amount int);
GO
CREATE PROC dbo.UpdateMaterials #Materials dbo.MaterialAmount READONLY AS
BEGIN
UPDATE M
SET materialAmount = MA.Amount
FROM dbo.materials M
JOIN #Materials MA ON M.materialID = MA.ID;
END;
GO
--Example of usage:
DECLARE #Materials dbo.MaterialAmount;
INSERT INTO #Materials
VALUES(1,100),
(5,20);
EXEC dbo.UpdateMaterials #Materials;

Use an output parameter of store procedure in update Statement

Hi I have a store procedure which insert data into a table1 and there is another store procedure which insert data in table2 I need to insert table2.ID in table1 while updating I am calling second store procedure in first and it returns me the Id as an output parameter but it didn't get updated.
SP1 :
ALTER PROCEDURE [dbo].[updateSP]
#prm1 varchar(30),
#prm2 varchar(20),
#prm3 varchar(20),
#prm3 varchar(max)
AS
BEGIN
SET NOCOUNT OFF;
DECLARE #ID int
exec SPInsert #ID OUTPUT, #prm1, #prm2 , #prm3
update tbl1 set status = prm1, updated_by = prm2, updated_date = GETDATE(), reason_id = #ID where student_no = prm3
END
SP2 :
ALTER PROCEDURE [dbo].[SPInsert]
#prm1 varchar(30),
#prm2 varchar(20),
#prm3 varchar(20),
#prm3 varchar(max),
#ID output,
AS
BEGIN
Insert into tbl2 (student_no, reason_txt, created_by, created_date)Values(#prm1 ,#prm2 ,#prm3 , GETDATE())
Select #ID = Scope_Identity()
END

SQL Server Stored Procedure - Return varchar id of inserted row

I'm working on a cascading insertion where a stored procedure should return an id of the inserted row. This would not be a problem if the id of the table was an int. However, the id is a varchar and therefore I cannot use SCOPE_IDENTITY().
This is my procedure so far:
CREATE PROCEDURE NEW_ARTICLE
#id varchar(50) OUTPUT,
#name varchar(100),
#articleNr varchar(50),
#gategory varchar(50),
#containerId varchar(50),
#contPerContainer int,
#pictureId varchar(50)
AS
SET NOCOUNT OFF
INSERT INTO nextlabel.[Article] (name, article_nr, category, container_id, count_per_container, picture_id )
VALUES (#name, #articleNr, #gategory, #containerId, #contPerContainer, #pictureId)
SET #id = SCOPE_IDENTITY()
Where the last row is not correct since the column id is a varchar.
How can I return the id?
Try this:
CREATE PROCEDURE NEW_ARTICLE
#id varchar(50) OUTPUT,
#name varchar(100),
#articleNr varchar(50),
#gategory varchar(50),
#containerId varchar(50),
#contPerContainer int,
#pictureId varchar(50)
AS
SET NOCOUNT OFF
SET #id = newid()
INSERT INTO nextlabel.[Article] (id, name, article_nr, category, container_id, count_per_container, picture_id)
VALUES (#id, #name, #articleNr, #gategory, #containerId, #contPerContainer, #pictureId)
GO

Update the table using stored procedure

I have a table and I have 50 columns in it. From my code behind at first I am inserting 10 values using a stored procedure, after that in second page based on userid I want to update other 40 columns. So I am updating the table and the userid column of the table is an identity column which is auto incremented so how to get the user id for update stored procedure?
CREATE PROCEDURE sp_update
(#FormFiledBy varchar(50), #MaritalStatus varchar(50),
#Height varchar(50), #Religion varchar(50), #Caste varchar(100),
#MotherTongue varchar(50), #Education varchar(100),
#Occupation varchar(50), #CountryofResidence varchar(50),
#EducationDetails varchar(100), #AnnualIncome varchar(50),
#CountryOfBirth varchar(50), #BirthPlace varchar(50),
#TimeOfBirth nchar(10), #StarSign varchar(100),
#Gothram varchar(50), #Rassi varchar(50), #HavinChildren varchar(10),
#PhysicalStatus varchar (100)
)
AS
BEGIN
UPDATE Profile_Master
SET FormFiledBy = #FormFiledBy,
MaritalStatus = #MaritalStatus,
Height = #Height,
physicalStatus = #physicalStatus,
Religion = #Religion,
Caste = #Caste,
MotherTongue = #MotherTongue,
Education = #Education,
Occupation = #Occupation,
CountryofResidence = #CountryofResidence,
EducationDetails = #EducationDetails,
AnnualIncome = #AnnualIncome,
CountryOfBirth = #CountryOfBirth,
BirthPlace = #BirthPlace,
TimeOfBirth = #TimeOfBirth,
StarSign = #StarSign,
Gothram = #Gothram,
Rassi = #Rassi,
HavinChildren = #HavinChildren,
PhysicalStatus = #PhysicalStatus
WHERE
????
END
In your initial procedure, when you insert the data, you should retrieve and return the userid value in an OUTPUT parameter so that you can then supply it to your update procedure.
You can use SCOPE_IDENTITY() for this fairly easily.
As requested, some sample code (simplified, but you should see the pattern):
CREATE PROCEDURE add_row #data1 varchar(20), #data2 varchar(20), #id int OUTPUT
AS
BEGIN
INSERT INTO Table (Data1, Data2) VALUES (#data1, #data2)
SELECT #id = SCOPE_IDENTITY()
END
GO
CREATE PROCEDURE update_row #id int, #data3 varchar(20), #data4 varchar(20)
AS
BEGIN
UPDATE Table SET Data3 = #data3, Data4 = #data4
WHERE Id = #id
END
GO
you don't need update your primary key, but you must pass UserId as parameter of your stored procedure.
Update Profile_Master
Set ....
Where UserId = #UserId --your parameter
Nota : yuo must ensure that your primary key is just UserId
You just have to pass SCOPE_IDENTITY() from fist Stored Procedure as below:
#Id int OUTPUT,
---
SET #Id = SCOPE_IDENTITY()
And in the second Stored Procedure Apply the Id as an argument an Update the record based on that.
#Id VARCHAR(15)
Update Profile_Master
set ....
........
where UserId = #Id