TDengine jdbc timezone - database

I used the code below to create timezone reconfigured connection.
operties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC+8");
Connection connDefault = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
and then I used the connDefault to create a statement,the use this statement to insert and select data.
insert into meters values('2021-07-29 00:00:00', 'taosdata');
select * from meters ;
But the java code query result is
ts=2021-07-29 16:00:00.0
there are 16 hours interval. While I expect the query result is the same as the insert time '2021-07-29 00:00:00'.
what's more the time stored in db is like this
ts | name
1627545600000 | taosdata
Query OK, 1 row(s) in set (0.008616s)
could someone help figure out why?
In addition, i found on the official website of tdengine always set timezone to "utc-8" does anyone know where that timezone is?
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
Connection conn = DriverManager.getConnection(jdbcUrl, connProps);

Like other database software, for example, PostgreSQL, TDengine uses Posix timezone spec which means the offset is opposite with the ISO 8601 standard.

Related

Why Hibernate HSQL Concat is not working for MSSQL?

So, I have Hibernate 5.3.1 in a project which connects to different enginees (MySql, Oracle, PostgreSQL and MS SQL), so I can't use native queries.
Let's say I have 3 records in a table, which all of them have the same datetime, but I need to group them only by date (not time). For example, 2019-12-04;
I execute this query:
SELECT
CONCAT(year(tx.date_), month(tx.date_), day(tx.date_)),
iss.code,
COUNT(tx.id)
FROM
tx_ tx
JOIN
issuer_ iss
ON
tx.id_issuer = iss.id
GROUP BY
CONCAT(year(tx.date_), month(tx.date_), day(tx.date_)), iss.code
But, when I test it connected to SQL SERVER 2017, instead of return 20191204, it's returning 2035. In Oracle and MySQL is working fine.
Anyone has any idea why is this happen? I've tried different ways, like use + instead of CONCAT but the result is the same.
I've also tried to extract them for separate (without concat), and they have been returning correct. The problem is, I need to group them by the complete date.
And just for the record, the field is declared as datetime2 in DDBB
How about simply adding them, instead of using CONCAT.
(year(tx.date_)*10000 + month(tx.date_)*100 + day(tx.date_)*1) AS datenum
Thus, try this:
SELECT
CAST((year(tx.date_)*10000 + month(tx.date_)*100 + day(tx.date_)*1) AS string) AS datenum,
iss.code
FROM tx_ tx
JOIN issuer_ iss
ON tx.id_issuer = iss.id
GROUP BY year(tx.date_), month(tx.date_), day(tx.date_), iss.code
Thanks for the hint Gert Arnold gave me. I just didn't realize that the query was adding like if they were numbers in MSSQL.
Finally, I manage to make it work in the 4 RDBMS casting to string first
SELECT
CONCAT(CAST(year(tx.date_) AS string), CAST(month(tx.date_) AS string), CAST(day(tx.date_) AS string)),
iss.code
FROM
tx_ tx
JOIN
issuer_ iss
ON
tx.id_issuer = iss.id
GROUP BY
CONCAT(year(tx.date_), month(tx.date_), day(tx.date_)), iss.code
I tried also casting to TEXT, but it throws exception in MySQL
Why use concat() to begin with?
Assuming Hibernate takes care of converting the non-standard year(), month() and day() functions, then the following should work on any DBMS
SELECT year(tx.date_), month(tx.date_), day(tx.date_), iss.code
FROM tx_ tx
JOIN issuer_ iss ON tx.id_issuer = iss.id
GROUP BY year(tx.date_), month(tx.date_), day(tx.date_), iss.code

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.

How do I Check for valid date in C# (that has a datetime type not datetime2)?

I've been searching but haven't found my answer so forgive me if this question is a duplicate.
I've got a .Net C# application that is using entity framework (EF) to communicate with a SQL Server database. I'm converting a large amount of data and I need to make sure my dates are valid SQL Server datetime types. My POCO classes use a datetime2 type for the dates so a date '0201-04-11 13:00:00 PM' is valid until the insert is actually attempted in the SQL Server database. I was attempting to use DateTime.TryParseExact with something like this...
if (DateTime.TryParseExact(legacyRecord.date_paid.ToString(), "M/d/yyyy hh:mm:ss tt", new CultureInfo("en-us"), DateTimeStyles.None, out datePaid))
{
// Load record into lease payment table table
LoadLeasePayment loadLeasePayment = new LoadLeasePayment();
Decimal LeasePaymentId = loadLeasePayment.AddRecord(prodLeaseId, legacyRecord.amount_paid, datePaid, prodContext, loadDate);
}
I'm sure the solution is obvious but I cannot see the forest for the trees. Any help is much appreciated.
After parsing the string DateTime value, you'll need to verify it is within the range of the target SQL data type. The SqlDateTime structure includes static MinValue and MaxValue fields to facilitate this.
if (DateTime.TryParseExact(legacyRecord.date_paid.ToString(), "M/d/yyyy hh:mm:ss tt", new CultureInfo("en-us"), DateTimeStyles.None, out datePaid))
{
if((datePaid >= SqlDateTime.MinValue) && (datePaid <= SqlDateTime.MaxValue))
{
// Load record into lease payment table table
LoadLeasePayment loadLeasePayment = new LoadLeasePayment();
Decimal LeasePaymentId = loadLeasePayment.AddRecord(prodLeaseId, legacyRecord.amount_paid, datePaid, prodContext, loadDate);
}
}

Migrate PB7 to 10.5 using SQL server DB

I migrated PB7 to PB10.5 on SQL server DB. The system gives me this message:
"DBMS MSS Microsoft SQL Server 6.x is not supported in your current
installation"
I changed the database connection settings from:
Old connect used in PB7:
DBMS = MSS Microsoft SQL Server 6.x
Database = databaseName
ServerName = serverName
LogId = LogId
AutoCommit = 1
DBParm = ""
UserId = userid
DatabasePassword =
LogPassword=password
Lock=
Prompt=0
To this in PB10.5:
DBMS =SNC SQL Native Client(OLE DB)
Database =databaseName
ServerName =serverName
LogId =LogId
AutoCommit = 0
DBParm = "
Database='databaseName'
TrimSpaces=1"
UserId=userid
DatabasePassword=
LogPassword=password
Lock=
Prompt=0
The system run without previous error message,but when retrieve any old stored arabic data in datawindows it seem unreadable like
ÚãáíÇÊ ÇÎÑì
I can't believe this question got overlooked -- sorry about that. It is a common question when migrating from older versions of PowerBuilder to PowerBuilder version 10 and higher. Good news, very easy to fix just can be time consuming depending on how many places you need to fix.
I've already written a blog article on the subject or just duckduckgo migrating PowerBuilder Unicode issues.
Converting ANSI and Unicode Strings for PowerBuilder Migrations to Version 10 and Higher
Here is a summary of the conversion process:
Convert data to ANSI
Blob lbl_data
lbl_data = Blob("PowerBuilder is cool!", EncodingANSI!)
ls_data = String(lbl_data, EncodingANSI!)
Convert data read via file to ANSI
Blob lbl_data
lbl_data = Blob("PowerBuilder is cool!", EncodingANSI!)
ls_data = String(lbl_data, EncodingANSI!)

How to get sysdate, time and timestamp from database using hibernate

In my application I need to get database date(sysdate in case of Oracle DB) and compare it with user input date (String converted to java.util.Date). From this forum I got the following code which helps in the case of Oracle dialect.
public Date getDate() {
Session session = getHibernateTemplate().getSessionFactory().openSession();
SQLQuery query = session.createSQLQuery("select sysdate as mydate from dual");
query.addScalar("mydate", Hibernate.TIMESTAMP);
return (Date) query.uniqueResult();
}
And from this link got the following method which uses mapping file with formula.
<property name="currentDate" formula="(select sysdate from dual)"/>
Again this is specific to Oracle. I think using later method is more performance friendly, because we can get it from the same session, i.e no need of opening another session just for getting date.
I am looking for a generic solution to get date, time and timestamp from any DBMS using Hibernate. Using HQL is the preferred. Hope such a solution is available.
For those who are looking for .NET /C# solution, here is what worked for me:
// this works only with Oracle
public DateTime DbTimeStamp(ISession session)
{
// Sample returned value = "12-OCT-11 01.05.54.365134000 AM -07:00"
string sql = "SELECT SYSTIMESTAMP FROM DUAL";
ISQLQuery query = session.CreateSQLQuery(sql)
.AddScalar("SYSTIMESTAMP", NHibernate.NHibernateUtil.DateTime);
return query.UniqueResult<DateTime>();
}

Resources