Select a Variable TimeSpan with an Arbitrary End point - asp.net

I've been working on a Stored Procedure that checks the time, then retrieves records going back over the last full 24 hour period between 8am and the previous 8am. So, for instance, assume that it's currently 10am. The stored procedure looks at the current time, notes that it is past 8am, and sets the query to run backwards 24 hours, from 8am today to 8a yesterday. If it were, say, 7am, the query would be set to check from 8am yesterday to 8am the day before. This was actually relatively simple to do. The SP is meant to be used to retrieve records for a report tracking jobs completed in the given time span.
However, they've come back at me and asked me to change the stored procedure such that the hour the report ends at, and the span of time checked, is configurable from the front-end of the site. I have this working for TimeSpans greater or equal to 24 hours, but am having trouble with spans under that. Here's what I have so far for my logic in the Stored Procedure -
-- Retrieves data on jobs that completed/completed with errors during a given time span.
DECLARE #Hour NVARCHAR(2)
DECLARE #TimeFrame NVARCHAR(2)
DECLARE #TimeSpan INTEGER
SET #TimeSpan = 24
SET #TimeFrame = 'AM'
SET #Hour = '08'
DECLARE #dateStart DateTime
DECLARE #dateEnd DateTime
IF #TimeSpan < 24 -- Our TimeSpan is under one full day.
BEGIN
IF GETDATE() > DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE())) + (#Hour + ':00:00 ' + #TimeFrame)
BEGIN
SET #dateStart = DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE() - (1 + #TimeSpan))) + (#Hour + ':00:00 ' + #TimeFrame)
SET #dateEnd = DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE())) + (#Hour + ':00:00 ' + #TimeFrame)
END
ELSE
BEGIN
SET #dateStart = DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE() - (2 + #TimeSpan))) + (#Hour + ':00:00 ' + #TimeFrame)
SET #dateEnd = DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE() - 1)) + (#Hour + ':00:00 ' + #TimeFrame)
END
END
ELSE -- Our TimeSpan is at least one full day.
BEGIN
IF GETDATE() > DATEADD(D, 0, DATEDIFF(D, 0, GETDATE())) + (#Hour + ':00:00 ' + #TimeFrame)
BEGIN
SET #dateStart = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE() - (1 + (#TimeSpan/24)))) + (#Hour + ':00:00 ' + #TimeFrame)
SET #dateEnd = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE())) + (#Hour + ':00:00 ' + #TimeFrame)
END
ELSE
BEGIN
SET #dateStart = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE() - (2 + (#TimeSpan/24)))) + (#Hour + ':00:00 ' + #TimeFrame)
SET #dateEnd = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE() - 1)) + (#Hour + ':00:00 ' + #TimeFrame)
END
END
#Hour, #TimeFrame and #TimeSpan are all parameters ready to be set by the report front-end, and default to '08', 'AM' and 24 respectively. I know that setting the day range works properly in the ELSE portion of the top-level if. I'm reasonably certain that the issue with setting the hour offset lies in how I'm using the DATEADD and DATEDIFF function here, but I haven't been able to figure out just where I'm making my miss step. Any help here would be greatly appreciated.

-- convert the required end hour to 24 hour format
DECLARE #EndHour INT
SET #EndHour = CASE WHEN #TimeFrame = 'AM' THEN #Hour ELSE #Hour + 12 END
-- set #DateEnd to the date-only portion of the current datetime
-- ie, the time portion will be set to 00:00:00
SET #DateEnd = DATEADD(day, 0, DATEDIFF(day, 0, GETDATE()))
-- add the required end hour
SET #DateEnd = DATEADD(hour, #EndHour, #DateEnd)
-- if #DateEnd is in the future then subtract 24 hours from it
IF #DateEnd > GETDATE()
SET #DateEnd = DATEADD(hour, -24, #DateEnd)
-- set #DateStart by subtracting the required timespan from #DateEnd
SET #DateStart = DATEADD(hour, -#TimeSpan, #DateEnd)

Why not just use a query like:
SELECT something
FROM aTable
WHERE timeCompleted BETWEEN #StartDate AND #EndDate
If you are concerned about the time being correct (i.e. the dates must be '01/01/1900 13:00:00' or something like that) just pass in the date by itself and add the time as a function in the SQL.
If this is not what you are intending please include more of the SQL so that we have a better understanding of what you are trying to accomplish.

Related

Error on INSERT INTO SELECT in query hosted on variable

I'm a little bit conffused.
Can anyone tell me why i get sintaxis error on the next script?
declare #schema1 NVARCHAR(100)
set #schema1 = 'ex.:DATABASENAME'
declare #query NVARCHAR(500)
set #query = 'INSERT UsersSessions (UserSessionId, IpAddress, ChannelId, IsEmployee, UserId, ClientFullName, UserAgent, StartDate, ExpirationDate, SessionDuration)
SELECT us.UserSessionId, us.IpAddress, us.ChannelId, CASE WHEN us.ChannelId = 2 THEN 1 ELSE 0 END AS IsEmployee, us.UserId, (u.Name + u.LastName) as ClientFullName, us.UserAgent, us.StartDate, us.ExpirationDate, (us.ExpirationDate-us.StartDate) AS SessionDuration
FROM ' + #schema1 + '.UsersSessions us INNER JOIN ' + #schema1 + '.Users u ON us.UserId = u.UserId WHERE us.UserSessionId NOT IN (SELECT UserSessionId FROM UsersSessions)'
EXEC(#query)
RESULT:
Msg 156, Level 15, State 1, Line 15
Incorrect syntax near the keyword 'Use'.
Completion time: 2021-11-16T11:10:32.6309920-03:00
If i remove the Insert block, i get the script running
declare #schema1 NVARCHAR(100)
set #schema1 = 'ex.:DATABASENAME'
declare #query NVARCHAR(500)
set #query = '
SELECT us.UserSessionId, us.IpAddress, us.ChannelId, CASE WHEN us.ChannelId = 2 THEN 1 ELSE 0 END AS IsEmployee, us.UserId, (u.Name + u.LastName) as ClientFullName, us.UserAgent, us.StartDate, us.ExpirationDate, (us.ExpirationDate-us.StartDate) AS SessionDuration
FROM ' + #schema1 + '.UsersSessions us INNER JOIN ' + #schema1 + '.Users u ON us.UserId = u.UserId WHERE us.UserSessionId NOT IN (SELECT UserSessionId FROM UsersSessions)'
EXEC(#query)
RESULT:
(1 row affected)
Completion time: 2021-11-16T11:11:07.6741062-03:00
I think some char is missing?
Thanks and regards!
Your query variable length is not sufficient, modify it as below. Also, schema name can accept only certain characters, colon is not allowed I guess.
declare #query NVARCHAR(max)

Querying million records with paging and custom searching using SQL stored procedure

I need help on optimizing this query that retrieves a list of products from businesses. This query only brings set of data using specific parameters you see below. It takes about 6-9 seconds to run with about 40,000 products and only brings 10 products at a time, but I need to make it faster.
I execute this:
EXEC [GetProducts] #StartRowIndex=0, #MaximumRows=10,
#SortedBy='ProductName', #SortedIn='DESC', #CategoryID=0,
#CategoryIDPath=N'''1|%''', #SearchText='ALL', #SearchSQL=N'', #CreatedByUser=0
Here's the full query:
ALTER PROCEDURE [GetProducts] (
#StartRowIndex int,
#MaximumRows int,
#SortedBy nvarchar(20),
#SortedIn nvarchar(6),
#CategoryID int,
#CategoryIDPath nvarchar(500),
#SearchText nvarchar(255),
#SearchSQL nvarchar(MAX),
#CreatedByUser int
)
as
BEGIN
--get correct Sorted By
DECLARE #strSortedBy nvarchar(300)
SET #strSortedBy =
(CASE
WHEN (#SortedBy = 'CreatedDate') THEN 'Products.CreatedDate ' + #SortedIn
WHEN (#SortedBy = 'Views') THEN 'Products.Views ' + #SortedIn
ELSE 'Products.ProductName ' + #SortedIn
END)
--check if you are filtering by Category START
DECLARE #FilterByCategoryID nvarchar(250)
IF (#CategoryID > 0)
BEGIN
SET #FilterByCategoryID = 'AND Products.CategoryID = ' + cast(#CategoryID as nvarchar(5))
END
else
BEGIN
IF (#CategoryIDPath <> '') --show category features first then the most recent by default
BEGIN
SET #FilterByCategoryID = 'AND Products.CategoryIDPath LIKE ' + #CategoryIDPath
END
else
BEGIN
SET #FilterByCategoryID = ''
END
END
--check if you are filtering by Category END
--this option is used when you are searching by category only START
IF (#SearchText <> '')
BEGIN
IF #SearchSQL = 'ALL'
BEGIN
SET #SearchSQL = ''
END
END
else
BEGIN
SET #SearchSQL = ''
END
--this option is used when you are searching by category only END
--check if you are filtering by CreatedByUser START
DECLARE #FilterByCreatedByUser nvarchar(250)
IF (#CreatedByUser > 0)
BEGIN
SET #FilterByCreatedByUser = 'AND Products.CreatedByUser = ' + cast(#CreatedByUser as nvarchar(10))
END
else
BEGIN
SET #FilterByCreatedByUser = ''
END
--check if you are filtering by CreatedByUser END
DECLARE #MaximumRow int
SET #MaximumRow = #startRowIndex + #maximumRows
exec('SELECT
RowRank
,Products.ItemID
,Products.ProductName
,Products.Description
,Products.CategoryID
,Products.CategoryIDPath
,Products.FileName
,Products.CategoryName
,Businesses.BusinessName
,Businesses.Country
,Products.TotalCount
FROM
(
SELECT
ROW_NUMBER() OVER(ORDER BY ' + #strSortedBy + ') AS RowRank
,COUNT(*) OVER() AS TotalCount
,Products.*
FROM
Products
INNER JOIN Businesses
ON Products.CreatedByUser = Businesses.CreatedByUser
AND Businesses.Published <> 0
AND (Businesses.[ExpireDate] >= GetDate() or Businesses.[ExpireDate] is null)
WHERE
Products.Published <> 0
AND (Products.[ExpireDate] >= GetDate() OR Products.[ExpireDate] is null)
AND Products.ItemType = ''Classifieds''
' + #FilterByCategoryID + '
' + #FilterByCreatedByUser + '
' + #SearchSQL + '
) AS Products
INNER JOIN Businesses
ON Products.CreatedByUser = Businesses.CreatedByUser
AND Businesses.Published <> 0
AND (Businesses.[ExpireDate] >= GetDate() or Businesses.[ExpireDate] is null)
WHERE
RowRank > ' + #startRowIndex + ' AND RowRank <= ' + #MaximumRow + '
ORDER BY ' + #strSortedBy)
END

dynamic query showing 'Unclosed quotation mark after the character string '),

i have a stored procedure in which i am getting error 'Unclosed quotation mark after the character string ' having a hard time with the script. please help me to find out what is wrong in my code.
here is my code.
ALTER PROCEDURE [dbo].[usp_Transfer]
#orgid bigint,
#SearchString nvarchar (500) = null,
#LocationId bigint = 0,
#ownerid bigint,
#OrderList varchar(MAX)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.\
SET NOCOUNT ON;
DECLARE #SQL varchar(MAX)
BEGIN
SET #SQL = 'SELECT ProductID = ii.ProductId,
InvItemId = convert(bigint,0),Name = p.Name,
PrimaryImageID = p.PrimaryImageID,ProductNumberLabel = p.ProductNumberLabel,ProductNumber = p.ProductNumber,
category = isnull(c.Name,''),
qty = ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00),
SalePrice= ISNULL(p.SalePrice, 0.00),
EnteredQuantity=(case when (ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) > 1) then 1.00 else ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) end)
,Discount=0,u.UnitName,
u.UnitID
FROM dbo.[Inven] ii
Left Join dbo.[Product] p on ii.ProductId = p.ProductId and p.activestatus=1
Left Join dbo.[category] c on p.DefaultCategoryId = c.CategoryId
Left Join dbo.[Unit] u on p.UnitId=u.UnitId and u.Activestatus=1
WHERE p.OrganizationID = #orgid
AND ii.InventoryID IN(1634)
AND ii.ActiveStatus = 1
AND p.ActiveStatus = 1
AND p.IsDisabled = 0
And p.CanSale = 1
AND ii.InventoryID IN (' + #OrderList + ')
group by ii.ProductId, p.Name, p.PrimaryImageID, p.ProductNumberLabel, p.ProductNumber, c.Name,p.SalePrice,u.unitname,u.UnitID
having ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0) > 0
Order by p.ProductNumber, p.Name, c.Name '
--EXEC(#SQL)
PRINT(#SQL)
END
END
Two things of note.
First, does #OrderList contain any quotes?
Second, this line:
...' WHERE p.OrganizationID = #orgid '
Should be:
....'WHERE p.OrganizationID = ' + #orgid + '...'
The easy way to test if either of these are the cause of the problem is to comment both out, run it and see if it works, if it does then comment them in one at a time to see which one gives you the error.
Finally, you could rewrite this query and avoid using a dynamic query at all. I guess looking at the query you have done it because of the IN (' + #OrderList + ') clause. These posts might help you rework that section:
Parameterize an SQL IN clause
SQL Server - In clause with a declared variable
Update your SP as below:
Note: there are so many errors if solve one like quotation mark, declare variable #orgid and then conversion error
Your initial error due to : category = isnull(c.Name,''), replace it with category = isnull(c.Name,'''')
alter PROCEDURE [dbo].[usp_Transfer]
#orgid bigint=1,
#SearchString nvarchar (500) = null,
#LocationId bigint = 0,
#ownerid bigint=1,
#OrderList varchar(MAX)='1'
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.\
SET NOCOUNT ON;
DECLARE #SQL varchar(MAX)
BEGIN
SET #SQL = 'SELECT ProductID = ii.ProductId,
InvItemId = convert(bigint,0),Name = p.Name,
PrimaryImageID = p.PrimaryImageID,ProductNumberLabel = p.ProductNumberLabel,ProductNumber = p.ProductNumber,
category = isnull(c.Name,''''),
qty = ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00),
SalePrice= ISNULL(p.SalePrice, 0.00),
EnteredQuantity=(case when (ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) > 1) then 1.00 else ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) end)
,Discount=0,u.UnitName,
u.UnitID
FROM dbo.[Inven] ii
Left Join dbo.[Product] p on ii.ProductId = p.ProductId and p.activestatus=1
Left Join dbo.[category] c on p.DefaultCategoryId = c.CategoryId
Left Join dbo.[Unit] u on p.UnitId=u.UnitId and u.Activestatus=1
WHERE p.OrganizationID = '+CAST(#orgid AS VARCHAR(10))+'
AND ii.InventoryID IN(1634)
AND ii.ActiveStatus = 1
AND p.ActiveStatus = 1
AND p.IsDisabled = 0
And p.CanSale = 1
AND ii.InventoryID IN (' + #OrderList + ')
group by ii.ProductId, p.Name, p.PrimaryImageID, p.ProductNumberLabel, p.ProductNumber, c.Name,p.SalePrice,u.unitname,u.UnitID
having ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0) > 0
Order by p.ProductNumber, p.Name, c.Name '
EXEC(#SQL)
PRINT(#SQL)
END
END

Calculate total hours between 2 time stamps?

How we can make a store procedure in between time?
like,
Total Hr=(( outtime - intime) - (breakin time - breakout time) )
create procedure sp_time_outtime
#id bigint
as
begin
declare
#totalhour as nvarchar(50),
#tth as bigint,
#ttm as bigint,
#inhour as bigint,
#outhour as bigint,
#breakinhour as bigint select #tth = datediff(mi, intime, (case when breakouttime is null then isnull(breakintime,GETDATE()) else GETDATE() end) ) from time where empid=#id and CONVERT(date,GETDATE()) = CONVERT(date,[date])
select #ttm = datediff(mi, isnull(breakintime,'1/1/1990'),ISNULL(breakouttime,isnull (breakintime,'1/1/1990'))) from time where empid=#id and CONVERT(date,GETDATE()) = CONVERT(date,[date])
select #totalhour = (#tth -#ttm)
SET #totalhour = CASE WHEN (#tth -#ttm) >= 60 THEN (SELECT CAST(((#tth -#ttm) / 60) AS VARCHAR(2)) + ' :H :' +
CASE WHEN ((#tth -#ttm) % 60) > 0 THEN
CAST(((#tth -#ttm) % 60) AS VARCHAR(2)) + ' M'
ELSE
''
END) ELSE
CAST(((#tth -#ttm) % 60) AS VARCHAR(2)) + 'M'
END
if ((select outtime from time where empid=#id and convert(date,GETDATE())=CONVERT(date,[date])) IS NULL)
begin
update time set outtime=GETDATE(),totalhour=#totalhour where
empid=#id and CONVERT(date,GETDATE()) = CONVERT(date,[date])
end END

Apex Dynamic SOQL date binding + days

I am able to evaluate today's date using:
String timeframe = DateTime.newInstance(Date.today(), Time.newInstance(0, 0, 0, 0)).format('yyyy-dd-MM');
But I need to add days to this. So I want:
String timeframe = DateTime.newInstance(Date.today()**.addDays(10)**, Time.newInstance(0, 0, 0, 0)).format('yyyy-dd-MM');
query += ' and (created_date__c <= ' + timeframe + ')';
But am receiving this error: line 1:392 no viable alternative at character '2'
I also tried:
DateTime refDate1 = DateTime.newInstance(System.today().year(), System.today().month(), System.today().day(), 0, 0, 0);
DateTime refDate2 = refDate1.addDays(-10);
query += ' and created_date__c <= '+ refDate1.date() + ' and created_date__c >= ' + refDate2.date();
Which throws: line 1:405 no viable alternative at character ' '
Please help!
I resolved this using code I'd already tried, which makes me think there was something wrong with my soql string to begin with.
String timeframe = DateTime.newInstance(System.today().addDays(-10),
Time.newInstance(0, 0, 0,0)).format('yyyy-dd-MM');
whereClause += ' and (';
whereClause += 'created_date__c >= ' + timeframe;
whereClause += ' OR sourced_date__c >= ' + timeframe;
whereClause += ' OR last_phone_bank_call_date__c >=' + timeframe;
whereClause += ')';

Resources