SQL Server stored procedure returning Null instead of an INtT - sql

I have this stored procedure:
#upc AS VARCHAR(13) = NULL,
#cert_code AS VARCHAR(15) = NULL,
#vendor AS INT = NULL,
#count AS INT = 0 OUTPUT,
#store AS VARCHAR(3) = NULL,
#corporate AS VARCHAR = Null,
#zone AS VARCHAR = Null,
#region AS VARCHAR = Null,
#class AS VARCHAR = Null
AS
BEGIN -- Added for new functionality
SET NOCOUNT ON;
If #store IS NOT NULL
BEGIN
-- Get the storeID from Stores
DECLARE #storeID AS INT
SELECT #storeID = StoreID
FROM Enterprise..Stores
WHERE Store = #store
END
IF #storeID IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID) AND (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID) AND (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID)
AND (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
END
If #zone IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsZone
WHERE (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsZone
WHERE (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsZone
WHERE (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
IF #region IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsRegion
WHERE (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsRegion
WHERE (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsRegion
WHERE (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
IF #class IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsClass
WHERE (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsClass
WHERE (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsClass
WHERE (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
IF #corporate IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsMaster
WHERE (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsMaster
WHERE (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsMaster
WHERE (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
GO
When I have #store IS NOT NULL it counts and returns an INT as expected, however when one of #corporate, #zone, #region, #class is set as NOT NULL, I am getting an output of null instead of an INT like expected.
What is the problem here?

I don't know if its a typo error or something else but please check you begin and ends for the IF and ELSE
From what I see the procedure ends within this set of codes as the END matches the BEGIN of the main stored procedure.
#upc AS VARCHAR(13) = NULL,
#cert_code AS VARCHAR(15) = NULL,
#vendor AS INT = NULL,
#count AS INT = 0 OUTPUT,
#store AS VARCHAR(3) = NULL,
#corporate AS VARCHAR = Null,
#zone AS VARCHAR = Null,
#region AS VARCHAR = Null,
#class AS VARCHAR = Null
AS
BEGIN -- Added for new functionality
SET NOCOUNT ON;
If #store IS NOT NULL
BEGIN
-- Get the storeID from Stores
DECLARE #storeID AS INT
SELECT #storeID = StoreID
FROM Enterprise..Stores
WHERE Store = #store
END
IF #storeID IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID) AND (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID) AND (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID)
AND (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
END -- This End is wrong should not be here
If this is just a typo please post the codes properly.
Also as others have pointed out initialize the #count parameter as zero.
It seems the remaining part of the procedure is never executed and as #count is not initialized it returns Null

Why you put varchar?
Use bellow code.
#corporate AS VARCHAR(max) = NULL,
#zone AS VARCHAR(max) = NULL,
#region AS VARCHAR(max) = NULL,
#class AS VARCHAR(max) = NULL

None of your queries should be able to assign a null to your #count variable since they all use the count() aggregate. That means none of the queries is ever run.
I do think the end just prior to the if #zone is wrong. But I'm pretty sure that the end at the end of the procedure definition must be the end of the batch. Maybe I'm wrong and your proc is actually ending earlier than you expected?
You can certainly compress a lot of that branching into your queries. Here's my attempt at it. I pared down most of the indentation and begin/end pairs.
declare #storeID as int;
if #store is not null
begin
-- Get the storeID from Stores
SELECT #storeID = StoreID
FROM Enterprise..Stores
WHERE Store = #store;
if #storeID is not null
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE StoreID = #storeID and
(
#cert_code is null and upc_code = #upc_code
or cert_code = #cert_code and (vendor = #vendor or #vendor is null)
);
end
if #zone is not null
SELECT #count = COUNT(*)
FROM Enterprise..ProductsZone
WHERE #cert_code is null and upc_code = #upc_code
or cert_code = #cert_code and (vendor = #vendor or #vendor is null);
if #region is not null
SELECT #count = COUNT(*)
FROM Enterprise..ProductsRegion
WHERE #cert_code is null and upc_code = #upc_code
or cert_code = #cert_code and (vendor = #vendor or #vendor is null);
if #class is not null
SELECT #count = COUNT(*)
FROM Enterprise..ProductsClass
WHERE #cert_code is null and upc_code = #upc_code
or cert_code = #cert_code and (vendor = #vendor or #vendor is null);

Related

Sql Scope_Identity() return Null?

I am facing this issue that my stored proc always return NULL though i have set my #output variable as well.I want to get last inserted scope Id from the table.
can someone help me where i have got wrong?
ALTER PROC spAddOrUpdateMember
#pMemberId INT = 0 ,
#pFirstName VARCHAR(50) = 'aa',
#pLastName VARCHAR(50)='aa' ,
#pMemberCode VARCHAR(15) = '12312',
#pDOB DATE = '03/10/2019',
#pGrade INT = 2 ,
#pCNIC VARCHAR(14) = '3423434',
#pFatherName VARCHAR(50) = 'asdasd' ,
#pCurrentAddress VARCHAR(MAX) = 'asds' ,
#pPermanentAddress VARCHAR(MAX) = 'fgdf',
#pEmploymentAddress VARCHAR(MAX) = 'ytuyu' ,
#pNationality INT =2
#output int = 0 output
AS
BEGIN
IF #pMemberId > 0
BEGIN
---UPDATE ME
UPDATE [dbo].[QC_Member_Profile]
SET
[FirstName] = #pFirstName
,[LastName] = #pLastName
,[DOB] = #pDOB
,[CNIC] = #pCNIC
,[FatherName] = #pFatherName
,[CurrentAddress] = #pCurrentAddress
,[PermanentAddress] = #pPermanentAddress
,[Nationality] = #pNationality
,[MemberTypeId] =#pMemberTypeId
WHERE MemberId = #pMemberId
END
ELSE
BEGIN
---INSERT ME
INSERT INTO QC_Member_Profile VALUES(
dbo.PIdentityKey(0),
#pFirstName,
#pLastName,
#pDOB,
#pCNIC,
#pFatherName,
#pCurrentAddress,
#pPermanentAddress,
#pNationality,
)
set #output = SCOPE_IDENTITY();
SELECT #output = SCOPE_IDENTITY();
select #output
END
END
I've guessed the name of your ID column, however, this should work. You'll need to amend the name of your ID column if it isn't called MemberID or if it doesn't have the data type int:
ALTER PROC spAddOrUpdateMember #pMemberId int = 0,
#pFirstName varchar(50) = 'aa',
#pLastName varchar(50) = 'aa',
#pMemberCode varchar(15) = '12312',
#pDOB date = '03/10/2019',
#pGrade int = 2,
#pCNIC varchar(14) = '3423434',
#pFatherName varchar(50) = 'asdasd',
#pCurrentAddress varchar(MAX) = 'asds',
#pPermanentAddress varchar(MAX) = 'fgdf',
#pEmploymentAddress varchar(MAX) = 'ytuyu',
#pNationality int = 2,
#output int = 0 OUTPUT
AS
BEGIN
IF #pMemberId > 0
BEGIN
UPDATE [dbo].[QC_Member_Profile]
SET [FirstName] = #pFirstName,
[LastName] = #pLastName,
[DOB] = #pDOB,
[CNIC] = #pCNIC,
[FatherName] = #pFatherName,
[CurrentAddress] = #pCurrentAddress,
[PermanentAddress] = #pPermanentAddress,
[Nationality] = #pNationality,
[MemberTypeId] = #pMemberTypeId
WHERE MemberId = #pMemberId;
END;
ELSE
BEGIN
DECLARE #ins table (OutputID int);
INSERT INTO QC_Member_Profile
OUTPUT Inserted.MemberID --guessed name
INTO #Ins
VALUES (dbo.PIdentityKey(0), #pFirstName, #pLastName, #pDOB, #pCNIC, #pFatherName, #pCurrentAddress, #pPermanentAddress, #pNationality);
SELECT #output = OutputID
FROM #ins;
SELECT #Output;
END;
END;
I've also fixed the syntax errors that were in your original question.

Function returning null

ALTER FUNCTION [dbo].[getCourseCost]
(
#CourseCode varchar(50),
#Year nchar(10),
#Period nchar(10)
)
RETURNS int
AS
BEGIN
DECLARE #Pnr_personal varchar(50)
DECLARE #Timlön_personal int
DECLARE #Antal_timmar_personal int
DECLARE #Kostnad_personal int
DECLARE #Kostnad_labass int
SELECT #Pnr_personal = Personnummer FROM Bemannas_Av WHERE Period = #Period AND Läsår = #Year AND Kurskod = #CourseCode
SELECT #Timlön_personal = Timlön FROM Personal WHERE Personnummer = #Pnr_personal
SELECT #Antal_timmar_personal = Antal_Timmar FROM Bemannas_Av WHERE Period = #Period AND Läsår = #Year AND Kurskod = #CourseCode
SELECT #Kostnad_labass = (Antal_timmar * Timlön) FROM Labass WHERE Period = #Period AND Läsår = #Year AND Kurser = #CourseCode
SET #Kostnad_personal = #Timlön_personal * #Antal_timmar_personal
IF #Kostnad_personal = NULL
BEGIN
SET #Kostnad_personal = 0
END
IF #Kostnad_labass = NULL
BEGIN
SET #Kostnad_labass = 0
END
RETURN #Kostnad_personal + #Kostnad_labass
END
This keeps returning NULL even though none of the used values are NULL in the database.
This part has a problem #Kostnad_personal=null means nothing .
IF #Kostnad_personal is NULL
BEGIN
SET #Kostnad_personal = 0
END
IF #Kostnad_labass is NULL
BEGIN
SET #Kostnad_labass = 0
END
Or use this :
RETURN ISNULL(#Kostnad_personal,0) + ISNULL(#Kostnad_labass,0)

Insert Stored Procedure with null parameters

I want to create an insert stored procedure with null parameters, if pass the value for that parameter then it has to insert or update in database
My stored procedure is:
Create proc [dbo].[SP_InsertOrUpdateCourseDetails]
#CourseID int,
#Tab1Title nvarchar(250) = null,
#Tab1Description nvarchar(max) = null,
#Tab2Title nvarchar(250) = null,
#Tab2Description nvarchar(max) = null,
#Tab3Title nvarchar(250) = null,
#Tab3Description nvarchar(max) = null,
#Tab4Title nvarchar(250) = null,
#Tab4Description nvarchar(max) = null,
#Syllabus nvarchar(max) = null
As
Begin
If NOT EXISTS (Select * from CourseDetail Where CourseID=#CourseID )
Begin
Insert into CourseDetail(CourseID, Tab1Title, Tab1Description,
Tab2Title, Tab2Description,
Tab3Title, Tab3Description, Tab4Title, Tab4Description,
Syllabus)
values (#CourseID, #Tab1Title, #Tab1Description, #Tab2Title, #Tab2Description,
#Tab3Title, #Tab3Description, #Tab4Title, #Tab4Description, #Syllabus)
IF ##ERROR = 0 AND ##ROWCOUNT =1
Begin
Select top 1 CourseID from CourseDetail Order by CourseDetailID Desc
End
Else
Begin
Select 0
End
End
Else
Begin
Update CourseDetail
SET
Tab1Title = #Tab1Title,
Tab1Description = #Tab1Description,
Tab2Title = #Tab2Title,
Tab2Description = #Tab2Description,
Tab3Title = #Tab3Title,
Tab3Description = #Tab3Description,
Tab4Title = #Tab4Title,
Tab4Description = #Tab4Description,
Syllabus = #Syllabus
Where
CourseID = #CourseID
IF ##ERROR = 0 AND ##ROWCOUNT =1
Begin
Select top 1 CourseID from CourseDetail Order by CourseDetailID Desc
End
Else
Begin
Select 0
End
End
End
You can use ISNULL function passing in it SP's parameter as first parameter and default value in case of insert or actual column's value in case of update:
Insert into CourseDetail(CourseID, Tab1Title, Tab1Description,
Tab2Title, Tab2Description,
Tab3Title, Tab3Description, Tab4Title, Tab4Description,
Syllabus)
values (#CourseID, ISNULL(#Tab1Title, 'default value'), ISNULL(#Tab1Description,'default value'), ...
Update CourseDetail
SET
Tab1Title = ISNULL(#Tab1Title, Tab1Title),
Tab1Description = ISNULL(#Tab1Description, Tab1Description),
....
Where
CourseID = #CourseID
But in this case you won't can to set NULL value explicitely even if you'll need

Dont want Select variable displaying values

It might be simple but I been having trouble figuring out.
I have a piece of code(Similar to Below Code) where I am assigning bunch of values to bunch of variables via select, it does the job but when I am running it I am getting result set which is causing my SSMS to crash is there way to avoid this....
DECLARE #Name VARCHAR(100)
DECLARE #LastName VARCHAR(100)
DECLARE #Address VARCHAR(100)
SELECT TOP 1
#Name = Name
#LastName = LastName
#Address = Address
From Person.Address
Where Name = 'Name'
Order By ID
I am using the above code in a loop where I am processing around 3-400K rows and pass this variables to a stored procedure, each top 1 select statement throws a result set causing my SSMS to crash I dont really need the select top 1 values to be displayed, any idea how to get rid of this?....
Any help would be much appreciated.
---As requested below is the code, I have hashed few things but this is what it is and I am running it from Query Analayzer as this is only 1 time process so we dont need SP to be created.
DECLARE #retstat INT
DECLARE #Name VARCHAR(255)
DECLARE #Lang TINYINT
DECLARE #Address CHAR(10)
DECLARE #ID INT
DECLARE #BranchSeqNo INT
DECLARE #AddressCode VARCHAR(10)
DECLARE #Address1 VARCHAR(50)
DECLARE #City VARCHAR(30)
DECLARE #State VARCHAR(3)
DECLARE #PostalCode VARCHAR(15)
DECLARE #Country VARCHAR(30)
SET #ID = NULL
UPDATE RAWClaimTable Set Processed = 0 where Processed is null
UPDATE RAWClaimTable SET ErrorCode = NULL ,ErrorMessage = NULL ,Processed = 0
WHERE ErrorMessage IS NOT NULL AND CLAIMID is null
WHILE EXISTS ( SELECT *
FROM RAWClaimTable
WHERE Processed = 0 )
BEGIN
-----Initialize Default Variables
SET #Lang = 0
SET #Address = 'Import'
SET #SaveMode = 0
SET #ID = Null
SELECT TOP 1
#LossDate = LossDate ,
#ClaimDate = ClaimDate ,
#OpenDate = OpenDate ,
#Receivedate = ReceiVeDate ,
#Name = Name ,
#Address = Address ,
#Address1 = Address1 ,
#City = City ,
#State = State ,
#PostalCode = PostalCode ,
#Country = Country
FROM RAWClaimTable
WHERE Processed = 0
ORDER BY ClaimID
BEGIN TRY
EXEC #RetStat = Usp_ProcessRawData #Lang, #Address, #SaveMode, #ID OUT,
#BranchSeqNo, #OriginalBranchSeqNo, #IncidentID,
#AssignmentTypeCode, #PartnershipID, #AccountID,
END TRY
BEGIN CATCH
SELECT #RetStat = ##Error
if ##Trancount > 0 rollback tran
IF #RetStat != 0
BEGIN
update RAWClaimTable set Errormessage = ERROR_MESSAGE() where ClaiMKey = #Name
END
END CATCH
IF #ID IS NOT NULL
BEGIN
UPDATE RAWClaimTable
SET ClaimID = #ID ,
Processed = 1
WHERE ClaiMKey = #Name
END
ELSE
BEGIN
UPDATE RAWClaimTable
SET Processed = 1
WHERE ClaiMKey = #Name
END
END
Use a CURSOR to loop thru your rows!
SET #Lang = 0
SET #Address = 'Import'
SET #SaveMode = 0
SET #ID = Null
DECLARE my_cursor CURSOR FOR
SELECT LossDate, ClaimDate, OpenDate, ReceiVeDate, Name, Address,
Address1, City, State, PostalCode, Country
FROM RAWClaimTable
WHERE Processed = 0
OPEN my_cursor
FETCH NEXT FROM my_cursor
INTO #LossDate, #ClaimDate, #OpenDate, #Receivedate, #Name, #Address,
#Address1, #City, #State, #PostalCode, #Country
WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN TRY
EXEC #RetStat = Usp_ProcessRawData #Lang, #Address, #SaveMode, #ID OUT,
#BranchSeqNo, #OriginalBranchSeqNo, #IncidentID,
#AssignmentTypeCode, #PartnershipID, #AccountID,
END TRY
BEGIN CATCH
SELECT #RetStat = ##Error
if ##Trancount > 0 rollback tran
IF #RetStat != 0
BEGIN
update RAWClaimTable set Errormessage = ERROR_MESSAGE()
where ClaiMKey = #Name
END
END CATCH
IF #ID IS NOT NULL
BEGIN
UPDATE RAWClaimTable
SET ClaimID = #ID ,
Processed = 1
WHERE ClaiMKey = #Name
END
ELSE
BEGIN
UPDATE RAWClaimTable
SET Processed = 1
WHERE ClaiMKey = #Name
END
FETCH NEXT FROM my_cursor
INTO #LossDate, #ClaimDate, #OpenDate, #Receivedate, #Name, #Address,
#Address1, #City, #State, #PostalCode, #Country
END

An object or column name is missing or empty

I am getting the following error
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Add a name or single space as the alias name.
for the query show below:
CREATE PROC [dbo].[Sp_Table1] #ctlg_ipt_event_id int
AS
SET NOCOUNT ON
DECLARE #current_status NCHAR(1), #ready_status_code NCHAR(1)
DECLARE #current_action NCHAR(1), #ready_action_code NCHAR(1), #done_action_code NCHAR(1)
DECLARE #pst_user_id int
SELECT #current_status = status_code
,#current_action = action_code
,#pst_user_id = last_mod_user_id
FROM merch_ctlg_ipt_event
WHERE ctlg_ipt_event_id = #ctlg_ipt_event_id
Select #ready_status_code = 'o'
, #ready_action_code = 'a'
, #done_action_code = 'b'
IF #current_status <> #ready_status_code OR #current_action <> #ready_action_code
BEGIN
RETURN
END
BEGIN TRAN
declare #rows int
,#err int
,#i int
,#name nvarchar(50) --COLLATE SQL_AltDiction_Pref_CP850_CI_AS
,#resolved_View_Name_category_id int
,#xref_value int
,#availability_start_date datetime
,#availability_end_date datetime
,#status_code int
,#last_mod_user_id int
,#CT datetime
,#supplier_id int
,#View_Name_id int
select #i = 1
,#CT = current_timestamp
Select Distinct mc.name,
mc.resolved_View_Name_category_id,
mc.xref_value,
mc.availability_start_date,
mc.availability_end_date,
mc.status_code,
CASE WHEN mc.last_mod_user_id = 42
THEN #pst_user_id
ELSE mc.last_mod_user_id
END as last_mod_user_id,
CURRENT_tsp
,IDENTITY(int,1,1) as rn
,si.supplier_id
,si.View_Name_id
into #temp
FROM View_Name AS si
JOIN merch_ctlg_ipt_View_Name AS mc
ON mc.supplier_id = si.supplier_id
AND mc.resolved_View_Name_id = si.View_Name_id
AND mc.cat_imp_event_id = #ctlg_ipt_event_id
AND mc.accept_flag = 'y'
WHERE si.shipper_flag = 'n'
select #rows=##ROWCOUNT,#err=##error
if #rows > 0 and #err=0
Begin
While #i <=#rows
begin
SElect #name = name,
#resolved_View_Name_category_id = resolved_View_Name_category_id,
#xref_value = xref_value,
#availability_start_date = availability_start_date,
#availability_end_date = availability_end_date,
#status_code = mc.status_code,
#last_mod_user_id =last_mod_user_id ,
,#i=#i+1
,#supplier_id=supplier_id
,#View_Name_id=View_Name_id
from #temp
Where rn=#i
UPDATE View_Name
SET name = #name,
View_Name_category_id = #resolved_View_Name_category_id,
xref_value = #xref_value,
availability_start_date = #availability_start_date,
availability_end_date = #availability_end_date,
status_code = #status_code,
last_mod_user_id = #last_mod_user_id ,
last_mod_timestamp = #CT
Where #sup_id = supplier_id
AND #View_Name_id = View_Name_id
AND shipper_flag = 'n'
IF ##ERROR > 0
BEGIN
ROLLBACK TRAN
RETURN
END
End
End
UPDATE
merch_ctlg_ipt_event
SET action_code = #done_action_code,
last_mod_timestamp = #CT
WHERE ctlg_ipt_event_id = #ctlg_ipt_event_id
IF ##ERROR > 0
BEGIN
ROLLBACK TRAN
RETURN
END
COMMIT TRAN
Return
go
Could you please help ?
You have 2 commas in a row here
#last_mod_user_id =last_mod_user_id ,
,#i=#i+1
Also probably not relevant to the error message but you have a line
Where #sup_id = supplier_id
but the declared variable is #supplier_id