Issue in T-SQL while checking null variable - sql-server

I am writing a trigger in SQL Server like this
DECLARE #N_CATComp smallint, #EXON varchar(69), #DATEDEB varchar(15), #DATEFIN varchar(15)
SELECT
#N_CATComp = N_CATCompta,
#EXON =[Exon N°],
#DATEDEB = CONVERT(varchar(15), [Date début] , 103),
#DATEDEB = CONVERT(varchar(15), [Date début] , 103)
FROM INSERTED
IF (#N_CATComp =4) AND ( ISNULL(#EXON,'')='' OR ISNULL(#DATEDEB,'') ='' OR ISNULL(#DATEFIN,'') ='')
BEGIN
RAISERROR('false',11,1)
END
MY problem is that when #exon, #datedeb,#datefin are not null and catcomp=4 the raiserror appears which it shouldn't
i tried to elpace isnull by for example len(#EXON)=0 in this case ven if the values are null then the raiserror don't appears

Here is the same thing with all those scalar variables removed.
IF EXISTS
(
SELECT *
from inserted
where N_CATCompta = 4
AND
(
ISNULL([Exon N°], '') = ''
OR
ISNULL([Date début], '') = ''
)
)
RAISERROR('false',11,1)

Related

SQL Server: Dynamically Pivot Temp Table (Dynamic SQL)

I want to Dynamically pivot my #Tempproj table. This table consists of multiple CTE's that I insert into this #Tempproj. Now I want to Pivot this temptable, however I currently can only do it now when I create a Physical table instead of a Temporary one.
When I run it with the following query it says:
Must declare the table variable "#Tempproj"
I don't know how to mix this SQL with Dynamic SQL correctly.
First I declare a temp table, quite a long statement, and all the way below is the Dynamic SQL Pivot query I use.
CREATE TABLE #Tempproj
(
[ProjKey] nvarchar(250) NULL
,[Lvl3] nvarchar(250) NULL
,[Lvl2] nvarchar(250) NULL
,[Lvl1] nvarchar(250) NULL
,[Element ID] nvarchar(250) NULL
,[Activiteit] nvarchar(250) NULL
,[Doel] nvarchar(250) NULL
,[Activiteitsnummer] nvarchar(250) NULL
,[Begindatum/-tijd] date NULL
,[Einddatum/-tijd] date NULL
,[Status projectfase] nvarchar(250) NULL
,[Afsluitingsdatum/-tijd] date NULL
,[Projectactiviteit] nvarchar(250) NULL
,[VerantwoordelijkeId] nvarchar(250) NULL
,[Verantwoordelijke] nvarchar(250) NULL
,[Categorie] nvarchar(250) NULL
,[Prioriteit] nvarchar(250) NULL
,[DataAreaID] nvarchar(250) NULL
);
WITH cteP AS (
SELECT
[NAME]
,ELEMENTNUMBER
,PARENTELEMENTNUMBER
,PathID = CAST(ELEMENTNUMBER AS VARCHAR(MAX))
,DATAAREAID
FROM HIERARCHYTREETABLE
WHERE NULLIF(PARENTELEMENTNUMBER, '') IS NULL
UNION All
SELECT
[NAME] = r.[NAME]
,ELEMENTNUMBER = r.ELEMENTNUMBER
,PARENTELEMENTNUMBER = r.PARENTELEMENTNUMBER
,PathID = p.PathID+CONCAT(',',CAST(r.ELEMENTNUMBER AS VARCHAR(MAX)))
,DATAAREAID = r.DATAAREAID
FROM HIERARCHYTREETABLE r
JOIN cteP p ON r.PARENTELEMENTNUMBER = p.ELEMENTNUMBER
AND r.DATAAREAID = p.DATAAREAID
)
,
cteP2 AS (
SELECT
B.Lvl3
,B.Lvl2
,B.Lvl1
,HIERARCHYTREETABLE.ELEMENTNUMBER AS 'Element ID'
,HIERARCHYTREETABLE.[NAME] AS 'Activiteit'
,SMMACTIVITIES.PURPOSE AS 'Doel'
,SMMACTIVITIES.ACTIVITYNUMBER AS 'Activiteitsnummer'
,SMMACTIVITIES.STARTDATETIME AS 'Begindatum/-tijd'
,NULLIF(SMMACTIVITIES.ENDDATETIME, '') AS 'Einddatum/-tijd'
,CASE WHEN SMMACTIVITIES.CLOSED = 1 THEN 'Gesloten' ELSE 'Open' END AS 'Status projectfase'
,NULLIF(SMMACTIVITIES.ACTUALENDDATETIME, '') AS 'Afsluitingsdatum/-tijd'
,SMMACTIVITIES.PROJACTID AS 'Projectactiviteit'
,SMMACTIVITIES.RESPONSIBLEEMPLOYEE AS 'VerantwoordelijkeId'
,DIRPARTYTABLE.[NAME] AS 'Verantwoordelijke'
,CASE SMMACTIVITIES.CATEGORY
WHEN 0 THEN 'Afspraak'
WHEN 1 THEN 'Taak'
WHEN 2 THEN 'Actie'
WHEN 3 THEN 'Melding'
END AS Categorie
,CASE SMMACTIVITIES.TASKPRIORITY
WHEN 0 THEN 'Normaal'
WHEN 1 THEN 'Laag'
WHEN 2 THEN 'Hoog'
END AS Prioriteit
,HIERARCHYTREETABLE.DATAAREAID
FROM HIERARCHYTREETABLE
LEFT JOIN cteP
ON cteP.ELEMENTNUMBER = HIERARCHYTREETABLE.ELEMENTNUMBER
AND cteP.DATAAREAID = HIERARCHYTREETABLE.DATAAREAID
CROSS Apply (
SELECT Lvl1 = xDim.value('/x[3]','varchar(50)')
,Lvl2 = xDim.value('/x[2]','varchar(50)')
,Lvl3 = xDim.value('/x[1]','varchar(50)')
,Lvl4 = xDim.value('/x[4]','varchar(50)')
FROM ( VALUES (CAST('<x>' + REPLACE(PathID,',','</x><x>')+'</x>' AS xml))) B(xDim)
) B
LEFT JOIN SMMACTIVITIES
ON SMMACTIVITIES.RECID = HIERARCHYTREETABLE.REFRECID
AND SMMACTIVITIES.DATAAREAID = HIERARCHYTREETABLE.DATAAREAID
LEFT JOIN EMPLTABLE
ON SMMACTIVITIES.RESPONSIBLEEMPLOYEE = EMPLTABLE.EMPLID
LEFT JOIN DIRPARTYTABLE
ON DIRPARTYTABLE.PARTYID = EMPLTABLE.PARTYID
AND DIRPARTYTABLE.DATAAREAID = EMPLTABLE.DATAAREAID
)
INSERT INTO #Tempproj(
[ProjKey],Lvl1,Lvl2,Lvl3,[Element ID]
,Activiteit,Doel,Activiteitsnummer,[Begindatum/-tijd],[Einddatum/-tijd],[Status projectfase]
,[Afsluitingsdatum/-tijd],Projectactiviteit,VerantwoordelijkeId
,Verantwoordelijke,Categorie,Prioriteit,DataAreaID)
SELECT
PROJTABLE.PROJID + '-' + PROJTABLE.DATAAREAID AS 'ProjKey'
,cteP2.*
FROM CteP2
LEFT JOIN HIERARCHYTREETABLE
ON HIERARCHYTREETABLE.ELEMENTNUMBER = CteP2.Lvl3
AND HIERARCHYTREETABLE.DATAAREAID = CteP2.DataAreaId
LEFT JOIN PROJTABLE
ON PROJTABLE.PROJID = HIERARCHYTREETABLE.[NAME]
AND PROJTABLE.DATAAREAID = HIERARCHYTREETABLE.DATAAREAID
WHERE Activiteit NOT LIKE 'MLD%'
AND Activiteit NOT LIKE 'O-%'
AND Activiteit NOT LIKE 'OTR%'
AND SUBSTRING(Activiteit, 1, 1) NOT IN ('1','2','3','4','5','6','7','8','9');
DECLARE #Columns as VARCHAR(MAX)
SELECT
#Columns = COALESCE(#Columns + ', ','') + QUOTENAME(Activiteit)
FROM
(SELECT DISTINCT Activiteit FROM #Tempproj
) AS B
ORDER BY B.Activiteit
DECLARE #SQL as VARCHAR(MAX)
SET #SQL = 'SELECT ProjKey, ' + #Columns + '
FROM
(
SELECT T.ProjKey,
T.Activiteit,
T.[Begindatum/-tijd]
FROM #Tempproj T
) as PivotData
PIVOT
(
max([Begindatum/-tijd])
FOR Activiteit IN (' + #Columns + ')
) AS PivotResult
ORDER BY ProjKey'
EXEC (#SQL)
Then when I run the query, it says that I haven't declared my #Tempproj table yet.
Now I see that I mix up SQL with Dynamic SQL, but I don't know how to fix this giant statement into this.
Any suggestions what I could do here?
EDIT: Table Variable replaced with an actual Temporary Table.

How to convert YES/NO to BIT automatically in SQL Server?

I want to override system defined conversion in SQL Server. is that possible.
Problem Statement
I have a large csv file to upload data in database. There is a column with BIT type contains True/False, Yes/No, 1/0
When I used bulk insertion True/False and '1/0' will be consider as right value but Yes/No (as expected) will throw an conversion error.
Is there any way to convert Yes/No without any looping or one by one value?
Edit
Custom data type PanelMemberType
CREATE TYPE [dbo].[PanelMemberType] AS TABLE(
[Email] [nvarchar](255) NOT NULL,
[LocationName] [nvarchar](255) NOT NULL,
[OptInPermission] [nvarchar](255) NOT NULL
)
GO
Stored procedure code:
ALTER PROCEDURE [dbo].[PanelMemberBulkUpdate]
#tblPanelMember PanelMemberType READONLY,
#PanelID int,
#UserID nvarchar(128)
AS
BEGIN
SET NOCOUNT ON;
MERGE INTO PanelMember p1
USING #tblPanelMember p2 ON p1.Email= p2.Email
WHEN MATCHED THEN
UPDATE SET
p1.PanelID = #PanelID,
p1.LocationID = (SELECT TOP(1) [LocationID]
FROM [dbo].[Location]
WHERE [LocationName] = p2.LocationName),
p1.Email = p2.Email,
p1.OptInPermission = CONVERT(BIT, p2.OptInPermission),
p1.DateAdded = p1.DateAdded,
p1.DateLastUpdated = (SELECT GETDATE()),
p1.LastUpdateUserID = #UserID
WHEN NOT MATCHED THEN
INSERT (PanelID, LocationID, Email, OptInPermission, DateAdded)
VALUES (#PanelID, (SELECT TOP(1) [LocationID]
FROM [dbo].[Location]
WHERE [LocationName] = p2.LocationName),
p2.Email, CONVERT(BIT, p2.OptInPermission),
(SELECT GETDATE()));
END
Just apply a bit more logic rather than trying to blindly convert to bit:
p1.OptInPermission = convert( bit,
CASE p2.OptInPermission
WHEN 'Yes' THEN 1
WHEN 'No' THEN 0
ELSE p2.OptInPermission END)
(Or, to avoid having to duplicate this logic in both branches of the MERGE, do it in the source:
USING (select Email,LocationName,convert( bit,
CASE p2.OptInPermission
WHEN 'Yes' THEN 1
WHEN 'No' THEN 0
ELSE p2.OptInPermission END as OptInPermission from #tblPanelMember) p2
)
Inserts records from CSV file into staging table first.
Then run the actual insert into your table and your select statement should look like this:
INSERT INTO ActualTable(column1, column2, column3)
SELECT column1
, column2
, CAST(CASE column3
WHEN 'Yes' THEN 1
WHEN 'No' THEN 0
ELSE column3
END AS BIT) AS YourBitColumn
FROM StagingTable;
Based on your approach, this should be working:
ALTER PROCEDURE [dbo].[PanelMemberBulkUpdate]
(
#tblPanelMember PanelMemberType READONLY
, #PanelID INT
, #UserID NVARCHAR(128)
)
AS
BEGIN TRY
SET NOCOUNT ON;
MERGE INTO PanelMember p1
USING #tblPanelMember p2
ON p1.Email = p2.Email
WHEN MATCHED THEN
UPDATE
SET p1.PanelID = #PanelID
, p1.LocationID = (SELECT TOP (1) [LocationID] FROM [dbo].[Location] WHERE [LocationName] = p2.LocationName)
, p1.Email = p2.Email
, p1.OptInPermission = CONVERT(BIT, CASE p2.OptInPermission
WHEN 'Yes' THEN 1
WHEN 'No' THEN 0
ELSE p2.OptInPermission
END)
, p1.DateAdded = p1.DateAdded
, p1.DateLastUpdated = GETDATE()
, p1.LastUpdateUserID = #UserID
WHEN NOT MATCHED THEN
INSERT (PanelID, LocationID, Email, OptInPermission, DateAdded)
VALUES
(
#PanelID
, (SELECT TOP (1) [LocationID] FROM [dbo].[Location] WHERE [LocationName] = p2.LocationName)
, p2.Email
, CONVERT(BIT, CASE p2.OptInPermission
WHEN 'Yes' THEN 1
WHEN 'No' THEN 0
ELSE p2.OptInPermission
END)
, GETDATE()
);
END TRY
BEGIN CATCH
THROW;
END CATCH
You cannot override default function, but you can write your own one. for instance:
CREATE FUNCTION dbo.ConvertBit
(
#Input VARCHAR(5)
)
RETURNS TABLE AS RETURN
SELECT CONVERT(BIT, CASE #Input
WHEN 'True' THEN 1
WHEN 'Yes' THEN 1
WHEN '1' THEN 1
WHEN 'False' THEN 0
WHEN 'No' THEN 0
WHEN '0' THEN 0
END AS BitColumn;
And then just query it this way:
ALTER PROCEDURE [dbo].[PanelMemberBulkUpdate]
(
#tblPanelMember PanelMemberType READONLY
, #PanelID INT
, #UserID NVARCHAR(128)
)
AS
BEGIN TRY
SET NOCOUNT ON;
MERGE INTO PanelMember p1
USING (
SELECT T.Email
, T.LocationName
, B.OptInPermission
FROM #tblPanelMember AS T
CROSS APPLY dbo.ConvertBit(T.OptInPermission) AS B(OptInPermission)
) AS p2
ON p1.Email = p2.Email
WHEN MATCHED THEN
UPDATE
SET p1.PanelID = #PanelID
, p1.LocationID = (SELECT TOP (1) [LocationID] FROM [dbo].[Location] WHERE [LocationName] = p2.LocationName)
, p1.Email = p2.Email
, p1.OptInPermission = p2.OptInPermission
, p1.DateAdded = p1.DateAdded
, p1.DateLastUpdated = GETDATE()
, p1.LastUpdateUserID = #UserID
WHEN NOT MATCHED THEN
INSERT (PanelID, LocationID, Email, OptInPermission, DateAdded)
VALUES
(
#PanelID
, (SELECT TOP (1) [LocationID] FROM [dbo].[Location] WHERE [LocationName] = p2.LocationName)
, p2.Email
, p2.OptInPermission
, GETDATE()
);
END TRY
BEGIN CATCH
THROW;
END CATCH

My stored procedure cannot show any record in application

I use this stored procedure in my application to fetch record but there is no record fetch from db using this SP.Give message that no Record found
CREATE PROCEDURE [dbo].[Proc_RptDailySummaryPTCLBillsCollection_Result]
(
#DateFrom DATETIME,
#DatTo DATETIME,
#SubOfficeID VARCHAR(200),
#GroupId INT,
#ClerkName VARCHAR(200),
#Type VARCHAR(200)
)
AS BEGIN
DECLARE #AgencyTable TABLE (
GpoId INT
, OfcId INT
, Total_Bills BIGINT
, Total_Amount BIGINT
) --Bill_Value BIGINT, Commission BIGINT,
--SET #DatTo = convert(datetime, convert(Varchar(12), #DatTo, 109) + ' 23:59:59PM')
-- Billing Summary By GPO Name
INSERT #AgencyTable (GpoId, OfcId, Total_Bills, Total_Amount) --Bill_Value, Commission,
SELECT
Bil.GroupId
, Bil.SubOfficeId
, ISNULL(COUNT(Bil.ConsumerNumber), 0) --AS Total_Bills,
-- ,ISNULL(SUM(Bil.C_Amount),0) --AS Bill_Value,
--,ISNULL(SUM(Bil.Commission),0) --AS Commission,
, ISNULL(SUM(Bil.C_Amount), 0) - ISNULL(SUM(Bil.Commission), 0) --AS Total_Amount
FROM BillTxnSO AS Bil
INNER JOIN pp_offices ofc ON Bil.GroupId = ofc.Group_Id AND Bil.SubOfficeId = ofc.OfficeCode
WHERE Bil.GroupId = #GroupId
AND TransDate BETWEEN #DateFrom AND #DatTo
GROUP BY Bil.GroupId, Bil.SubOfficeId
--select * from #AgencyTable
SELECT
ofc.OfficeName AS SubOffice
, ofc.Group_ID AS GroupID
, ISNULL(gpo.Total_Bills, 0) AS NoOfBills
, ISNULL(gpo.Total_Amount, 0) AS Amount -- isnull(gpo.Bill_Value,0)as Bill_Value , isnull(gpo.Commission,0) as Commission,
FROM #AgencyTable gpo
INNER JOIN pp_offices ofc ON ofc.Group_ID = gpo.GpoId AND gpo.OfcId = ofc.OfficeCode
ORDER BY ofc.OfficeName
END
"Give message that no record found"
Use ##ROWCOUNT
IF(##ROWCOUNT = 0)BEGIN
Select 'No record found'
return
END

Conversion failed when converting date and/or time from character string

What I am doing is using own function, which is returning string, now I want this column for ordering, and while using it for ordering it is not ordering properly because its a string, when I tried to convert as datetime it causes an error.
Any help ?
Thanks a lot.
SELECT
b.CallId,
CONVERT(VARCHAR(25), b.ETADate, 103) as'ETADate',
dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId) AS 'closingDateTime'
FROM
CallEntry AS a, CallEntrySerialNumbers AS b
WHERE
a.ASPId = 2
AND a.CompanyId = 3
AND a.CallId= b.CallId
AND a.ProdCompanyId = 1
AND b.CallCaseId IS NOT NULL
AND b.CallCaseId NOT LIKE 'NA'
AND ProdCategoryid = 1
AND a.CallDateTime > dateadd(day, -30, getdate())
AND b.StatusId = 2
ORDER BY
dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId) ASC
// what I tried and causes above error is
ORDER BY
CONVERT(DATE, dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId)) asc
EDIT-added function
ALTER FUNCTION [dbo].[ASP_getCallEntrySerialNoLastTranDateTime]
(
#CallEntrySerialNumbersId bigint
)
RETURNS varchar(500)
AS
BEGIN
DECLARE #ReturnVal NVARCHAR(500);
begin
select #ReturnVal = ( select Top 1 CONCAT(CONVERT(VARCHAR(10),CallTranEndDateTime,103),' ',CONVERT(VARCHAR(10),CallTranEndDateTime,108)) from calltransactions
where CallEntrySerialNumbersId = #CallEntrySerialNumbersId AND CallTranTypeId = 3
order by CallTranId desc)
end;
RETURN #ReturnVal;
END
Try this one -
SET DATEFORMAT dmy
SELECT *
FROM (
SELECT
b.CallId
, ETADate = CONVERT(VARCHAR(25), b.ETADate, 103)
, closingDateTime = dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId)
FROM dbo.CallEntry a
JOIN dbo.CallEntrySerialNumbers b ON a.CallId = b.CallId
WHERE a.ASPId = 2
AND a.CompanyId = 3
AND a.ProdCompanyId = 1
AND ISNULL(b.CallCaseId, '') NOT LIKE 'NA'
AND ProdCategoryid = 1
AND a.CallDateTime > DATEADD(day, -30, GETDATE())
AND b.StatusId = 2
) d
ORDER BY CAST(d.closingDateTime AS DATE)
ALTER FUNCTION [dbo].[ASP_getCallEntrySerialNoLastTranDateTime]
(
#CallEntrySerialNumbersId BIGINT
)
RETURNS VARCHAR(30)
AS BEGIN
DECLARE #ReturnVal VARCHAR(30)
SELECT #ReturnVal = (
SELECT TOP 1 CONVERT(VARCHAR(10), CallTranEndDateTime, 103) + ' ' + CONVERT(VARCHAR(10), CallTranEndDateTime, 108)
FROM dbo.CallTransactions
WHERE CallEntrySerialNumbersId = #CallEntrySerialNumbersId
AND CallTranTypeId = 3
ORDER BY CallTranId DESC
)
RETURN #ReturnVal
END

stored function returning NULL

I create the following function on MASTER db so you can replicate it without problems
ALTER FUNCTION [dbo].[sf_GetDateAggioGAP]
(#name varchar,#type_desc VARCHAR)
RETURNS DATETIME AS
BEGIN
DECLARE #RESULT DATETIME
DECLARE #DATA DATETIME
DECLARE #RIPETI INT
SET #DATA = (SELECT DISTINCT create_date as DATINI FROM sys.all_objects WHERE (name = #name) AND (TYPE_DESC = #type_desc))
SET #RIPETI = (SELECT DISTINCT OBJECT_ID as RIPETI FROM sys.all_objects WHERE (name = #name) AND (TYPE_DESC = #type_desc))
SET #RESULT=#DATA
WHILE #DATA <= getdate()
BEGIN
SET #DATA=dateadd(month,#RIPETI,#DATA)
IF #DATA > GETDATE()
BREAK
ELSE
CONTINUE
SET #RESULT=#DATA
END
RETURN #RESULT
END
When i call my function in this way "select dbo.sf_getdateaggiogap('sysrscols','system_table') as datanext from sys.all_objects where name ='sysrscols'" the result is always null
the code run correctly but the query's result is always null.
where am i wrong?
THANKS
Missing Size for parameters ....
Alter FUNCTION [dbo].[sf_GetDateAggioGAP]
(#name varchar(max),#type_desc VARCHAR(max))

Resources