Prevent INSERT of NULL values for Stored Procedure - sql-server

I'm working on a stored procedure that is supposed to update a table Order_TruckDelivery with info from another table Basket_TruckDelivery if the second table has any data. There are two columns in each of the tables: an int id and a datetime column called TruckDeliveryDate. If Basket_TruckDelivery has a date stored for the current basket id, then insert that date into the Order_TruckDelivery table.
Right now, the INSERT will execute regardless if there is anything in the Basket_TruckDelivery table, and this results in a NULL value for the TruckDelveryDate column in the Order_TruckDelivery column. I want to prevent this from happening but am not entirely sure how. Basically, I only want to perform and INSERT into the Order_TruckDelivery table IF the value of TruckDeliveryDate in Basket_TruckDelivery is NOT empty or null.
This is what I have so far...I have not done much work with stored procedures, so I am not sure what I've missed....
ALTER PROCEDURE [dbo].[SaveTruckIntoOrder]
#BasketID INT,
#OrderID INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE
#TruckDeliveryDate DATETIME
IF(EXISTS(SELECT uidBasket FROM [Basket_TruckDelivery] WHERE [uidBasket] = #BasketID))
BEGIN
SELECT
#TruckDeliveryDate = [TruckDeliveryDate]
FROM
[Basket_TruckDelivery]
WHERE
[uidBasket] = #BasketID
END
BEGIN
INSERT INTO [Order_TruckDelivery] ([uidOrder], [TruckDeliveryDate])
VALUES (#OrderID, #TruckDeliveryDate)
END
END

ALTER PROCEDURE [dbo].[SaveTruckIntoOrder] #BasketID INT
,#OrderID INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #TruckDeliveryDate DATETIME
IF (
EXISTS (
SELECT uidBasket
FROM [Basket_TruckDelivery]
WHERE [uidBasket] = #BasketID
)
)
BEGIN
SELECT #TruckDeliveryDate = [TruckDeliveryDate]
FROM [Basket_TruckDelivery]
WHERE [uidBasket] = #BasketID
END
IF (
#TruckDeliveryDate IS NOT NULL
AND #TruckDeliveryDate != ''
)
BEGIN
INSERT INTO [Order_TruckDelivery] (
[uidOrder]
,[TruckDeliveryDate]
)
VALUES (
#OrderID
,#TruckDeliveryDate
)
END
END

Related

Not updating records in table through stored procedure ,Not showing any errors . resulting as zero rows affected

create procedure dailyconuntupdate
(
#count bigint,
#GeneratedDate datetime = NULL
)
as
IF #GeneratedDate is null
set #GeneratedDate= getdate()
Begin
update sentcount set Sentcontentcount= #count;
End
Exec dbo.dailyconuntupdate #count=1000

insert data into sql table and get recent inserted iD and insert data in same table from different table

Here is the situation that I have to insert profile photos in the SQL table. But here are 2 scenarios the condition
if user is inserting photo and data from front end. Its working perfectly fine.
if user is skip the photo and just inserting his biography then in that case the default image should be inserted by default. I tried to do in front end Just adding dummy image in if else condition, but in DMZ server for some reason this is creating problem, on local server its working good.
Here is the Query...
ALTER PROCEDURE [dbo].[SavePhysicianBiodata]
-- Add the parameters for the stored procedure here
#ID int,
#Physician_Bio nvarchar(MAX),
#Physician_Mnemonic nvarchar(MAX),
#Physician_Image image,
#Physician_ImageType nvarchar(MAX),
#Physician_ImageFileName nvarchar(MAX)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
if( #ID is null OR #ID='')
begin
--if not image then deafult image will be applied
if((#Physician_ImageType is null or #Physician_ImageType='') and
(#Physician_ImageFileName is null or #Physician_ImageFileName='') )
begin
insert into Physician_Biodata(Physician_Bio, Physician_Mnemonic)
values(#Physician_Bio, #Physician_Mnemonic)
set #ID = SCOPE_IDENTITY()
update [dbo].[Physician_Biodata]
set Physician_Image=#Physician_Image,
Physician_ImageType=#Physician_ImageType,
Physician_ImageFileName=#Physician_ImageFileName
where ID=#ID
end
else
begin
-- Insert statements for procedure here when user adds photo as well
insert into Physician_Biodata(Physician_Bio, Physician_Mnemonic,
Physician_Image, Physician_ImageType, Physician_ImageFileName)
values(#Physician_Bio, #Physician_Mnemonic,
#Physician_Image,#Physician_ImageType,#Physician_ImageFileName)
end
end
else
begin
update [dbo].[Physician_Biodata]
set Physician_Bio=#Physician_Bio,
Physician_Mnemonic=#Physician_Mnemonic,
Physician_Image=#Physician_Image,
Physician_ImageType=#Physician_ImageType,
Physician_ImageFileName=#Physician_ImageFileName
where ID=#ID
end
END
In this query I also tried insert query which is given below
insert into Physician_Biodata(ID, Physician_Image, Physician_ImageType, Physician_ImageFileName)
select #ID, dd.Physician_Image,dd.Physician_ImageType,dd.Physician_ImageFileName from DefaultImage as dd
join Physician_Biodata
on Physician_Biodata.Physician_ImageFileName = dd.Physician_ImageFileName
where Physician_Biodata.ID = #ID
but getting error during execute procedure
Msg 544, Level 16, State 1, Procedure dbo.SavePhysicianBiodata, Line 35 [Batch Start Line 2]
Cannot insert explicit value for identity column in table 'Physician_Biodata' when IDENTITY_INSERT is set to OFF.
If somebody can help me it would be great.. Thanks in advance.
Yes I have already changed the first insert statement (removed ID) and
updated the 2nd query
set #ID = IDENT_CURRENT('Physician_Biodata')
update Physician_Biodata
set Physician_Biodata.Physician_Image= DefaultImage.Physician_Image, Physician_Biodata.Physician_ImageType= DefaultImage.Physician_ImageType, Physician_Biodata.Physician_ImageFileName=DefaultImage.Physician_ImageFileName from Physician_Biodata, DefaultImage where Physician_Biodata.ID=#ID
and it worked
It appears that Physician_Biodata's ID column is an IDENTITY, hence the exception you have.
Changing this...
INSERT INTO Physician_Biodata (
ID, Physician_Image, Physician_ImageType, Physician_ImageFileName
)
SELECT
#ID,
dd.Physician_Image,
dd.Physician_ImageType,
dd.Physician_ImageFileName
FROM DefaultImage AS dd
JOIN Physician_Biodata
ON Physician_Biodata.Physician_ImageFileName = dd.Physician_ImageFileName
WHERE
Physician_Biodata.ID = #ID;
To this...
INSERT INTO Physician_Biodata (
Physician_Image, Physician_ImageType, Physician_ImageFileName
)
SELECT
dd.Physician_Image,
dd.Physician_ImageType,
dd.Physician_ImageFileName
FROM DefaultImage AS dd
JOIN Physician_Biodata
ON Physician_Biodata.Physician_ImageFileName = dd.Physician_ImageFileName
WHERE
Physician_Biodata.ID = #ID;
Will make your "explicit value" exception go away as in your INSERT you are attempting to insert #ID into ID which is an identity column. You also use ID = #ID in your WHERE clause, which makes inserting #ID pointless as this would be a chicken-and-egg issue.
On another note, if #Physician_ImageType and #Physician_ImageFileName are both NULL going in, they'll still be NULL on your UPDATE given your existing SP's logic.
I've taken a little liberty to tidy/simplify your T-SQL and added a note about what I've questioned.
ALTER PROCEDURE [dbo].[SavePhysicianBiodata] (
#ID int,
#Physician_Bio nvarchar(MAX),
#Physician_Mnemonic nvarchar(MAX),
#Physician_Image image,
#Physician_ImageType nvarchar(MAX),
#Physician_ImageFileName nvarchar(MAX)
)
AS
BEGIN
SET NOCOUNT ON;
IF ISNULL( #ID, '' ) = ''
BEGIN
--if not image then deafult image will be applied
IF ISNULL( #Physician_ImageType, '' ) = '' AND ISNULL( #Physician_ImageFileName, '' ) = ''
BEGIN
INSERT INTO Physician_Biodata ( Physician_Bio, Physician_Mnemonic )
VALUES ( #Physician_Bio, #Physician_Mnemonic ) ;
SET #ID = SCOPE_IDENTITY();
/*
Where are you setting the values for #Physician_Image, #Physician_ImageType, and #Physician_ImageFileName? These are still NULL?
*/
UPDATE [dbo].[Physician_Biodata]
SET
Physician_Image = #Physician_Image,
Physician_ImageType = #Physician_ImageType,
Physician_ImageFileName = #Physician_ImageFileName
WHERE
ID = #ID;
END
ELSE BEGIN
-- Insert statements for procedure here when user adds photo as well
INSERT INTO Physician_Biodata (
Physician_Bio, Physician_Mnemonic, Physician_Image, Physician_ImageType, Physician_ImageFileName
)
VALUES (
#Physician_Bio, #Physician_Mnemonic, #Physician_Image, #Physician_ImageType, #Physician_ImageFileName
);
END
END
ELSE BEGIN
UPDATE [dbo].[Physician_Biodata]
SET
Physician_Bio = #Physician_Bio,
Physician_Mnemonic = #Physician_Mnemonic,
Physician_Image = #Physician_Image,
Physician_ImageType = #Physician_ImageType,
Physician_ImageFileName = #Physician_ImageFileName
WHERE
ID = #ID;
END
END

How to get and use the value returned by a stored procedure to a INSERT INTO... SELECT... statement

I am just new in SQL language and still studying it. I'm having hard time looking for answer on how can I use the stored procedure and insert value into a table.
I have this stored procedure:
CREATE PROCEDURE TestID
AS
SET NOCOUNT ON;
BEGIN
DECLARE #NewID VARCHAR(30),
#GenID INT,
#BrgyCode VARCHAR(5) = '23548'
SET #GenID = (SELECT TOP (1) NextID
FROM dbo.RandomIDs
WHERE IsUsed = 0
ORDER BY RowNumber)
SET #NewID = #BrgyCode + '-' + CAST(#GenID AS VARCHAR (30))
UPDATE dbo.RandomIDs
SET dbo.RandomIDs.IsUsed = 1
WHERE dbo.RandomIDs.NextID = #GenID
SELECT #NewID
END;
and what I'm trying to do is this:
INSERT INTO dbo.Residents([ResidentID], NewResidentID, [ResLogdate],
...
SELECT
[ResidentID],
EXEC TestID ,
[ResLogdate],
....
FROM
source.dbo.Resident;
There is a table dbo.RandomIDs containing random 6 digit non repeating numbers where I'm pulling out the value via the stored procedure and updating the IsUsed column of the table to 1. I'm transferring data from one database to another database and doing some processing on the data while transferring. Part of the processing is generating a new ID with the required format.
But I can't get it to work Sad I've been searching the net for hours now but I'm not getting the information that I need and that the reason for my writing. I hope someone could help me with this.
Thanks,
Darren
your question is little bit confusing, because you have not explained what you want to do. As i got your question, you want to fetch random id from randomids table and after performed some processing on nextid you want to insert it into resident table [newresidentid] and end of the procedure you fetch data from resident table. if i get anything wrong feel free to ask me.
your procedure solution is following.
CREATE PROCEDURE [TestId]
AS
SET NOCOUNT ON;
BEGIN
DECLARE #NEWID NVARCHAR(30)
DECLARE #GENID BIGINT
DECLARE #BRGYCODE VARCHAR(5) = '23548'
DECLARE #COUNT INTEGER
DECLARE #ERR NVARCHAR(20) = 'NO IDS IN RANDOM ID'
SET #COUNT = (SELECT COUNT(NEXTID) FROM RandomIds WHERE [IsUsed] = 0)
SET #GENID = (SELECT TOP(1) [NEXTID] FROM RandomIds WHERE [IsUsed] = 0 ORDER BY [ID] ASC)
--SELECT #GENID AS ID
IF #COUNT = 0
BEGIN
SELECT #ERR AS ERROR
END
ELSE
BEGIN
SET #NEWID = #BRGYCODE + '-' + CAST(#GENID AS varchar(30))
UPDATE RandomIds SET [IsUsed] = 1 WHERE [NextId] = #GENID
INSERT INTO Residents ([NewResidentId] , [ResLogDate] ) VALUES (#NEWID , GETDATE())
SELECT * FROM Residents
END
END
this procedure will fetch data from your randomids table and perform some processing on nextid than after it directs insert it into resident table and if you want to insert some data through user you can use parameter after declaring procedure name
E.G
CREATE PROCEDURE [TESTID]
#PARAM1 DATATYPE,
#PARAM2 DATATYPE
AS
BEGIN
END
I'm not convinced that your requirement is a good one but here is a way to do it.
Bear in mind that concurrent sessions will not be able to read your update until it is committed so you have to kind of "lock" the update so you will get a block until you're going to commit or rollback. This is rubbish for concurrency, but that's a side effect of this requirement.
declare #cap table ( capturedValue int);
declare #GENID int;
update top (1) RandomIds set IsUsed=1
output inserted.NextID into #cap
where IsUsed=0;
set #GENID =(select max( capturedValue) from #cap )
A better way would be to use an IDENTITY or SEQUENCE to solve your problem. This would leave gaps but help concurrency.

SQL trigger on update or delete

I have to have one single trigger that fires on either the UPDATE OR DELETE operations. I have the trigger working fine for when one certain column is updated. However, I need different logic for when a DELETE operation was fired. How would I have both logic inside of one trigger? Here is what I have so far:
ALTER TRIGGER [dbo].[Audit_Emp_Trigger]
ON [dbo].[EMPLOYEE]
AFTER UPDATE, DELETE
AS
BEGIN
--Only execute the trigger if the Dno field was updated or deleted
IF UPDATE(Dno)
BEGIN
--If the Audit_Emp_Record table does not exist already, we need to create it
IF OBJECT_ID('dbo.Audit_Emp_Record') IS NULL
BEGIN
--Table does not exist in database, so create table
CREATE TABLE Audit_Emp_Record
(
date_of_change smalldatetime,
old_Lname varchar (50),
new_Lname varchar (50),
old_ssn int,
new_ssn int,
old_dno int,
new_dno int
);
--Once table is created, insert the values of the update operation into the table
INSERT INTO Audit_Emp_Record(date_of_change, old_Lname, new_Lname, old_ssn, new_ssn, old_dno, new_dno) SELECT GETDATE(), D.Lname, I.Lname, D.Ssn, I.Ssn, D.Dno, I.Dno FROM inserted I JOIN deleted D ON I.Ssn = D.Ssn
END
ELSE
BEGIN
--The table already exists, so simply insert the new values of the update operation into the table
INSERT INTO Audit_Emp_Record(date_of_change, old_Lname, new_Lname, old_ssn, new_ssn, old_dno, new_dno) SELECT GETDATE(), D.Lname, I.Lname, D.Ssn, I.Ssn, D.Dno, I.Dno FROM inserted I JOIN deleted D ON I.Ssn = D.Ssn
END
END
END
You can test for the type of operation by seeing which of the magic-/pseudo-tables -- INSERTED and DELETED have data in them. I prefer to use something like the following:
DECLARE #Operation CHAR(1);
IF (EXISTS(SELECT * FROM inserted))
BEGIN
IF (EXISTS(SELECT * FROM deleted))
BEGIN
-- rows in both has to be an UPDATE
SET #Operation = 'U';
END;
ELSE
BEGIN
-- no rows in "deleted" has to be an INSERT
SET #Operation = 'I';
END;
END;
ELSE
BEGIN
-- no rows in "inserted" has to be a DELETE
SET #Operation = 'D';
END;
You can then use the #Operation variable in an IF statement to do one or the other of those operations.
Something like:
IF (#Operation = 'U')
BEGIN
--Only execute the trigger if the Dno field was updated or deleted
IF UPDATE(Dno)
BEGIN
{your current code here}
END;
END;
ELSE
BEGIN
{what to do if the operation is a DELETE goes here}
END;
Technically you don't need the ELSE condition that sets #Operation = 'I';, but if you are going to copy/paste this code into various triggers or keep around as a template then no harm in it handling all three conditions.
Also, just as a side-note, you don't need the ELSE condition of the IF OBJECT_ID('dbo.Audit_Emp_Record') IS NULL statement, nor the INSERT INTO Audit_Emp_Record that is just after the CREATE TABLE but before the END. Just do the CREATE TABLE if it doesn't exist and then do the INSERT outside of that test. Meaning:
IF UPDATE(Dno)
BEGIN
--If the Audit_Emp_Record table does not exist already, we need to create it
IF OBJECT_ID('dbo.Audit_Emp_Record') IS NULL
BEGIN
--Table does not exist in database, so create table
CREATE TABLE Audit_Emp_Record
...
END
INSERT INTO Audit_Emp_Record(...)
END

Efficiently return a value from a stored procedure

I have query which returns single value (i.e) count. I'm exceuting it using the stored procedure in the following way and using execute reader with dataset to get single value
CREATE PROCEDURE GetCnt
#EmpNo char(4)
AS
BEGIN
SET NOCOUNT ON;
Declare #Cnt int
SELECT #Cnt = count(*)
FROM employees
WHERE EMPLNO = #EmpNo
AND test = 'p'
BEGIN
SELECT #Cnt
END
END
is this effcient way
or Do I need to use the execute.scalar() and return value directly from the query instead of assigning to #cnt
can any one advise me
All ExecuteScalar does is get the first field from the first record.
Can't you just SELECT the count directly?
BEGIN
SET NOCOUNT ON
SELECT Count(*) FROM employees WHERE EMPLNO = #EmpNo AND test='p'
END
You do not need to create the variable. You just need the following:
CREATE PROCEDURE GetCnt
#EmpNo char(4)
AS
BEGIN
SET NOCOUNT ON;
SELECT count(1)
FROM employees
WHERE EMPLNO = #EmpNo
AND test = 'p'
END
Since this is only one value being returned from the stored procedure, you will likely want to use ExecuteScalar()

Resources