Transaction inside the stored procedure - sql-server-2008

USE [incentive]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[usp_insert_empincentivefinal]
(#id int,
#ConsultantName varchar(50) ,
#ClientName varchar(50) ,
#StartDate varchar(50),
#PositionName varchar(20) ,
#Location varchar(20) ,
#Job_Status varchar (20),
#RecruiterName varchar(20),
#BenchMarketing varchar(1) ,
#Placement varchar(1),
#CompanyName varchar(20),
#Durations varchar(20),
#DurationofProject varchar(10)
--#out int out
)
AS
BEGIN
SET NOCOUNT ON
BEGIN TRAN
INSERT INTO [tbl_Empincentivenew1](ConsultantName, ClientName, RecruiterName, PositionName, CompanyName, Location, DurationofProject, Durations, BenchMarketing, Placement, Job_Status, StartDate)
OUTPUT INSERTED.id
DEFAULT VALUES
COMMIT
END
GO
My table is not inserted with id when I am running the procedure, but when I am executing the transaction part alone, the id value gets inserted.
Could you please help?

If you add TRAN after the commit command like this:
COMMIT TRAN
Does that help ?

Related

I want to increase or decrease the amount of money in Total_Crédit which is in Credit_electrecité depending on the event to be done

create PROCEDURE PR_Credit_Total(
in newidpiece int,
in newnpiece bigint,
in newnop varchar(60),
in newdateengagement date,
in newdatefacture date,
in newlocalité varchar(50),
in newtournee int,
in newnpolice bigint,
in newservice varchar(20),
in newmontant float,
in newecheance varchar(7),
in newcreated varchar(25),
in eventvarchar(100)
)
BEGIN
set #total=(SELECT sum(Total_Crédit) from credit_electricité) ;
if event=='ajouter'
and newtournee is null
THEN
if #total-newmontant>=0
INSERT into vignetteoneep VALUES(newidpiece,newnpiece,newnop,newdateengagement,
newdatefacture,newlocalité,newtournee,newnpolice,newservice,newmontant,newecheance,newcreated);
then
UPDATE credit_electricité set Total_Crédit=Total_Crédit-newmontant;
end if;
end if;
END
create PROCEDURE PR_Credit_Total(
#newidpiece AS int,
#newnpiece AS bigint,
#newnop AS varchar(60),
#newdateengagement AS date,
#newdatefacture AS date,
#newlocalité AS varchar(50),
#newtournee AS int,
#newnpolice AS bigint,
#newservice AS varchar(20),
#newmontant AS float,
#newecheance AS varchar(7),
#newcreated AS varchar(25),
#event AS varchar(100),
#total AS INT
)
AS
BEGIN
set #total=(SELECT sum(Total_Crédit) from credit_electricité)
if #event = 'ajouter' and #newtournee is null
if #total - #newmontant >=0
INSERT into vignetteoneep VALUES(newidpiece,newnpiece,newnop,newdateengagement,
newdatefacture,newlocalité,newtournee,newnpolice,newservice,newmontant,newecheance,newcreated)
UPDATE credit_electricité set Total_Crédit=Total_Crédit - #newmontant
END
Here's a list of syntax errors to fix
in eventvarchar(100) missing space ,should be in event varchar(100) but event is a keyword and best avoided
if event=='ajouter' null safe equal in mysql is <=> so should be if event <=> 'ajouter' but = would do
The second if does not have a then it's not clear if the insert and update should be part of same condition but I suspect not
if #total-newmontant>=0 then
INSERT ...
else
UPDATE ...
end if;
And you may need to set delimiters

Create stored procedure with updating multiple columns

I am getting the following error in my code:
MySQL said: Documentation
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'END' at line 20
CREATE PROCEDURE updateUser(
IN firstname VARCHAR(20),
IN Vlastname VARCHAR(20),
IN Vemail VARCHAR(50),
IN Vpassword VARCHAR(100),
IN Vyear INT(5),
IN Vgender VARCHAR(10),
IN Vprefer VARCHAR(200),
IN Vinterested VARCHAR(200),
IN Vabout VARCHAR(200),
IN Vid INT(11)
)
BEGIN
UPDATE users SET
name = (CASE WHEN firstname IS NOT NULL THEN firstname ELSE name
END),
lastname = (CASE WHEN vlastname IS NOT NULL THEN vlastname ELSE lastname
END)
WHERE id = Vid
END;
When developing stored procedures in MySQL, you must set a delimiter different from ; to properly end the stored program statement. This allows the use of ; to delineate multiple statements within the procedure.
Per MySQL 25.1 Defining Stored Programs docs:
If you use the mysql client program to define a stored program containing semicolon characters, a problem arises. By default, mysql itself recognizes the semicolon as a statement delimiter, so you must redefine the delimiter temporarily to cause mysql to pass the entire stored program definition to the server.
Therefore consider below adjustment:
DELIMITER // -- TEMPORARILY CHANGE DELIMITER FROM ;
CREATE PROCEDURE updateUser (
IN firstname VARCHAR(20),
IN Vlastname VARCHAR(20),
IN Vemail VARCHAR(50),
IN Vpassword VARCHAR(100),
IN Vyear INT(5),
IN Vgender VARCHAR(10),
IN Vprefer VARCHAR(200),
IN Vinterested VARCHAR(200),
IN Vabout VARCHAR(200),
IN Vid INT(11)
)
BEGIN
UPDATE `users`
SET
`name` = CASE WHEN `firstname` IS NOT NULL THEN `firstname` ELSE `name` END,
`lastname` = CASE WHEN `vlastname` IS NOT NULL THEN `vlastname` ELSE `lastname` END
WHERE `id` = Vid; -- SEMICOLON HERE TO SEPARATE STATEMENTS
END
// -- PROPERLY END PROCEDURE STATEMENT
DELIMITER ; -- RESET DELIMITER BACK TO ;
you are missing a semicolon after The WHERE clause
And you can simplify it
DELIMITER //
CREATE PROCEDURE updateUser(
IN firstname VARCHAR(20),
IN Vlastname VARCHAR(20),
IN Vemail VARCHAR(50),
IN Vpassword VARCHAR(100),
IN Vyear INT(5),
IN Vgender VARCHAR(10),
IN Vprefer VARCHAR(200),
IN Vinterested VARCHAR(200),
IN Vabout VARCHAR(200),
IN Vid INT(11)
)
BEGIN
UPDATE users SET
name = COALESCE (firstname, name),
lastname = COALESCE (vlastname,lastname)
WHERE id = Vid;
END//
DELIMITER ;

How to declare variables in mysql Stored procedure?

I want to declare a variable and then assign a value of select query to that particular variable and then I need to pass that variable in an insert statement . So I tried the below code,
DROP PROCEDURE IF EXISTS `pro_damagestockdao` $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `pro_damagestockdao`(
IN damage_date date,
IN damage_inv_no varchar(12),
IN damage_inv_date date,
IN damage_dist_name varchar(30),
IN damage_contact_no varchar(15),
IN damage_item_code varchar(30),
IN damage_item_name varchar(30),
IN damage_batch_no varchar(15),
IN damage_mfr_name varchar(50),
IN damage_expiry_date date,
IN damage_pur_qty int(11),
IN damage_qty int(11),
IN damage_unit_price double(10,2),
IN damage_unit_vat double(4,2),
IN damage_unit_discount double(4,2),
IN damage_sub_total double(10,2),
IN damage_total_amount double(10,2),
IN damage_remarks varchar(1000),
IN functionality varchar(20),
out flag int
)
BEGIN
DECLARE selCnt int;
DECLARE dqty int;
SET dqty = (SELECT free FROM purchase_invoice p WHERE p.invoice_no = damage_inv_no);
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
SET flag=0;
START TRANSACTION;
if(functionality='save') then
INSERT INTO damage_stocks
(damage_stock_date,invoice_no,invoice_date,dist_name,contact_no,item_code,item_name,batch_no,qty,damaged_qty,unit_price,unit_vat,unit_discount,sub_total,total_amount,remarks) VALUES
(damage_date,damage_inv_no,damage_inv_date,damage_dist_name,damage_contact_no,0,damage_item_name,damage_batch_no,dqty,damage_qty,damage_unit_price,damage_unit_vat,damage_unit_discount,damage_sub_total,damage_total_amount,damage_remarks);
But it fails.. You see, I declared a variable dqty and then I passed it to the insert statement.
It is not problem to declaration. It is assign problem
try this query
SELECT free into dqty FROM purchase_invoice p WHERE p.invoice_no = damage_inv_no;
The following code works fine for me:
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `pro_damagestockdao`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `pro_damagestockdao`(
IN damage_date DATE,
IN damage_inv_no VARCHAR(12),
IN damage_inv_date DATE,
IN damage_dist_name VARCHAR(30),
IN damage_contact_no VARCHAR(15),
IN damage_item_code VARCHAR(30),
IN damage_item_name VARCHAR(30),
IN damage_batch_no VARCHAR(15),
IN damage_mfr_name VARCHAR(50),
IN damage_expiry_date DATE,
IN damage_pur_qty INT(11),
IN damage_qty INT(11),
IN damage_unit_price DOUBLE(10,2),
IN damage_unit_vat DOUBLE(4,2),
IN damage_unit_discount DOUBLE(4,2),
IN damage_sub_total DOUBLE(10,2),
IN damage_total_amount DOUBLE(10,2),
IN damage_remarks VARCHAR(1000),
IN functionality VARCHAR(20),
OUT flag INT)
BEGIN
DECLARE selCnt INT;
DECLARE dqty INT;
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
SET dqty = (SELECT free FROM purchase_invoice p WHERE p.invoice_no = damage_inv_no);
SET flag = 0;
START TRANSACTION;
IF(functionality = 'save') THEN
INSERT INTO damage_stocks (damage_stock_date, invoice_no, invoice_date, dist_name, contact_no, item_code, item_name, batch_no, qty,damaged_qty, unit_price, unit_vat, unit_discount, sub_total, total_amount, remarks)
VALUES (damage_date, damage_inv_no, damage_inv_date, damage_dist_name, damage_contact_no, 0, damage_item_name, damage_batch_no, dqty,damage_qty, damage_unit_price, damage_unit_vat, damage_unit_discount, damage_sub_total, damage_total_amount, damage_remarks);
END IF;
END$$
DELIMITER ;
With this SP call:
CALL `pro_damagestockdao`("2015-06-23","rx45","2015-06-20","DistName","DContactNo","DamageItemCode","damage_item_name","damage_batch_no","damage_mfr_name", "2015-07-01", 10, 5, 15.2, 7.66, 9.88, 99.00, 150.22, "No remarks", "save", #sorin);
What error do you get?
Do you get an error when trying to create the stored procedure or when you call it?

Why does ##RowCount shows 1 row effected but SCOPE_IDENTITY() returns NULL?

i have the following stored procedure.
alter proc uspUpdtStudent
#pStudID int,
#pTitle char(10),
#pFName varchar(50),
#pLName varchar(50),
#pDOB date,
#pGender char(1),
#pIsPriorStud bit,
#pCitizen varchar(50),
#pResidency varchar(50),
#pPic varbinary(max),
--#pOldContact as dbo.Contact readonly,
#pNewContact as dbo.Contact readonly,
#pProgTrack tinyint,
#pProgID int,
#pid int output -- why not EnrID?
as
begin
SET NOCOUNT ON;
declare #tblNew as table (rw_id int identity(1,1), addL1 varchar(200), sub varchar(100), town varchar(100), post int)
select #pTitle, #pFName, #pLName, #pDOB, #pGender, #pIsPriorStud, #pCitizen, #pResidency, #pPic, #pStudID
update dbo.Students
set
Title=#pTitle,
FName=#pFName,
LName=#pLName,
DOB=#pDOB,
Gender=#pGender,
IsPriorStud=#pIsPriorStud,
Citizenship=#pCitizen,
Residency=#pResidency,
StudImg=#pPic,
DateOfRago=GETDATE()
where StudID =#pStudID
select #pStudID as 'Passed Student ID'
declare #rowcount int
set #pid = SCOPE_IDENTITY()
--select #pid
set #rowcount = ##ROWCOUNT
select #rowcount as 'Effected Row count'
if #rowcount > 0
begin
SELECT #pid as 'Student table row ID'
end
else
begin
set #pid = -1
--rollback tran
return 302
end
end
go
Then i pass theses values to the stored procedure
USE [SMSV1]
GO
declare #p13 int
set #p13=-1
declare #p14 dbo.Contact
insert into #p14 values(N'fyyyfyf',N'woeoeoo',N'kokokok',N'123456')
exec uspUpdtStudent #pStudID=100000007,#pTitle=N'Mr.',#pFName=N'George',#pLName=N'kadafi',#pDOB='1940-12-12 00:00:00',#pGender=N'M',#pIsPriorStud=0,#pCitizen=N'LIBIYA',#pResidency=N'LIBIYA',#pPic=null,#pProgID=15,#pProgTrack=2,#pid=#p13 output,#pNewContact=#p14
what is funny about is, it adds a row to the student table but when i tried to access the row id from SCOPE_IDENTITY() it shows as NULL. the IF condition executes because ##ROWCOUNT is greater than zero also As you can see in the code i have even saved the id value in a variable #pid. I have attached this video on youtube so it might help to understand understand the situation.
Here is my student table
USE [SMSV1]
GO
/****** Object: Table [dbo].[Students] Script Date: 12/18/2014 07:39:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Students](
[ID] [int] IDENTITY(1,1) NOT NULL,
[StudID] [int] NULL,
[Title] [char](10) NULL,
[FName] [varchar](50) NULL,
[LName] [varchar](50) NULL,
[DOB] [date] NULL,
[Gender] [char](1) NULL,
[IsPriorStud] [bit] NULL,
[Citizenship] [varchar](50) NULL,
[Residency] [varchar](50) NULL,
[StudImg] [varbinary](max) NULL,
[DateOfRago] [datetime] NULL,
[Updt] [datetime] NOT NULL,
[IsActive] [bit] NULL,
CONSTRAINT [PK_Students] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Students] ADD CONSTRAINT [DF_Students_Updt] DEFAULT (getdate()) FOR [Updt]
GO
thanks
##ROWCOUNT gets reset per each statement. Try the following to see:
DECLARE #Test INT;
SELECT 10 UNION ALL SELECT 20;
SELECT ##ROWCOUNT;
SELECT 10 UNION ALL SELECT 20;
SET #Test = 1;
SELECT ##ROWCOUNT;
Returns:
10
20
2
10
20
1 -- this is 1 instead of 2 due to the SET command being between the second two SELECTs
If you want SET #RowCount = ##ROWCOUNT; to be accurate, it has to be the next statement after the UPDATE. Where you currently have it (i.e. after a SET command) #rowcount will always be 1 no matter what happens with the UPDATE.
Also, there is no INSERT, so SCOPE_IDENTITY() would have to return NULL. And why would you need to dynamically get the ID anyway? Isn't it being passed into the proc via #pStudID? If for some reason the [StudID] field in the [Students] table is not the IDENTITY field, you can still get that via the OUTPUT clause:
UPDATE dbo.Students
SET
Title=#pTitle,
FName=#pFName,
LName=#pLName,
DOB=#pDOB,
Gender=#pGender,
IsPriorStud=#pIsPriorStud,
Citizenship=#pCitizen,
Residency=#pResidency,
StudImg=#pPic,
DateOfRago=GETDATE()
OUTPUT INSERTED.ID -- this is the IDENTITY field as per the CREATE TABLE statement
WHERE StudID = #pStudID;
Using the OUTPUT clause in this manner will result in a 1 row, 1 column result set ONLY IF a row is updated. If there is no matching row, there is no result set. If you want a clearer indication of no row updated than merely no result set, as I mentioned above, put the SET #RowCount = ##ROWCOUNT; just after the UPDATE and then you can test for IF (#RowCount = 0)....
IF you need the ID field in the #pid variable since it is an OUTPUT parameter, then you need to capture the result set of the UPDATE...OUTPUT into a temp table or table variable:
DECLARE #UpdatedID TABLE (ID INT);
UPDATE dbo.Students
SET
Title=#pTitle,
FName=#pFName,
LName=#pLName,
DOB=#pDOB,
Gender=#pGender,
IsPriorStud=#pIsPriorStud,
Citizenship=#pCitizen,
Residency=#pResidency,
StudImg=#pPic,
DateOfRago=GETDATE()
OUTPUT INSERTED.ID -- this is the IDENTITY field as per the CREATE TABLE statement
INTO #UpdatedID (ID)
WHERE StudID = #pStudID;
SELECT #pid = ID
FROM #UpdatedID;
IF (#pid IS NULL)
BEGIN
SET #pid = -1;
RETURN 302;
END;
From SCOPE_IDENTITY (Transact-SQL) (Bold for emphasis mine)
Returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.
You are doing an Update, not an insert, hence it is not being set.

Debugging stored procedure but no value return

My applications calls a stored procedure as required by my use case. The stored procedure insert records into two tables related by primary and foreign key constraints.
This means PatientNumber in Visit table must exist in the Patient table.
When I debug this procedure no value is display after setting initial values.
I am new to this, please help.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Add_Patient_Visit]
AS
BEGIN TRANSACTION
SET NOCOUNT ON;
declare #Visit_Number Varchar(50)
declare #Prescription_Number Varchar(50)
declare #Visit_Date Datetime = GETDate()
set #Visit_Number = '25684956555'
set #Visit_Date = GETDATE()
set #Prescription_Number = '653214658'
INSERT INTO Visits(Visit_Number, Visit_Date, Patient_Number)
VALUES(#Visit_Number, #Visit_Date, #Patient_Number)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
declare #Patient_Number Varchar(50)
declare #FirstName Varchar(50)
declare #LastName Varchar(50)
declare #Trible Varchar(50)
declare #Gender Varchar(5)
declare #Date_Of_Birth Datetime
INSERT INTO Patient(Patient_Number, FirstName, LastName, Tribe, Gender, Date_Of_Birth)
VALUES (#Patient_Number, #FirstName, #LastName, #Trible, #Gender, #Date_Of_Birth)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
COMMIT
GO
There is a mistake in above procedure. You are using #Patient_Number before declaring, while inserting in table 'Visits'. Declare it in begining, like :
declare #Patient_Number Varchar(50)
declare #Visit_Number Varchar(50)
declare #Prescription_Number Varchar(50)
declare #Visit_Date Datetime = GETDate()
set #Visit_Number = '25684956555'
set #Visit_Date=GETDATE()
set #Prescription_Number='653214658'
Insert into Visits(Visit_Number,Visit_Date,Patient_Number)
Values(#Visit_Number,#Visit_Date,#Patient_Number)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
declare #FirstName Varchar(50)
declare #LastName Varchar(50)
declare #Trible Varchar(50)
declare #Gender Varchar(5)
declare #Date_Of_Birth Datetime
INSERT INTO Patient(Patient_Number,FirstName,LastName,Tribe,Gender,Date_Of_Birth)
VALUES (#Patient_Number,#FirstName,#LastName,#Trible,#Gender,#Date_Of_Birth)
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
COMMIT