SQL Server 2016 slow running procedure with attached plan - sql-server
The stored procedure is running very slow in SQL Server 2016 as compared to SQL Server 2019. It's doing some common validation from a temporary staging table and inserting data in primary tables and mapping tables.
The mapping tables have clustered indexes on primary keys {Table1Id, Table2Id, Table3Id}. The procedure needs to process around 4 million rows. It finishes execution in 2 hours in SQL Server 2019, but takes probably 6-8 hours in SQL Server 2016 with the same data file.
Description of the stored proc -
There is a dbo.HouseholdTemp table with all rows to be processed its doing
Slice each row and insert one portion in dbo.Locations and another
potion in dbo.Individuals table if LocationGroupId or IndividualGroupId
does not exists or is empty.
Save the generated ID from those two tables and map them in dbo.Households table {LocationId, IndividualId}.
Select an existing MailingId from dbo.Mailings table with a JOIN query.
Insert another row in dbo.ListTypes table if the combination of Type and Code does not exists and get the ListTypes Id.
Insert a row in the dbo.HouseholdMailings table with MailingId,
LocationId, IndividualId , ListTypeId.
Execution plan is attached.
FYI, The SQL installation is on C drive where as the database files are on D drive. Please help!
Execution plan can be found here : https://www.brentozar.com/pastetheplan/?id=BybjNm5a8
CREATE PROCEDURE [dbo].[usp_ProcessHouseholdDatav2]
AS
BEGIN TRY
-- Declare variables
DECLARE #DataIngestionLogId int = 0;
DECLARE #HouseholdCount bigint = 0;
DECLARE #n int = 0;
DECLARE #householdrecords int = 0;
DECLARE #householdrecordsexistscount int = 0;
DECLARE #householdmailingsrecords int = 0;
DECLARE #householdmailingsrecordsexistscount int = 0;
DECLARE #listtyperecords int = 0;
DECLARE #tempid int = 0;
DECLARE #locationid int = 0;
DECLARE #individualid int = 0;
DECLARE #mailingid int = 0;
DECLARE #jobnumber nvarchar(6) = N'';
DECLARE #mergedpanelcode nvarchar(10) = N'';
DECLARE #locationgroupid nvarchar(10) = N'';
DECLARE #individualgroupid nvarchar(10) = N'';
DECLARE #listtype varchar(3) = '';
DECLARE #listcode varchar(4) = '';
DECLARE #findernumber nvarchar(50) = N'';
DECLARE #modelrank nvarchar(2) = N'';
DECLARE #listtypeid int = 0;
DECLARE #starttime datetime = GETDATE();
INSERT INTO dbo.DataIngestionLogs (FileName,
Message,
CreatedDate)
VALUES ('usp_ProcessHouseholdData', 'PROCESS STARTED ' + CAST(#HouseholdCount AS nvarchar(10)) + ' records to be processed', GETDATE());
SET #DataIngestionLogId = SCOPE_IDENTITY();
WHILE EXISTS (SELECT TOP 1 1 FROM dbo.HouseholdTemp ht WHERE ht.ProcessedDate IS NULL /*AND #n < 1000000*/ )
BEGIN
-- Retrieve Id, JobNumber and MergedPanelCode from HouseholdTemp table
SELECT TOP 1
#tempid = ht.Id,
#jobnumber = ht.JobNumber,
#mergedpanelcode = ht.MergedPanelCode,
#locationgroupid = ht.LocationGroupID,
#individualgroupid = ht.IndividualGroupID,
#listtype = ht.ListType,
#listcode = ht.ListCode,
#findernumber = ht.FinderNumber,
#modelrank = ht.ModelRank
FROM dbo.HouseholdTemp ht
WHERE ht.ProcessedDate IS NULL;
IF (#locationgroupid IS NULL OR #locationgroupid = '')
BEGIN
INSERT INTO dbo.Locations (LocationGroupId,
Address1,
Address2,
City,
State,
Zip10,
ZipCode,
DeliveryPointCode,
FIPSCounty,
CountyName,
AddressType,
PrimaryNumber,
PreDirectional,
StreetName,
StreetSuffix,
PostDirectional,
UnitDesignator,
UnitNumber,
PMBNumber,
CarrierRoute,
PenetrationCode,
MetroName,
CreatedDate,
ModifiedDate)
SELECT TOP 1
ht.LocationGroupID AS LocationGroupID,
ht.Address1 AS Address1,
ht.Address2 AS Address2,
ht.City AS City,
ht.State AS State,
ht.Zip10 AS Zip10,
ht.ZipCode AS ZipCode,
ht.DeliveryPointCode AS DeliveryPointCode,
ht.FIPSCounty AS FIPSCounty,
ht.CountyName AS CountyName,
ht.AddressType AS AddressType,
ht.PrimaryNumber AS PrimaryNumber,
ht.PreDirectional AS PreDirectional,
ht.StreetName AS StreetName,
ht.StreetSuffix AS StreetSuffix,
ht.PostDirectional AS PostDirectional,
ht.UnitDesignator AS UnitDesignator,
ht.UnitNumber AS UnitNumber,
ht.PMBNumber AS PMBNumber,
ht.CarrierRoute AS CarrierRoute,
ht.PenetrationCode AS PenetrationCode,
ht.MetroName AS MetroName,
GETDATE(),
GETDATE()
FROM dbo.HouseholdTemp ht
WHERE ht.Id = #tempid;
SET #locationid = SCOPE_IDENTITY();
END;
ELSE
BEGIN
-- Check if record exists with LocationGroupId in Locations table
IF (NOT EXISTS (SELECT TOP 1
1
FROM dbo.Locations l
WHERE l.LocationGroupId = RTRIM(LTRIM(#locationgroupid))))
BEGIN
-- PRINT 'Location does not exists with LocationGroupId : ' + #locationgroupid + '--> Insert in Locations table....'
INSERT INTO dbo.Locations (LocationGroupId,
Address1,
Address2,
City,
State,
Zip10,
ZipCode,
DeliveryPointCode,
FIPSCounty,
CountyName,
AddressType,
PrimaryNumber,
PreDirectional,
StreetName,
StreetSuffix,
PostDirectional,
UnitDesignator,
UnitNumber,
PMBNumber,
CarrierRoute,
PenetrationCode,
MetroName,
CreatedDate,
ModifiedDate)
SELECT TOP 1
ht.LocationGroupID AS LocationGroupID,
ht.Address1 AS Address1,
ht.Address2 AS Address2,
ht.City AS City,
ht.State AS State,
ht.Zip10 AS Zip10,
ht.ZipCode AS ZipCode,
ht.DeliveryPointCode AS DeliveryPointCode,
ht.FIPSCounty AS FIPSCounty,
ht.CountyName AS CountyName,
ht.AddressType AS AddressType,
ht.PrimaryNumber AS PrimaryNumber,
ht.PreDirectional AS PreDirectional,
ht.StreetName AS StreetName,
ht.StreetSuffix AS StreetSuffix,
ht.PostDirectional AS PostDirectional,
ht.UnitDesignator AS UnitDesignator,
ht.UnitNumber AS UnitNumber,
ht.PMBNumber AS PMBNumber,
ht.CarrierRoute AS CarrierRoute,
ht.PenetrationCode AS PenetrationCode,
ht.MetroName AS MetroName,
GETDATE(),
GETDATE()
FROM dbo.HouseholdTemp ht
WHERE ht.Id = #tempid;
SET #locationid = SCOPE_IDENTITY();
END;
ELSE
BEGIN
SELECT TOP 1
#locationid = Id
FROM dbo.Locations l
WHERE l.LocationGroupId = RTRIM(LTRIM((#locationgroupid)));
END;
END;
IF (#individualgroupid IS NULL OR #individualgroupid = '')
BEGIN
INSERT INTO dbo.Individuals (IndividualGroupId,
FirstName,
LastName,
DateOfBirth,
EmailAddress,
Gender,
MaritalStatus,
CreatedDate,
ModifiedDate)
SELECT ht.IndividualGroupID AS IndividualGroupId,
ht.FirstName AS FirstName,
ht.LastName AS LastName,
CAST(ht.DateOfBirth AS date) AS DateOfBirth,
ht.EmailAddress AS EmailAddress,
ht.Gender AS Gender,
ht.MaritalStatus AS MaritalStatus,
GETDATE(),
GETDATE()
FROM dbo.HouseholdTemp ht
WHERE ht.Id = #tempid;
SET #individualid = SCOPE_IDENTITY();
END;
ELSE
BEGIN
-- Check if record exists with IndividualGroupId in Individuals table
IF (NOT EXISTS (SELECT TOP 1
1
FROM dbo.Individuals i
WHERE i.IndividualGroupId = RTRIM(LTRIM((#individualgroupid)))))
BEGIN
INSERT INTO dbo.Individuals (IndividualGroupId,
FirstName,
LastName,
DateOfBirth,
EmailAddress,
Gender,
MaritalStatus,
CreatedDate,
ModifiedDate)
SELECT ht.IndividualGroupID AS IndividualGroupId,
ht.FirstName AS FirstName,
ht.LastName AS LastName,
CAST(ht.DateOfBirth AS date) AS DateOfBirth,
ht.EmailAddress AS EmailAddress,
ht.Gender AS Gender,
ht.MaritalStatus AS MaritalStatus,
GETDATE(),
GETDATE()
FROM dbo.HouseholdTemp ht
WHERE ht.Id = #tempid;
SET #individualid = SCOPE_IDENTITY();
END;
ELSE
BEGIN
SELECT TOP 1
#individualid = Id
FROM dbo.Individuals i
WHERE i.IndividualGroupId = RTRIM(LTRIM(#individualgroupid));
END;
END;
IF (#locationid > 0 AND #individualid > 0)
BEGIN
BEGIN TRY
INSERT INTO dbo.Households (LocationId,
IndividualId,
CreatedDate)
VALUES (#locationid, #individualid, GETDATE());
SET #householdrecords = #householdrecords + 1;
END TRY
BEGIN CATCH
END CATCH;
-- Get Mailing Id from JobNumber and MergedPanelCode
SELECT TOP 1
#mailingid = m.Id
FROM dbo.Mailings m
INNER JOIN dbo.Jobs j ON j.Id = m.JobId
INNER JOIN dbo.MergedPanels mp ON mp.Id = m.MergedPanelId
WHERE j.Number = #jobnumber
AND mp.Code = #mergedpanelcode;
IF (#mailingid > 0)
BEGIN
IF ((#listtype IS NOT NULL
OR #listtype != '')
AND (#listcode IS NOT NULL
OR #listcode != ''))
BEGIN
IF NOT EXISTS (SELECT TOP 1
1
FROM dbo.ListTypes lt
WHERE lt.Type = #listtype
AND lt.Code = #listcode)
BEGIN
INSERT INTO dbo.ListTypes (Type,
Code,
CreatedDate,
ModifiedDate)
VALUES (#listtype, #listcode, GETDATE(), GETDATE());
SET #listtypeid = SCOPE_IDENTITY();
SET #listtyperecords = #listtyperecords + 1;
END;
ELSE
BEGIN
SELECT TOP 1
#listtypeid = Id
FROM dbo.ListTypes lt
WHERE lt.Type = #listtype
AND lt.Code = #listcode;
END;
END;
IF (#listtypeid > 0)
BEGIN TRY
INSERT INTO dbo.HouseholdMailings (MailingId,
LocationId,
IndividualId,
ListTypeId,
FinderNumber,
ModelRank,
CreatedDate)
VALUES (#mailingid, #locationid, #individualid, #listtypeid, #findernumber, #modelrank, GETDATE());
SET #listtypeid = 0;
SET #householdmailingsrecords = #householdmailingsrecords + 1;
END TRY
BEGIN CATCH
END CATCH;
END;
ELSE
BEGIN
SET #householdmailingsrecordsexistscount = #householdmailingsrecordsexistscount + 1;
END;
END;
-- Update the ProcessedDate in HouseholdTemp table
UPDATE dbo.HouseholdTemp
SET ProcessedDate = GETDATE()
WHERE Id = #tempid;
SET #n = #n + 1;
SET #locationid = 0;
SET #individualid = 0;
SET #mailingid = 0;
END;
INSERT INTO dbo.DataIngestionLogs (FileName,
Message,
ParentId,
CreatedDate)
VALUES ('usp_ProcessHouseholdData', 'PROCESS COMPLETED ' + CAST(#n AS nvarchar(10)) + ' records processed.', #DataIngestionLogId, GETDATE());
END TRY
BEGIN CATCH
PRINT 'Error insert...';
INSERT INTO dbo.DataIngestionErrors
VALUES (SUSER_SNAME(), ERROR_NUMBER(), ERROR_STATE(), ERROR_SEVERITY(), ERROR_LINE(), ERROR_PROCEDURE(), ERROR_MESSAGE(), GETDATE(), #DataIngestionLogId);
END CATCH;
Related
Getting error when executing the stored procedure using SQL Server
I get an error Subquery returned more than 1 value when executing a stored procedure. I need to copy data from the database I am building to the live database. The code inserted the data into TestTextmessage table and updateed TextMessage table. The error occurred when try to insert into the TestMobileRecipient table that is the reason why the table is empty. The table structure and code are below Stored procedure CREATE PROCEDURE [dbo].[TestSendITMessage] AS BEGIN SET NOCOUNT ON; DECLARE #i int DECLARE #idmessage int DECLARE #numrows int DECLARE #messagehold TABLE ( idx SMALLINT PRIMARY KEY IDENTITY(1,1), MessageId INT ) DECLARE #InsertedID INT INSERT INTO #messagehold SELECT DISTINCT Id FROM [MPFT_SendIT].dbo.TextMessage WHERE DontSendBefore < GETDATE() AND DateSent IS NULL AND MessageSent = 0 SET #i = 1 SET #numrows = (SELECT COUNT(*) FROM #messagehold) IF #numrows > 0 WHILE (#i <= (SELECT MAX(idx) FROM #messagehold)) BEGIN SET #idmessage = (SELECT MessageId FROM #messagehold WHERE idx = #i) --Do something with Id here PRINT #idmessage INSERT INTO [dbo].[TestTextMessage] ([Origin], [MessageBody], [MessageSent], [DateCreated], DontSendBefore) SELECT 'LogIT', MessageBody, 0, GETDATE(), DontSendBefore FROM [MPFT_SendIT].dbo.TextMessage WHERE Id = #idmessage SET #InsertedID = SCOPE_IDENTITY(); INSERT INTO [dbo].[TestMobileRecipient] ([MessageId], MobileNumber]) VALUES (#InsertedID, (SELECT MobileNumber FROM MobileRecipient WHERE MessageId = #idmessage)) UPDATE TextMessage SET DateSent = GETDATE(), MessageSent = 1 WHERE Id = #idmessage SET #i = #i + 1 END END
the error message is very clear. Your sub-query SELECT MobileNumber FROM MobileRecipient WHERE MessageId= #idmessage is returning more than 1 row Change the insertion of table TestMobileRecipient to following Insert into [dbo].[TestMobileRecipient] ( [MessageId] ,[MobileNumber] ) SELECT #InsertedID , MobileNumber FROM MobileRecipient WHERE MessageId= #idmessage
You should update your this line SET #idmessage = (SELECT MessageId FROM #messagehold WHERE idx = #i) with SET #idmessage = (SELECT top 1 MessageId FROM #messagehold WHERE idx = #i)
Trigger did not run?
I have a trigger "after insert/update/delete/". It is supposed to count Balance on Account table based on transactions in Transaction table. It is on Transaction table. I am getting Balance discrepancies rarely, so have decided to add some logging into it. It dumps inserted+deleted tables (they are combined into a table var) and tsql statement which fired it. Judging from my log, it looks like the trigger did not fire for some inserts into Transaction table. Can this happen ? Are there any TSQL statement which change table data without firing trigger (except truncate table etc)? Here is the trigger : CREATE TRIGGER [dbo].[trg_AccountBalance] ON [dbo].[tbl_GLTransaction] AFTER INSERT, UPDATE, DELETE AS set nocount on begin try declare #OldOptions int = ##OPTIONS set xact_abort off declare #IsDebug bit = 1 declare #CurrentDateTime datetime = getutcdate() declare #TriggerMessage varchar(max), #TriggerId int if #IsDebug = 1 begin select #TriggerId = isnull(max(TriggerId), 0) + 1 from uManageDBLogs.dbo.tbl_TriggerLog declare #dbcc_INPUTBUFFER table(EventType nvarchar(30), Parameters Int, EventInfo nvarchar(4000) ) declare #my_spid varchar(20) = CAST(##SPID as varchar(20)) insert #dbcc_INPUTBUFFER exec('DBCC INPUTBUFFER ('+#my_spid+')') select #TriggerMessage = replace(EventInfo, '''', '''''') from #dbcc_INPUTBUFFER insert into uManageDBLogs.dbo.tbl_TriggerLog (TriggerId, "Message", CreateDate) values (#TriggerId, #TriggerMessage, #CurrentDateTime) end declare #Oper int select #Oper = 0 -- determine type of sql statement if exists (select * from inserted) select #Oper = #Oper + 1 if exists (select * from deleted) select #Oper = #Oper + 2 if #IsDebug = 1 begin select #TriggerMessage = '#Oper = ' + convert(varchar, #Oper) insert into uManageDBLogs.dbo.tbl_TriggerLog (TriggerId, "Message", CreateDate) values (#TriggerId, #TriggerMessage, #CurrentDateTime) end if #Oper = 0 return -- No data changed declare #TomorrowDate date = dateadd(day, 1, convert(date, getdate())) declare #CurrentDate date = convert(date, getdate()) -- transactions from both inserted and deleted tables declare #tbl_Trans table (FirmId int, GLAccountId int, AmountDebit money, AmountCredit money, "Status" char(1), TableType char(1)) declare #tbl_AccountCounters table (FirmId int, GLAccountId int, Balance money) declare #IsChange bit = null insert into #tbl_Trans (FirmId, GLAccountId, AmountDebit, AmountCredit, "Status", TableType) select FirmId, GLAccountId, AmountDebit, AmountCredit, "Status", 'I' from inserted union select FirmId, GLAccountId, AmountDebit, AmountCredit, "Status", 'D' from deleted if #IsDebug = 1 begin select #TriggerMessage = (select * from #tbl_Trans for xml path ('tbl_Trans')) insert into uManageDBLogs.dbo.tbl_TriggerLog (TriggerId, "Message", CreateDate) values (#TriggerId, #TriggerMessage, #CurrentDateTime) end insert into #tbl_AccountCounters (FirmId, GLAccountId, Balance) select FirmId, GLAccountId, 0 from #tbl_Trans group by FirmId, GLAccountId if #Oper = 1 or #Oper = 2 -- insert/delete begin update #tbl_AccountCounters set Balance = cnt.TransSum from #tbl_AccountCounters as ac join ( select trans.FirmId, trans.GLAccountId, isnull(sum((trans.AmountDebit - trans.AmountCredit) * iif(trans.TableType = 'I', 1, -1)), 0) as TransSum from #tbl_Trans as trans where trans.Status = 'A' group by trans.FirmId, trans.GLAccountId ) as cnt on ac.FirmId = cnt.FirmId and ac.GLAccountId = cnt.GLAccountId select #IsChange = 1 end else begin if update(AmountDebit) or update(AmountCredit) or update(Status) or update(GLAccountId) begin update #tbl_AccountCounters set Balance = cnt.TransBalance from #tbl_AccountCounters as ac join (select trans.FirmId, trans.GLAccountId, isnull(sum(trans.AmountDebit - trans.AmountCredit), 0) as TransBalance from dbo.tbl_GLTransaction as trans where trans."Status" = 'A' and exists (select 1 from #tbl_AccountCounters as ac where ac.GLAccountId = trans.GLAccountId and ac.FirmId = trans.FirmId) group by trans.FirmId, trans.GLAccountId) as cnt on ac.FirmId = cnt.FirmId and ac.GLAccountId = cnt.GLAccountId select #IsChange = 0 end end if #IsDebug = 1 begin select #TriggerMessage = '#IsChange = ' + isnull(convert(varchar, #IsChange), 'null') insert into uManageDBLogs.dbo.tbl_TriggerLog (TriggerId, "Message", CreateDate) values (#TriggerId, #TriggerMessage, #CurrentDateTime) select #TriggerMessage = (select * from #tbl_AccountCounters for xml path ('tbl_AccountCounters')) insert into uManageDBLogs.dbo.tbl_TriggerLog (TriggerId, "Message", CreateDate) values (#TriggerId, #TriggerMessage, #CurrentDateTime) end if #IsChange is not null begin update tbl_GLAccount set tbl_GLAccount.Balance = iif(#IsChange = 1, cnt.Balance + acc.Balance, cnt.Balance), tbl_GLAccount.LastUpdate = getutcdate(), tbl_GLAccount.LastUpdatedBy = 1 from #tbl_AccountCounters as cnt join dbo.tbl_GLAccount as acc on cnt.FirmId = acc.FirmId and cnt.GLAccountId = acc.GLAccountId end if (16384 & #OldOptions) = 16384 set xact_abort on end try begin catch declare #ErrorLine varchar(max) select #ErrorLine = uManageDb.dbo.udf_GetErrorInfo() insert into uManageDb.dbo.tbl_TriggerError ("Name", "Message", CreateDate) values ('AccountingDB..trg_AccountBalance', #ErrorLine, GETUTCDATE()) end catch
I think I've found it. I have this line: select .. from inserted union select .. from deleted and they inserted 5 trans for $300 and 4 trans $100. I've got 2 records (300 and 100) in my #tbl_Trans (it was in the log). That's probably was the bug. So log hellps and trigger run as it had to. I'll replace union with union all.
How to insert data using XML in SQL Server 2008
The whole "inserting multiple records with XML" has pretty much been superseded by table parameters in SQL Server 2008. CREATE PROCEDURE [Booking].[PlannerQuotation] (#PlannerQuoatetionXML XML, #ResponseXML XML OUTPUT) AS BEGIN SET NOCOUNT ON; DECLARE #PlannerID INT ,#CustomerName NVARCHAR(100) ,#MobileNumber NVARCHAR(20) ,#ToAddress NVARCHAR(256) ,#Subject NVARCHAR(100) ,#Message NVARCHAR(100) ,#QuotationEmailBody NVARCHAR(100) ,#QuotationStatus NVARCHAR(100) ,#UserID INT --Comment : 1 ,#EntityID INT --Comment : 1 ,#ID INT BEGIN TRY BEGIN TRANSACTION --select details SELECT #CustomerName = Plannerxml.nref.value('./CustomerName[1]', 'NVARCHAR(100)') ,#PlannerID = Plannerxml.nref.value('./PlannerID[1]', 'INT') --Comment : 1 ,#UserID = Plannerxml.nref.value('./UserID[1]', 'INT') --Comment : 1 ,#MobileNumber = Plannerxml.nref.value('./MobileNumber[1]', 'NVARCHAR(20)') ,#ToAddress = Plannerxml.nref.value('./ToAddress[1]', 'NVARCHAR(256)') ,#Subject = Plannerxml.nref.value('(./Subject[1])', 'VARCHAR(100)') ,#Message = Plannerxml.nref.value('./Message[1]', 'NVARCHAR(100)') ,#QuotationEmailBody = Plannerxml.nref.value('(./QuotationEmailBody[1])', 'VARCHAR(100)') ,#QuotationStatus = Plannerxml.nref.value('./QuotationStatus[1]', 'NVARCHAR(100)') --,#IsSystemPlan = Plannerxml.nref.value('./IsSystemPlan[1]', 'TINYINT') --,#ExpireDate = CAST(REPLACE(REPLACE(Plannerxml.nref.value('(./ExpireDate[1])', 'varchar(22)'), 'T', ' '), 'TZ', ' ') AS DATETIME) --,#StartDate = CAST(REPLACE(REPLACE(Plannerxml.nref.value('(./StartDate[1])', 'varchar(22)'), 'T', ' '), 'TZ', ' ') AS DATETIME) -- Mode of Operation will contain 3 Options - Copy,Move,Rename FROM #PlannerQuoatetionXML.nodes('//PlannerQuoatetionRQ') AS Plannerxml(nref) --select Planner id --SELECT #plannerID = tblPlanner.colPlannerID.value('#PlannerID', 'int') --FROM #PlannerQuoatetionXML.nodes('PlannerQuoatetionRQ/Planners/Planner') tblPlanner(colPlannerID) SELECT #EntityID = P.EntityID FROM Booking.Planner WHERE PlannerID = #PlannerID AND IsActive = 1 AND ISNULL(IsDeleted, 0) = 0 -- If Operation is Copy and new planner -- create new planner IF (UPPER(#ModeofOperation) = 'COPY'AND Isnull(#CopytoPlannerID, 0) = 0) BEGIN -- Insert New planner name into Planner table IF NOT EXISTS (SELECT 1 FROM Booking.Planner WHERE PlannerName = #PlannerName AND EntityID = #EntityID AND IsActive = 1 AND ISNULL(IsDeleted, 0) = 0) BEGIN --insert into planner INSERT INTO Booking.PlannerQuotation (PlannerID, CustomerName, MobileNumber, ToAddress, Subject, Message, QuotationEmailBody, QuotationStatus, IsActive, CreatedBy, CreatedDate) VALUES (#PlannerID, #CustomerName, #MobileNumber, #ToAddress, #Subject, #Message, #QuotationEmailBody, #QuotationStatus, 1, #UserID, [Entity].[GetEntityDateTime](#EntityID)) SELECT #ID = SCOPE_IDENTITY() END ELSE BEGIN EXEC Logging.HandleError 60208, 'en-US' END END ELSE BEGIN SET #ID = #PlannerID END SET #ResponseXML = '<Response><PlannerQuotationID>'+ CAST(#ID AS VARCHAR(MAX))+'</PlannerQuotationID></Response>' --end update planner and details record COMMIT TRANSACTION END TRY BEGIN CATCH IF (##TRANCOUNT > 0) BEGIN ROLLBACK TRANSACTION END IF (ERROR_NUMBER() < 60000) BEGIN EXEC Logging.InsertFailedTransactionLog 'PlannerQuotationInsert' ,#PlannerQuotationXML END EXEC Logging.InsertLogError END CATCH END I use SQL Server 2008 in my web application back end. Apparently I iterate through all the records from the C# code whenever there is a multiple insertion scenario. I have never tried the multiple insert using XML. And I think after reading many blogs about XML manipulation using SQL Server 2008 the process is pretty tedious .. So my question is: is inserting via XML more efficient than the traditional inserts?
Data not displayed in SSRS report, but execting query in SQL shows data
I want to show some data in a report by using a stored procedure: ALTER PROCEDURE [dbo].[usp_GetThirtyDaysSims] ( #DateFrom DATETIME = NULL, #DateTo DATETIME = NULL, #O2QuarterStartDate INT = NULL, #AreaId INT = NULL, #StoreId INT = NULL, #O2MonthStartDate INT = NULL, #TransactionType NVARCHAR(1000) ) AS BEGIN DECLARE #O2Quarter AS INT DECLARE #O2Year AS INT DECLARE #O2Month AS INT IF (#AreaId = 0 OR #AreaId = 999999999) BEGIN SET #AreaId = NULL END IF (#StoreId = 0 OR #StoreId = 999999999) BEGIN SET #StoreId = NULL END IF (#O2QuarterStartDate = 0 OR #O2QuarterStartDate = 999999999) BEGIN SET #O2QuarterStartDate = NULL END IF (#O2MonthStartDate = 0 OR #O2MonthStartDate = 999999999) BEGIN SET #O2MonthStartDate = NULL END IF(#O2QuarterStartDate IS NOT NULL) BEGIN SELECT #O2Quarter = O2Quarter,#O2Year = O2Year FROM DimDate WHERE DateKey=#O2QuarterStartDate SELECT #DateFrom = MIN([Date]),#DateTo = MAX([Date]) FROM DimDate WHERE O2Quarter=#O2Quarter AND O2Year=#O2Year END IF(#O2MonthStartDate IS NOT NULL) BEGIN PRINT #O2MonthStartDate SELECT #O2Month=O2Month, #O2Quarter = O2Quarter,#O2Year = O2Year FROM DimDate WHERE DateKey=#O2MonthStartDate SELECT #DateFrom = MIN([Date]),#DateTo = MAX([Date]) FROM DimDate WHERE O2Month=#O2Month AND O2Quarter=#O2Quarter AND O2Year=#O2Year END SELECT Area,StoreName,SUM(Tariff) SumOfTariff, COUNT(1) NoOfSimsSold FROM [dbo].[ufn_GetThirtyDaysSimsData](#DateFrom,#DateTo) FT INNER JOIN DimDate DD ON FT.TransactionDateId = DD.DateKey WHERE (#DateFrom IS NOT NULL AND DD.[Date] >= #DateFrom) AND (#DateTo IS NOT NULL AND DD.[Date] <= #DateTo) AND (FT.AreaId = #AreaId OR #AreaId IS NULL) AND (FT.StoreId = #StoreId OR #StoreId IS NULL) AND (FT.TransactionType = #TransactionType OR #TransactionType IS NULL) GROUP BY Area,StoreName ORDER BY Area,StoreName END When I filter by using the 7 filters above, data is not showing on the report but there are no errors either - why might this be?
Make sure your function is table-based. You don't need to add the date parameters in the WHERE clause because you are already passing those in the function. Test your query by running it first in SSMS. Here is a simplified version of the query: SELECT Area, StoreName, SUM(Tariff) SumOfTariff, COUNT(1) NoOfSimsSold FROM [dbo].[ufn_GetThirtyDaysSimsData](#DateFrom,#DateTo) FT INNER JOIN DimDate DD ON FT.TransactionDateId = DD.DateKey WHERE FT.AreaId = #AreaId AND FT.StoreId = #StoreId AND FT.TransactionType = #TransactionType GROUP BY Area, StoreName ORDER BY Area, StoreName
varchar entry of 5118 causing SQL Server stored procedure to fail
and thanks in advance I have a very basic stored procedure that inserts a row into a table. It has been working flawlessly until today Here is the script ( #emp varchar(16), #logdate date, #logtime time, #term char(20), #SSID char(16) ) AS INSERT INTO AccessLog (EmployeeID, LogDate, LogTime, TerminalID, InOut, ChangedBy) VALUES (#emp, #logdate, #logtime, #term, 3, #SSID) When the string of 5118 is passed to it the insert will fail. There are several triggers that fire after this insert finishes. Here's the strange part. You can pass it anyother number for the #emp variable and it works just fine, but pass it 5118, it fails. The error I receive is below: Msg 241, Level 16, State 1, Procedure UpdateTimeWorked, Line 27 Conversion failed when converting date and/or time from character string. Here is the procedure that is failing – the highlighted line is Line 27 TRIGGER [dbo].[UpdateTimeWorked] ON [dbo].[TimeLog] FOR UPDATE AS SET NOCOUNT ON DECLARE #ID int; DECLARE #RCDIDIN int; DECLARE #RCDIDOUT int; DECLARE #ComboIn datetime; DECLARE #ComboOut datetime; SELECT #ID = ID FROM INSERTED; SELECT #ComboIn = LoginCombo FROM INSERTED; SELECT #ComboOut = LogoutCombo FROM INSERTED; SELECT #RCDIDIN = RCDIDIN FROM INSERTED; SELECT #RCDIDOUT = RCDIDOUT FROM INSERTED; **IF ( UPDATE(LogoutCombo))** BEGIN IF (#RCDIDOUT != 0) BEGIN UPDATE TimeLog SET LogOutRND = (select CAST(dbo.roundtime(LogOutRND,0.25) AS TIME)) WHERE ID = #ID UPDATE TimeLog SET LogOutComboRND = CAST(CAST(LogOutDate AS DATE) AS SMALLDATETIME) + CAST(LogOutRND AS TIME) WHERE ID = #ID UPDATE TimeLog SET TimeWorked = dbo.gettime(DATEDIFF(ss,LogInComboRND,LogoutComboRND)) WHERE ID = #ID AND LogInEntered = 1 AND LogOutEntered = 1 UPDATE TimeLog SET TimeWorked = (select CAST(dbo.roundtime(TimeWorked,0.25) AS TIME)), Rounded = 1 WHERE ID = #ID AND LogInEntered = 1 AND LogOutEntered = 1 END END IF ( UPDATE(LoginCombo)) BEGIN IF (#RCDIDIN != 0) BEGIN UPDATE TimeLog SET LogInRND = (select CAST(dbo.roundtime(LogInRND,0.25) AS TIME)) WHERE ID = #ID UPDATE TimeLog SET LogInComboRND = CAST(CAST(LogInDate AS DATE) AS SMALLDATETIME) + CAST(LogInRND AS TIME) WHERE ID = #ID UPDATE TimeLog SET TimeWorked = dbo.gettime(DATEDIFF(ss,LogInComboRND,LogoutComboRND)) WHERE ID = #ID AND LogInEntered = 1 AND LogOutEntered = 1 UPDATE TimeLog SET TimeWorked = (select CAST(dbo.roundtime(TimeWorked,0.25) AS TIME)), Rounded = 1 WHERE ID = #ID AND LogInEntered = 1 AND LogOutEntered = 1 END END GO I am at a total blank to come up with why this is not working. Anyone have any ideas? Like I stated, pass it any other entry for the #emp and it will run fine. I can even pass it ‘5118’ and it will work, but not 5118.