I am trying to compare the datetime, in clickhouse. But it's seems it's working in some wired way.
I have a column in my table which I want to compare with (now(),'UTC').
If the value of datetime in that column is less then the (now(),'UTC') Time than I wanna select data from that record.
I have created the table like
create table my_table (`mytime` DateTime, `data' [type]) ENGINE= engine
I want the queue like
Select data from my_table where mytime < toDateTime(now(), 'UTC')
Even if mytime > toDateTime(now(), 'UTC') it always considers mytime < toDateTime(now(), 'UTC')
It seems to me that something may up with the way you inserted data or your ClickHouse version has a bug.
The following example shows how to do what you are attempting in a way that works on my 19.15.4.10 server as expected to select only the earlier row. Note the select sleep() to ensure now() invocations are different.
drop table if exists my_table;
create table my_table (mytime DateTime, data String) engine = Memory;
insert into my_table values(now(), 'a');
select sleep(1);
insert into my_table values(toDateTime('2020-01-01 00:00:00', 'UTC'), 'b');
select * from my_table where mytime < now();
select * from my_table where mytime < toDateTime(now(), 'UTC');
On my server it does not matter whether you select now() or convert it. I also tried the way you originally defined the table and that works too. Hence the thought that something is up with your data.
The reason behind this issue was in clickhouse, it takes DateTime and DateTime('UTC') as different objects, therefore the comparison between them does not work as expected. Since I wanted to make the comparison with (now(),'UTC'), I have to change the type of
mytime as DateTime ('UTC').
I have to change the table as
create table my_table (`mytime` DateTime ('UTC'), `data' [type]) ENGINE= engine
I have the following table create definition in SQL Server:
CREATE TABLE [dbo].[EventLog]
(
[RawEvent] NVARCHAR(MAX) NOT NULL,
[ReceivedDate] AS CAST(JSON_VALUE(RawEvent, '$.ReceivedTime') AS DATETIME)
)
When I receive a JSON string, that string has ReceivedTime which I parse out and use that as the ReceivedDate column's value when inserting this record.
This is currently working. However, when RawEvent string doesn't have the property ReceivedTime, I want to use the current SQL date time as the default value instead of NULL which is what it is doing now.
Is this possible to do in the table definition?
In SQL you can use COALESCE to supply a default value instead of null
COALESCE(CAST(JSON_VALUE(RawEvent, '$.ReceivedTime') AS DATETIME),GETDATE())
While I think #AaronBertrand idea of COALESCE is more straightforward, here's a working example using computed columns:
CREATE TABLE [dbo].[EventLog] (
[RawEvent] NVARCHAR(MAX) NOT NULL,
[ReceivedDate] AS CAST(JSON_VALUE(RawEvent, '$.ReceivedTime') AS DATETIME),
[ReceivedDateDefault] DATETIME NOT NULL DEFAULT GETDATE(),
[ReceivedDateCalculated] AS (CASE WHEN JSON_VALUE(RawEvent, '$.ReceivedTime') IS NULL
THEN [ReceivedDateDefault]
ELSE JSON_VALUE(RawEvent, '$.ReceivedTime') END),
)
INSERT INTO dbo.EventLog (RawEvent)
VALUES
( N'{"Foo":"Bar",
"ReceivedTime":"2019-08-02"
}'),
( N'{"Foo":"Baz"
}')
And the results:
SELECT ReceivedDateCalculated FROM dbo.EventLog
ReceivedDateCalculated
2019-08-02 00:00:00.000
2019-08-02 13:51:14.910
Might be some funky edge cases with empty strings or something, you would definitely want to consider that. There is one additional benefit of having the second date column, that you will always have a timestamp on this row (if you don't already). Which I've found tends to be pretty useful.
Basically, my problem can be re-created using the following script in oracle db:
create table test
(
current_date date
);
insert into test(current_date) values( TO_DATE('2018-02-01', 'yyyy-MM-dd') );
insert into test(current_date) values( TO_DATE('2018-03-01', 'yyyy-MM-dd') );
insert into test(current_date) values( TO_DATE('2018-04-01', 'yyyy-MM-dd') );
--select data later than May
select * from test where current_date >= TO_DATE('2018-05-01', 'yyyy-MM-dd') ;
But all three date come out as result? Why? Did I do something wrong here?
2/1/2018 12:00:00 AM
3/1/2018 12:00:00 AM
4/1/2018 12:00:00 AM
It's because current_date is an Oracle built-in function, returning the current date (and time). The way Oracle namespaces work means the built-in reference trumps your column name.
One way to fix it would be to use a table alias in your query:
select * from test t
where t.current_date >= TO_DATE('2018-05-01', 'yyyy-MM-dd') ;
This tells Oracle you're referencing the column name not the built-in.
Obviously the better solution is to change your table so you don't have a column name which clashes with an Oracle built-in.
I have the following string that I need to save to a sql server database column that has a date datatype.
'2017-05-25T00:00:00'
Can I use cast within a insert script to save this value and is this the best way?
yes You can insert the value like this
INSERT INTO YourTable(ColumnName)
SELECT CAST(StringFiled AS DATETIME)
You Can cast it as Date,DateTime or any other Date type you need
You can use any of the following options.
insert into myTable
values (CAST('2017-05-25T00:00:00' as datetime))
insert into myTable
values (Convert(varchar(30),'2017-05-25T00:00:00',102))
CREATE TABLE Customer
(
customerID int identity (500,20) CONSTRAINT
.
.
dateCreated datetime DEFAULT GetDate() NOT NULL,
dateModified datetime DEFAULT GetDate() NOT NULL
);
When i insert a record, dateCreated and dateModified gets set to default date/time. When i update/modify the record, dateModified and dateCreated remains as is? What should i do?
Obviously, i need to dateCreated value to remain as was inserted the first time and dateModified keeps changing when a change/modification occurs in the record fields.
In other words, can you please write a sample quick trigger? I don't know much yet...
You might want to look at creting an update trigger to update this value for you
Have a look at something like
CREATE TABLE Vals(
ID INT,
Val VARCHAR(10),
DateCreated DATETIME DEFAULT GetDate(),
DateUpdated DATETIME DEFAULT GetDate()
)
GO
CREATE TRIGGER Upd ON Vals
AFTER UPDATE
AS
UPDATE Vals
SET DateUpdated = GetDate()
FROM Vals INNER JOIN
inserted ON Vals.ID = inserted.ID
Go
INSERT INTO Vals (ID, Val) SELECT 1, 'A'
SELECT *
FROM Vals
GO
UPDATE Vals SET Val = 'B'
SELECT *
FROM Vals
GO
DROP TABLE Vals
GO
UPDATE
Customer
SET
... = NewValue,
dateModified = DEFAULT
WHERE
...
I'd use this rather than dateModified = GETDATE() so GETDATE() is only used once (say you want to change to GETUTCDATE() in future)
Or a trigger if you have multiple update paths...?
When i insert a record, dateCreated
and dateModified gets set to default
date/time. When i update/modify the
record, dateModified and dateCreated
remains as is? What should i do?
A Column default is only used when INSERTing and not by an UPDATE. The default will be used by the INSERT command if you do not supply the column or issue the DEFAULT keyword in the INSERT.
INSERT INTO Customer (col1, col2)
VALUES (..,..) ---get default for dateCreated & dateModified
INSERT INTO Customer (col1, col2,dateCreated)
VALUES (..,..,DEFAULT) ---get default for dateCreated & dateModified
INSERT INTO Customer (col1, col2,dateCreated,dateModified)
VALUES (..,..,DEFAULT,DEFAULT) ---get default for dateCreated & dateModified
INSERT INTO Customer (col1, col2,dateCreated,dateModified)
VALUES (..,..,'1/1/2010',DEFAULT) ---only get default for dateModified
INSERT INTO Customer (col1, col2,dateCreated,)
VALUES (..,..,'1/1/2010') ---only get default for dateModified
INSERT INTO Customer (col1, col2,dateCreated,dateModified)
VALUES (..,..,'1/1/2010','1/2/2010') ---no defaults for dateCreated & dateModifie
I like using a local variable set that the top of the procedure:
DECLARE #RunDate datetime
SET #RunDate=GETDATE()
I then use that within the procedure, so all changes (even on multiple tables) have the exact same date to the millisecond. I also prefer the dateModified column to allow nulls and not have a default, when it is inserted, it has been created not modified, I'll set the dateModified when it is actually modified.
then use:
UPDATE Customer
SET importantColumn=
,dateModified = #RunDate
WHERE ...
UPDATE CustomerPrice
SET importantColumn=
,dateModified = #RunDate
WHERE ...
#astander is right, you should just use an update trigger if you want this automated. My update triggers are slightly different (I use the 'inserted' virtual table). Here's one that should fit your schema (rename however you see fit):
CREATE TRIGGER [CustomerDateModifiedTrigger] ON [dbo].[Customer]
FOR UPDATE
AS
UPDATE Customer
SET dateModified = GETDATE()
FROM Customer c
INNER JOIN inserted i ON c.customerID = i.customerID
#Kronass, you don't have any idea about what uou are saying!
timestamp is the synonym for the rowversion data type and is subject to the behavior of data type synonyms. In DDL statements, use rowversion instead of timestamp wherever possible. For more information, see Data Type Synonyms (Transact-SQL).
The Transact-SQL timestamp data type is different from the timestamp data type defined in the ISO standard.
The timestamp syntax is deprecated. This feature will be removed in a future version of Microsoft SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.
rowversion (Transact-SQL) Is a data type that exposes automatically generated, unique binary numbers within a database. rowversion is generally used as a mechanism for version-stamping table rows. The storage size is 8 bytes. The rowversion data type is just an incrementing number and does not preserve a date or a time. To record a date or time, use a datetime2 data type.
1) Be sure to create the index for the primary key. (I just uncovered a mistake of this type recently.)
2) You can use one INSERT/UPDATE trigger instead of separate triggers at the price of a tiny loss of efficiency. If insert.DateCreated is null, then update Vals.DateCreated, otherwise update Vals.DateModified.
There is a datatype in SQL Server Called timestamp. which keep track of the row version for each time you modify the row.
Or if you want you can use a trigger and change the ModifiedDate Column.