Order by on Two Datetime Fields .If one field is Null How to avoid Sybase from populating it with default datetime - sql

I am using a Select Query to insert data into a Temp Table .In the Select Query I am doing order by on two columns something like this
insert into #temp
Select accnt_no,acct_name, start_date,end_date From table
Order by start_date DESC,end_date DESC
Select * from #temp
Here when there is an entry present in start_date field and an Null entry in the end_date field .During the order by operation Sybase is filling it with an Default date ( jan 1 1900 ) . I dont want that to happen .If the end_date field is Null . The data should be written just as Null .Any suggestion on how to keep it as Null even while fetching the data from the table .

The 1/1/1900 usually comes from trying to cast an empty string into a datetime.
Is your 'date' source column an actual datetime datatype or a string-ish varchar or char?

Sounds like the table definition requires that end_date not be null, and has default values inserted automatically to prevent them. Are you sure there are even nulls when you do a straight select on the table without the confusion of ordering and inserting?

I created a temp table with a nullable datetime column that has a default value.
Defaults are not there to handle nulls per se, they are there to handle missing values on inserts that were not supplied. If I run an insert without a column list (just as you have done) the default value does not apply and a null is still inserted.
I suggest adding the column list to your insert statement. This might prevent the problem (or expose a different problem in having them in the wrong order.)
insert into #temp (accnt_no, accnt_name, start_date, end_date)
select accnt_no,acct_name, start_date,end_date from ...
Here's a query that should help you find the actual defaults on any of the columns if you don't have access to the create script:
select c.name, object_name(cdefault), text
from tempdb..syscolumns c, tempdb..syscomments cm
where c.id = object_id('tempdb..#temp') and cm.id = c.cdefault

Related

How to validate the date in a varchar column in SQL Server

I have a staging table which contains all varchar columns. I want to validate a date stored in the data column. Since my staging table contains all varchar columns, then all csv records are inserted into table.
After inserted into the staging table, I need a validation for specific date column to validate date are properly present or not. If any string value comes then I need to eliminate from staging table
Building on #Larnu's comment, you can use TRY_CONVERT to select only the records that contain proper dates, then use those records to do some further action. Consider the following example:
-- Using a table variable as an example of the source data
DECLARE #SampleTable TABLE
(
Id int,
SomePossibleDateField varchar(20)
)
-- Now insert some sample data into the table variable, just for illustration
INSERT INTO #SampleTable
VALUES (1, '2021-05-04'),
(2, '2021-05-05'),
(3, 'not a date'),
(4, NULL),
(5, ''),
(6, '2021-05-06')
-- Now select all the records that contain proper dates:
SELECT * FROM #SampleTable WHERE TRY_CONVERT(DATE, [SomePossibleDateField], 120) > '1900-01-01'
The results of the final select statement above are
Id SomePossibleDateField
1 2021-05-04
2 2021-05-05
6 2021-05-06
Some things to note:
First, in this sample, for simplicity, all the dates are expressed as format 120 (ODBC Canonical). So you may need to try different formats depending on your data. See the date formats listed on the CAST page for the different format values.
Second, that select statement tests for dates greater than the year 1900, but you can change that to any other date that makes sense for your data.
Finally, in case you are looking specifically for records that only contain bad data, you can do that by changing the select statement to something like:
SELECT * FROM #SampleTable
WHERE TRY_CONVERT(DATE, [SomePossibleDateField], 120) = ''
OR TRY_CONVERT(DATE, [SomePossibleDateField], 120) IS NULL
Which results with:
Id SomePossibleDateField
3 not a date
4 NULL
5
Unfortunately, an empty string does not result in NULL like bad data does, it simply gets passed through as empty string. So, if you are specifically looking for bad records, you will need to check both for IS NULL and for '' as shown in the example above.

Insert current date time in a column of and keep it constant

i am using sql server in making my project with javafx. Their i have a table of purchase and sale. One of the column of both of them is date having current date and time to store them as a record that this transaction has been saved in this time.
Now i am using the that date column with varchar datatype and have using computed column specification with following function:
(CONVERT([varchar](25),getdate(),(120)))
but when i select records from that table using query
SELECT pr.Date, p.Name, pr.Quantity, s.Name, p.Pur_Price
FROM (([Product] AS p
INNER JOIN [Purchase] AS pr ON pr.Product_id=p.Product_id)
INNER JOIN [Supplier] AS s ON s.Supplier_Id=p.Supplier_Id)
WHERE pr.Date>= dateadd(dd, 0, datediff(dd, 0, getdate()-30))
but it selects all the records keeping all date records to current date and time. Thanks in advance.
Looking forward for your good replies.
The problem is that your Date column is computed on the fly and not actually stored in the table. So each time you SELECT from that table, the expression of the computed column is calculated (CONVERT([varchar](25),getdate(),(120))) thus resulting in the same value for all rows.
A fix would be using a PERSISTED computed column so that values are actually stored with the table when inserting or updating:
CREATE TABLE Product (
OtherColumns INT,
[Date] AS (CONVERT([varchar](25), getdate(), 120)) PERSISTED)
The problem with this is that non-deterministic expressions can't be persisted, as this error message pops up:
Msg 4936, Level 16, State 1, Line 1 Computed column 'Date' in table
'Product' cannot be persisted because the column is non-deterministic.
You have several other options for this. Please use DATE or DATETIME columns to store and handle dates and avoid using VARCHAR for this as it brings many problems. The following examples use DATETIME:
Use a DEFAULT constraint linked to the column with the expression you want:
CREATE TABLE Product (
OtherColumns INT,
[Date] DATETIME DEFAULT GETDATE())
INSERT INTO Product (
OtherColumns) -- Skip the Date column on the INSERT
VALUES
(1)
SELECT * FROM Product
OtherColumns Date
1 2018-12-14 08:49:08.347
INSERT INTO Product (
OtherColumns,
Date)
VALUES
(2,
DEFAULT) -- Or use the keyword DEFAULT to use the default value
SELECT * FROM Product
OtherColumns Date
1 2018-12-14 08:49:08.347
2 2018-12-14 08:50:10.070
Use a trigger to set the value. This will override any inserted or updated value that the original operation set (as it will execute after the operation, as stated in it's definition).
CREATE TRIGGER utrProductSetDate ON Product
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON
UPDATE P SET
Date = GETDATE()
FROM
inserted AS I
INNER JOIN Product AS P ON I.OtherColumns = P.OtherColumns -- Assuming PK or Unique columns join
END
Thanks all of you. But i solved my problem by putting my date Column of that table into datetime data type and i my query i have entered the date using getdate() method. It worked for me to save current date and time in my purchase and sale table.

SQL Pivot table - filter timestamp

I have a logger table with timestamp,tagname and tagvalue fields.
Every time tag value changes, the control system writes record to the table with those 3 parameters.
Timestamp for records is not synchornized.
I want to run a pivot table query to get all data for 3 different tags to show the values of those 3 tags only.
When I run the query below, I get in return a dataset with all timestamp records in the table and lots of null values in the value fields(the SQL returns me all timestamp values).
I use the query:
SELECT *
FROM (
SELECT [timestamp],
[_VAL] AS '_VAL',
[point_id]
FROM DATA_LOG) p
PIVOT(SUM([_VAL]) FOR point_id in ([GG02.PV_CURNT],
[GG02.PV_JACKT],
[GG02.PV_SPEED],
[GG02.PV_TEMP])
) as tagvalue
ORDER BY timestamp ASC
Here's an example to the values I get in return from the SQL Server:
Results example:
Please anybody can help me how to limit the timestamp that SQL returns me only for timestamp relevant to those 3 tags and not all timestamp values in the table? (the return values list will include a record when at least one of the tags values will not be null)
If anybody have other ideas and not using PIVOT query to get the data in the format shown above - any idea will be welcome.
I think you simply want:
WHERE [GG02.PV_CURNT] IS NOT NULL OR
[GG02.PV_JACKT] IS NOT NULL OR
[GG02.PV_SPEED] IS NOT NULL OR
[GG02.PV_TEMP] IS NOT NULL
in the subquery.

Insert a record into 2 tables in SQL Server using comma separated value

I have 2 table A and table B; table B is linked to table A through a foreign key.
TABLE A has a structure somewhat like this
PK Id
DeliveryChannelValue
DeliverychannelId
Date time
Table B has this structure
PK Id UniqueIdentifiers
Date time
FK tableA id
Now in a stored procedure, I get unique identifiers as comma separated value, so based on the number of items in that list, I have to create the same number of rows in table A and in table B.
If the number of items in comma separated value is 3, then there will be 3 rows to be inserted into table A and 3 rows into table B. I am trying to avoid a cursor.
Please suggest efficient way to do this.
You can use this CodeProject project split function to separate the values, and then use a known DateTime stamp to keep the tables in sync. This assumes these values aren't constantly updating which could cause a DateTime duplication issue: if that's the case, you'll need to use a add a GUID value in place of the YOURDATE field, below:
DECLARE #DATESTAMP DATETIME = GETDATE()
INSERT INTO TABLE_A (ID, YOURDATE)
SELECT item, #DATESTAMP
FROM dbo.[FN_SPLIT](#yourinputstring)
GO
INSERT INTO TABLE_B(YOURDATE, TABLE_A_ID)
SELECT #DATESTAMP, ID
FROM TABLE_A
WHERE YOURDATE = #DATESTAMP
GO

Compare columns with time datatype in SQL

I have table with column with time Datatype.I want to compare the time in SQL.The main problem is when i compare any time with '00:00:00'/'00:10:00'.
For e.g. select timings from train where trn_time > '19:00:00'.
then in output i want '00:00:00' also wic I am not getting.
And I dont want to use 'Datetime' data type.
Please help.
i created a table in mysql with name 'table11'
CREATE TABLE `table11` (
`id` INT(10) NULL DEFAULT NULL,
`time_col` TIME NULL DEFAULT NULL
)
and inserted data as follows
and when i used following query
select * from table11 tbl where tbl.time_col< '19:00:00'
i got result
if you use tbl.time_col< '19:00:00' then only you will get '00:00:00' in the output.
i think in your case its better to use 'Datetime' datatype