Getting an exception with datetime diff - sql-server

I've 2 buttons on my webpage. And when I hit the first button, the system time gets updated in starttime of my sql table, and when I hit a stop, The end time has to be updated and the difference between both should be updated in anothere table. I've using the below queries.
To update the end time and to update the total time.
update breakstable set endtime = ?, TotalBreakTime = (? - StartTime) where userid = ?
and endtime is NULL
here first 2 ?s refers to a button click that happens and another ? for the logged in userId getting captured from session.
update another table with the sum of the totalbreaktime.
MERGE Time_Tracker as target using (SELECT USERID, CONVERT(NUMERIC(10,2),
SUM(DATEDIFF(Second, '19000101', TotalBreakTime))/60.0) as ColumnWithBreaksCount FROM
BreaksTable where CONVERT(Date, StartTime) = CONVERT(Date, GETDATE()) GROUP BY USERID)
as source ON target.USERID = source.USERID WHEN MATCHED THEN UPDATE
SET BREAKS = source.ColumnWithBreaksCount;"
problem:
I start my time, go on a break and return after an hour and half and i hit the stop button. Instead of updating the table it is giving me the below Exception.
com.microsoft.sqlserver.jdbc.SQLServerException: The datediff
function resulted in an overflow. The number of dateparts separating
two date/time instances is too large. Try to use datediff with a less
precise datepart.
and the JDBC Exception (For Java guys) is as below.
com.microsoft.sqlserver.jdbc.SQLServerException: The datediff function
resulted in an overflow. The number of dateparts separating two
date/time instances is too large. Try to use datediff with a less
precise datepart. at
com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:196)
at
com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1454)
at
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:388)
at
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:338)
at
com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4026)
at
com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1416)
at
com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:185)
at
com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:160)
at
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:306)
at
org.DAO.UpdateEndTimeDAO.UpdateEndTimeDetails(UpdateEndTimeDAO.java:48)
at org.servlet.UpdateEndTime.doPost(UpdateEndTime.java:38) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:648) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at Filter.MyFilter.doFilter(MyFilter.java:58) at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
And the exception points to the second query declared in my question.
If the time is less, say like 2 min or 3 mins, it is updating without any issue.
please where am I going wrong and how can I fix this.
My Breaks table looks like below
Instead of null, this should be the end time captured on button click
And my Time tracker looks like below.
instead of 4.97 in above screenshot it should be the sum of the totalbreaktime from my first screenshot.
Thanks

This is because DATETIME functions like DATEDIFF, DATEADD etc. accept and returns integer (INT) data type. Limit of the data type is 2^31 (-2,147,483,648) to 2^31-1 (2,147,483,647).
So if you add -2147483648 to TotalBreakTime. It returns "1948-08-08 14:01:46.000"
SELECT DATEADD(SS,CAST(-2147483648 AS BIGINT),'2016-08-26 17:15:54.000');
And more the the limit of datatype returns ERROR.
Arithmetic overflow error converting expression to data type int.
Because date difference in second is too large (out of limit of datatype) between the dates in the query. It returns the error.
SELECT CONVERT(NUMERIC(10,2),
SUM(CAST(DATEDIFF(Second, '19000101', '2016-08-26 17:15:54.000') AS BIGINT))/60.0)
I would suggest to discuss logic with you team resolve the issue accordingly.
Thanks

try this:
MERGE Time_Tracker as target
using
(SELECT USERID,
Sum(cast(cast(TotalBreakTime as float)
* 86400 as bigint)) ColumnWithBreaksCount
FROM BreaksTable b
Where datediff(day, StartTime, GETDATE()) = 0
GROUP BY USERID) source
ON target.USERID = source.USERID
WHEN MATCHED THEN UPDATE
SET BREAKS = source.ColumnWithBreaksCount;"

Related

Joining continuous queries in Flink SQL

I'm trying to join two continuous queries, but keep running into the following error:
Rowtime attributes must not be in the input rows of a regular join. As a workaround you can cast the time attributes of input tables to TIMESTAMP before.\nPlease check the documentation for the set of currently supported SQL features.
Here's the table definition:
CREATE TABLE `Combined` (
`machineID` STRING,
`cycleID` BIGINT,
`start` TIMESTAMP(3),
`end` TIMESTAMP(3),
WATERMARK FOR `end` AS `end` - INTERVAL '5' SECOND,
`sensor1` FLOAT,
`sensor2` FLOAT
)
and the insert query
INSERT INTO `Combined`
SELECT
a.`MachineID`,
a.`cycleID`,
MAX(a.`start`) `start`,
MAX(a.`end`) `end`,
MAX(a.`sensor1`) `sensor1`,
MAX(m.`sensor2`) `sensor2`
FROM `Aggregated` a, `MachineStatus` m
WHERE
a.`MachineID` = m.`MachineID` AND
a.`cycleID` = m.`cycleID` AND
a.`start` = m.`timestamp`
GROUP BY a.`MachineID`, a.`cycleID`, SESSION(a.`start`, INTERVAL '1' SECOND)
In the source tables Aggregated and MachineStatus, the start and timestamp columns are time attributes with a watermark.
I've tried casting the input rows of the join to timestamps, but that didn't fix the issue and would mean that I cannot use SESSION, which is supposed to ensure that only one data point gets recorded per cycle.
Any help is greatly appreciated!
I investigated this a little further and noticed that the GROUP BY statement doesn't make sense in that context.
Furthermore, the SESSION can be replaced by a time window, which is the more idiomatic approach.
INSERT INTO `Combined`
SELECT
a.`MachineID`,
a.`cycleID`,
a.`start`,
a.`end`,
a.`sensor1`,
m.`sensor2`
FROM `Aggregated` a, `MachineStatus` m
WHERE
a.`MachineID` = m.`MachineID` AND
a.`cycleID` = m.`cycleID` AND
m.`timestamp` BETWEEN a.`start` AND a.`start` + INTERVAL '0' SECOND
To understand the different ways to join dynamic tables, I found the Ververica SQL training extremely helpful.

I can no longer query my view and my code fails over, Any suggestions?

I have a query that has been running for over a week with no issues.
CREATE or REPLACE VIEW VW_AF AS
select f.*
from VW_AFC f
inner join
(
SELECT Forecast, ROUTE_TO_MARKET, FORECASTCURRENCY,LEVEL,IMPORT , MAX(Version) AS maxVersion
FROM VW_AFC
GROUP BY Forecast, ROUTE_TO_MARKET, FORECASTCURRENCY,LEVEL,IMPORT
order by Forecast, ROUTE_TO_MARKET, FORECASTCURRENCY,LEVEL,IMPORT
)x
on x.Forecast = f.Forecast
and x.ROUTE_TO_MARKET = f.ROUTE_TO_MARKET
and x.FORECASTCURRENCY = f.FORECASTCURRENCY
and x.Level = f.level
and x.Import = f.Import
and x.maxversion = f.version;
Today i went to query this view and keep getting errors
--SQL execution internal error: Processing aborted due to error zz:yy; incident xx.--
I have no ideas, I know that for some reason the nested inner query is now failing but cant suss it.
Any experts have advice??
Thxs
According to your comments, I think you already found the correct approach to this error.
Whenever you see "SQL execution internal error" message, you should submit a support ticket to Snowflake. The numbers you see on the error message, can only be interpreted by Snowflake (they point an incident record). Snowflake Support will access to the incident record, see the underlying error message, and provide a workaround or a fix.

How do I add a TimeSpan to a time column in SQL Server

I want to do something like the following:
update AutoTagUse set TimeActive = (TimeActive + #OrigTimeActive) where AutoTagUseId = #AutoTagUseId
Where TimeActive is a TIME(0) column in SQL Server, and OrigTimeActive is a TimeSpan variable (in C#).
I'm trying to do this so I can have multiple services updating this value in the database simultaneously without have to lock things down with transactions.
The SQL Server entry to create the column is:
[TimeActive] TIME (0)
CONSTRAINT [DF_AutoTagUse_TimeActive] DEFAULT ('00:00:00') NOT NULL,
What I am now trying is:
TimeSpan difference = TimeActive - origTimeActive;
conn.ExecuteScalar("update AutoTagUse set TimeActive = dateadd(SECOND, #OrigTimeActive, TimeActive) where AutoTagUseId = #AutoTagUseId",
new { AutoTagUseId = AutoTagUseId, OrigTimeActive = difference }, transaction);
And I am getting:
System.Data.SqlClient.SqlException
HResult=0x80131904
Message=Argument data type time is invalid for argument 2 of dateadd function.
Source=.Net SqlClient Data Provider
StackTrace:
at Dapper.SqlMapper.ExecuteScalarImpl[T](IDbConnection cnn, CommandDefinition& command)
at Dapper.SqlMapper.ExecuteScalar(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Nullable1 commandTimeout, Nullable1 commandType)
at LicenseLibrary.DataObjects.AutoTagUse.Update(IDbConnection conn, IDbTransaction transaction) in C:\git\Store\LicenseLibrary\DataObjects\AutoTagUse.cs:line 171
at TestLibrary.DataObjects.TestAutoTagUse.<>c.b__2_0(IDbConnection conn) in C:\git\Store\TestLibrary\DataObjects\TestAutoTagUse.cs:line 59
at LicenseLibrary.Database.AzureDataAccess.<>c__DisplayClass11_0.b__0() in C:\git\Store\LicenseLibrary\Database\AzureDataAccess.cs:line 104
at Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.RetryPolicy.<>c__DisplayClass1.b__0()
at Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.RetryPolicy.ExecuteAction[TResult](Func`1 func)
Being time(0), I'm assuming your interval is SECONDS
You can use DATEADD()
Example
Update AutoTagUse
set TimeActive = dateadd(SECOND,#OrigTimeActive,TimeActive)
Where AutoTagUseId = #AutoTagUseId
In general, if you're wanting to store a time span, the time data type in SQL Server is not suitable. Because it's designed for storing times of day, not time spans. This means that there's no support for adding two of these values together (it doesn't make sense to add 4pm and 8pm together). Nor does it support negative values or values greater than 24 hours.
For all of these reasons, I'd usually recommend instead using a numeric data type with a clear indication given in its name of the intended units. (I usually prefer an int type in the smallest granularity required, others may choose to use a decimal of some sort)
E.g. I'd use SecondsActive int as the column here.

SQL Report Error - [Macromedia][SQLServer JDBC Driver][SQLServer]Invalid column name

We use a housing software based on ColdFusion and uses SQL to create database functions in our reports. I am working on a custom report to try to subtract one column from another: more specifically subtract COUNT_OF_INSPECTION_TYPE from OCCUPANCY. The OCCUPANCY column is based on the following code:
CONVERT(INT
, CASE
WHEN tblHalls.HALLNAME = 'Hall1' THEN 198
WHEN tblHalls.HALLNAME = 'Hall2' THEN 430
WHEN tblHalls.HALLNAME = 'Hall3' THEN 333
END
)
When I try a new function OCCUPANCY - COUNT_OF_INSPECTION_TYPE, I get an error:
Unable to invoke CFC - Error Executing Database Query. [Macromedia][SQLServer JDBC Driver][SQLServer]Invalid column name
'OCCUPANCY'.
I'm not sure if I am explaining this right. I'd appreciate any help you can offer.
You cannot create an alias and use it in another calculation, at the same level, because the alias is not defined yet. Either repeat the whole CASE ... END statement in the calculation (less desirable) OR use another option, such as a CTE, derived table, APPLY operator, etcetera.
Wrapping your existing SELECT in a CTE is probably one of the simplest options:
;WITH cte
AS
(
-- Your current SELECT statement goes here
SELECT
CONVERT(INT
, CASE
WHEN tblHalls.HALLNAME = 'Hall1' THEN 198
WHEN tblHalls.HALLNAME = 'Hall2' THEN 430
WHEN tblHalls.HALLNAME = 'Hall3' THEN 333
END
)
AS OCCUPANCY
, tblHalls.COUNT_OF_INSPECTION_TYPE
, ... (Other Columns)
FROM tblHalls
)
-- Now use the alias in a calculation
SELECT cte.*
, cte.OCCUPANCY - cte.COUNT_OF_INSPECTION_TYPE AS SomeAliasForThisCol
FROM cte
Side note, since the CASE statement does not define an ELSE condition, the result of the calculation will be NULL if none of HallName's match. If that is not desirable, consider setting a default.

Using a subquery in WonderWare to select all tags

I'm trying to get data from a WonderWare historian database on all tags in the database. There is already a table containing all the tags, so I would like to use a subquery to select all of the tag names. I'm getting an error w.r.t this subquery.
My sql statement:
/******
I want to be able to select:
- all columns
- for all tags <-- I'm getting an error here, trying to use a subquery
- between two time stamps
- at a specified resolution
******/
SELECT *
FROM
Runtime.[dbo].AnalogHistory
WHERE
TagName IN (
SELECT DISTINCT TagName
FROM
Runtime.dbo.Tag
)
AND
DateTime >= '2016-01-01 00:00'
AND
DateTime < '2016-01-01 00:30'
AND
wwResolution = 5000
AND
wwRetrievalMode = 'Average'
AND
wwTimeStampRule = 'Start'
The error I am receiving is the following:
OLE DB provider "INSQL" for linked server "INSQL" returned message "History queries must contain at least one valid tagname".
Which I guess means that it isn't being executed properly.
I've also tried using openquery, but then I get other errors related to the subquery unable to discern 'schema' information about the Tag table:
OLE DB provider "INSQL" for linked server "INSQL" returned message "Failed to retrieve schema information for object 'Tag'".
This was the excerpt changed:
TagName IN ( SELECT * FROM OPENQUERY(INSQL,
'SELECT DISTINCT TagName
FROM
Runtime.dbo.Tag')
)
Historian Server is not a normal SQL Server database. It's historical views get data from the INSQL linked server. INSQL has some special rules that are documented in HistorianConcepts.pdf.
SELECT
*
FROM
Runtime.dbo.Tag t
INNER REMOTE JOIN
Runtime.dbo.AnalogHistory h
ON
t.TagName = h.TagName
WHERE
DateTime >= '2016-01-01 00:00'
AND
DateTime < '2016-01-01 00:30'
AND
wwResolution = 5000
AND
wwRetrievalMode = 'Average'
AND
wwTimeStampRule = 'Start'
Try:
SELECT DISTINCT aa.TagName FROM (
SELECT DateTime, TagName, Value
FROM History
WHERE DateTime >= '2016-01-01 00:00'
AND DateTime <= '2016-01-01 00:30'
AND wwResolution = 5000
AND wwRetrievalMode = 'Average'
AND wwTimeStampRule = 'Start'
) aa

Resources