when I try to insert my date values in all my other tables it works fine, except of one. Whatever format I try I always get the error, that the inserted value couldn't be converted from an input char to the expected date format.
That's how I insert my values
-- ServiceTicket
INSERT INTO ServiceTicket
VALUES ('90000', '01-5-2019', '50000', '10000', '70000', 200.00, 100.00, 5.00, 350.00) --Error converting into DATE type
And this is the table structure:
CREATE TABLE dbo.ServiceTicket (
ticketIssueNo INT NOT NULL IDENTITY(1,1) PRIMARY KEY, --Identity autoincrements
serviceDate DATE NOT NULL,
vehicleId CHAR(8) NOT NULL,
customerId CHAR(8) NOT NULL,
inspectionId CHAR(8) NOT NULL,
serviceCost DECIMAL(10,4) NOT NULL CHECK(serviceCost BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,
inspectionCost DECIMAL(10,4) NOT NULL CHECK(inspectionCost BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,
repairCost DECIMAL(2,2) NOT NULL CHECK(repairCost BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,
GST DECIMAL(10,4) NOT NULL DEFAULT 0.0,
amountDue DECIMAL(10,4) NOT NULL CHECK(amountDue BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,
FOREIGN KEY(vehicleId) REFERENCES Vehicle(vehicleId)
ON UPDATE NO ACTION,
FOREIGN KEY(inspectionId) REFERENCES VehicleInspection(inspectionId)
ON UPDATE NO ACTION,
FOREIGN KEY(customerId) REFERENCES Customer(customerId)
ON UPDATE NO ACTION
)
GO
I might overlook something.
Always list the columns when writing an insert statement.
Here's an exact equivalnet of your insert statement, written properly, based on the DDL you've published:
INSERT INTO ServiceTicket
(serviceDate, vehicleId , customerId, inspectionId , serviceCost , inspectionCost, repairCost, GST , amountDue) VALUES
('90000' , '01-5-2019' , '50000' , '10000' , '70000' , 200.00 , 100.00 , 5.00 , 350.00)
I've used tabs so that each value would be perfectly aligned with the column it goes into, that helps a lot when you have a long list of columns.
As you can clearly see, the serviceDate gets the value '90000' - while it shoud clearly be '01-5-2019'
Always use ISO8601 format for string representation of date / datetime values.
Any other format is culture dependent, and the worst thing about it is that it depends on the default language of the login - so different logins might have different results if you use a culture-dependent format. The ISO8601 standard provides two alternatives for datetime formats: yyyy-mm-ddThh:mm:ss or yyyymmddThhmmss. If you are inserting only a date only string value into a DateTime data type column / variable, be sure to use only the second (yyyymmdd) format - because yyyy-mm-dd is still culture dependent with DateTime (but not with Date or with DateTime2 - that's one more reason why you should never use DateTime again.
So the proper way of writing the insert statement would be this:
INSERT INTO ServiceTicket
(serviceDate, vehicleId , customerId, inspectionId , serviceCost , inspectionCost, repairCost, GST , amountDue) VALUES
('2019-05-01', '90000' , '50000' , '10000' , '70000' , 200.00 , 100.00 , 5.00 , 350.00)
(That is, assuming 01-5-2019 stands for May 1st. If it stands for January 5th, it should be 2019-01-05).
The date format '01-5-2019' which you are using does not appear to be a default accepted date literal by SQL Server. Try using '20190501':
INSERT INTO ServiceTicket (serviceDate, ... <other columns>)
VALUES
('20190501', ...);
Note that YYYYMMDD is an unambiguous unseparated ISO format, as the documentation discusses.
The format for inserting date type in SQL is YYYY-dd-MM, You need to change it to '2019-05-01'
Change your date format from '01-5-2019' to '2019-05-01'.
Instead passing date as '01-5-2019' pass CAST('01-5-2019' AS DATE).
The default format for the year data type in SQL is YYYY-MM-DD(If you've not changed it before) Info. So as described here, you should convert the input string into a valid date type.
Related
I have this SQL statement to create a table that stores the JSON string data and the event time found in that JSON string.
CREATE TABLE [dbo].[EventLog]
(
[EventID] INT NOT NULL IDENTITY(1,1),
[EventTime] AS CAST(JSON_VALUE(RawEvent, '$.EventTime') AS DATETIME ) PERSISTED,
[RawEvent] NVARCHAR(MAX) NOT NULL
)
However I get the following error below when I run this, I assume SQL Server does not know if the value fits DATETIME? is there a way to get this column defined?
Msg 4936, Level 16, State 1, Line 26
Computed column 'EventTime' in table 'Event' cannot be persisted because the column is non-deterministic.
You can use CONVERT with dates and have deterministic behavior as long as you specify certain date styles. As per the docs here, with the most common JavaScript date formats (since you are converting from JSON), you can use style 126 or 127, which are ISO8601 and ISO8601 with time zone. Your table, then, could be specified like this:
CREATE TABLE [dbo].[EventLog]
(
[EventID] INT NOT NULL IDENTITY(1,1),
[EventTime] AS CONVERT(DATETIME, JSON_VALUE(RawEvent, '$.EventTime'), 126) PERSISTED,
[RawEvent] NVARCHAR(MAX) NOT NULL
)
Alas, this is explained in the documentation:
CAST Deterministic unless used with datetime, smalldatetime, or sql_variant.
You may be able to parse the date and reconstruct the value using datefromparts() or datetimefromparts().
Not a duplicate of User-Defined Table Type insertion sometimes causing conversion error
I have a user defined table type:
CREATE TYPE [dbo].[udtImport] AS TABLE(
Name varchar(256) null
Code varchar(32) null
StartDate varchar(256) null
EndDate varchar(256) null
DateCreated datetime null
The DateCreated field is populated in my DB layer using DateTime.Now(), while all other fields are from an imported table.
When I import a file with the date fields populated I get a SQL error:
Conversion failed when converting date and/or time from character
string.
Intercepting the generated code using SQL Profiler shows this:
DECLARE #p1 dbo.udtImport;
INSERT INTO #p1
VALUES
( N'Kit A1',
N'A002',
'2016-04-02 00:00:00.000',
'2016-10-10 00:01:00.000',
'2018-10-22 16:08:28.6823468' );
exec impSaveImport #ImportList=#p1
impSaveImport is a stored procedure that has just one parameter: the table type var and does a straight insert to table [Import]. No logic, no triggers, no reference to other tables.
Executing this code in SSMS shows the same error as expected.
Trimming the last 4 digits off the last DateTime field causes the insert query to succeed.
So far so good.
When I import a file with the StartDate and EndDate fields empty, I get no error, and data is successfully inserted into the Import table.
When I intercept the successful insert using profiler I get this:
DECLARE #p1 dbo.udtImport;
INSERT INTO #p1
VALUES
( N'Kit A1',
N'A002',
null,
null,
'2018-10-22 16:34:11.5243245' );
exec impSaveImport #ImportList=#p1
Keep in mind this query SUCCESSFULLY insert one row into the table Import.
When I run this latest query in SSMS I get the same conversion error as before,
but it ran without error from within my MVC app!
This last part has me stumped.
How can it be?
Project is using MVC with SQL2016.
You could use DATETIME2:
CREATE TYPE [dbo].[udtImport] AS TABLE(
Name varchar(256) null,
Code varchar(32) null,
StartDate varchar(256) null, -- should be datetime2 format
EndDate varchar(256) null, -- should be datetime2 format
DateCreated datetime2 null);
DECLARE #p1 dbo.udtImport;
INSERT INTO #p1(Name, Code, StartDate, EndDate, DateCreated)
VALUES
( N'Kit A1',
N'A002',
'2016-04-02 00:00:00.000',
'2016-10-10 00:01:00.000',
'2018-10-22 16:08:28.6823468' );
db<>fiddle demo
I've been fighting with this problem for a few days.
I created the next table in Oracle's SQL Developer:
CREATE TABLE EMPLEADOSMM (
ID_EMPLEADO VARCHAR2 (10) PRIMARY KEY,
NOMBREEM VARCHAR2 (15) NOT NULL,
AP_PATEM VARCHAR2 (20) NOT NULL,
AP_MATEM VARCHAR2 (20) NOT NULL,
FECHA_NAC DATE NOT NULL,
FECHA_ING DATE NOT NULL,
ID_CARGO VARCHAR2 (10));
Then, I proceeded to add some values to the table, the thing is that it added some like this:
INSERT INTO EMPLEADOSMM VALUES ('100006','OSCAR','MARIN','PEREZ','12-jul-85','15-nov-17','C0002');
But this others send me the 'ORA-01858: a non-numeric character was found where a numeric was expected' error.
INSERT INTO EMPLEADOSMM VALUES ('100004','FABIAN','RODRIGUEZ','VELEZ','31-aug-87','13-jul-17','C0003');
INSERT INTO EMPLEADOSMM VALUES ('100005','LUZ MARIA','TORINO','YAÑEZ','11-dec-90','13-jul-17','C0003');
I tried changing the year format by "yyyy", rewriting all the zeros, but nothings seems to work. Some ideas?
First, I want to emphasize that the code does work. Here is a SQL Fiddle demonstrating the working code.
Second, that means that something about your system causes it to break. Barbaras Ozhan seems to have the right explanation -- internationalization settings recognize some month abbreviations as being the same as English, but not all of them.
You should be writing the insert as:
INSERT INTO EMPLEADOSMM (ID_EMPLEADO, NOMBREEM, AP_PATEM, AP_MATEM, FECHA_NAC, FECHA_ING, ID_CARGO)
VALUES ('100006', 'OSCAR', 'MARIN', 'PEREZ', DATE '1985-07-12', DATE '2017-11-15', 'C0002');
INSERT INTO EMPLEADOSMM (ID_EMPLEADO, NOMBREEM, AP_PATEM, AP_MATEM, FECHA_NAC, FECHA_ING, ID_CARGO)
VALUES ('100004', 'FABIAN', 'RODRIGUEZ', 'VELEZ', DATE '1987-08-31', DATE '2017-07-13', 'C0003');
INSERT INTO EMPLEADOSMM (ID_EMPLEADO, NOMBREEM, AP_PATEM, AP_MATEM, FECHA_NAC, FECHA_ING, ID_CARGO)
VALUES ('100005', 'LUZ MARIA', 'TORINO', 'YAÑEZ', DATE '1990-12-11', DATE '2017-07-13', 'C0003');
Oracle supports the ANSI standard keyword DATE for introducing date constants in the ISO/ANSI standard format, YYYY-MM-DD. I strongly recommend that you use this format in all your code. Use TIMESTAMP when there is a time component.
Including the column names is a best practice.
I would question why the employee id is a string, if you are only going to include numbers in it.
I got a table with date type column and default set to: getdate()
But when I try to do datediff() on two separated raws, it always gives me 0 or some constant value. How to assign default value of date and perform datediff() that will work?
Example code, that reproduce my problem
CREATE TABLE Test
(
id INT PRIMARY KEY NOT NULL IDENTITY,
date DATE DEFAULT getdate() NOT NULL,
user VARCHAR(100)
);
CREATE UNIQUE INDEX Test_id_uindex ON Test (id);
Call the below raws with 1 sec delay in between or more
INSERT INTO Test(user) VALUES ('Cool1')
INSERT INTO Test(user) VALUES ('Cool2')
Now look below over the strange outputs of the next queries:
SELECT getdate() as date
Output:
date
2016-12-22 10:42:40
SELECT * from Test
Output:
id date user
1 2016-12-22 Cool
2 2016-12-22 Cool1
And the last one:
SELECT
a.id,
datediff(MILLISECOND, a.date, b.date)
FROM Test a
JOIN Test b ON a.id = b.id + 1
Output:
id difTime
2 0
Your code is fine. You are confusing the date data type with datetime or datetime2. Change your table definition to use a type that stores the time along with the date:
CREATE TABLE Test (
id INT PRIMARY KEY NOT NULL IDENTITY,
date DATETIME DEFAULT getdate() NOT NULL,
user VARCHAR(100)
);
This is a natural place for confusion because GETDATE() returns a value with a time component. However, DATE doesn't support the time component.
You can also use CURRENT_TIMESTAMP, whose name is a bit more evocative of the fact that it returns the time.
I have this SQL-Statement:
SELECT Geburtsdatum FROM Kunde
WHERE Geburtsdatum BETWEEN '1993-01-01' AND '2000-01-01'
but I get some weird results, like: 2.02.1990
'Geburtsdatum' is a DATE
Any suggestions or solutions?
my table-structure:
CREATE TABLE Kunde (
Kunde_ID INTEGER NOT NULL ,
Card INTEGER ,
Vorname VARCHAR(255) NOT NULL ,
Nachname VARCHAR(255) NOT NULL ,
Ort VARCHAR(255) NOT NULL ,
Strasse VARCHAR(255) NOT NULL ,
Postleitzahl VARCHAR(10) NOT NULL ,
Mail VARCHAR(255) ,
Telefonnummer VARCHAR(255) ,
Geburtsdatum DATE NOT NULL ,
Beitrittsdatum DATE NOT NULL ,
Geschlecht INTEGER NOT NULL ,
Land VARCHAR(255) NOT NULL DEFAULT 'Österreich' ,
Bankname VARCHAR(255) ,
Bankleitzahl VARCHAR(255) ,
Kontonummer VARCHAR(255) ,
GroupID INTEGER NOT NULL ,
Besucher INTEGER ,
Access BOOLEAN ,
image BLOB NULL ,
writeDate DATE ,
drinkAbo BOOLEAN ,
PRIMARY KEY (Kunde_ID) )
From the documentation:
SQLite does not have a storage class set aside for storing dates and/or times.
So your column isn't exactly stored as a date. Reading further, we learn that columns specifed as DATE are actually stored as NUMERIC using affinity rule 5.
Going back up to section 1.2:
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
Good. So let's try:
SELECT Geburtsdatum FROM Kunde
WHERE Geburtsdatum
BETWEEN julianday('1993-01-01') AND julianday('2000-01-01');
Oddly enough, SQL Fiddle seems to store DATEs as strings and the above doesn't work. In this case, the following should:
SELECT Geburtsdatum FROM Kunde
WHERE date(Geburtsdatum)
BETWEEN date('1993-01-01') AND date('2000-01-01');
Additionally, in your case you seem to be getting some strange (read: localized) format returned. I wonder if it really is a string in your case too, just with a different format. You could try:
SELECT Geburtsdatum FROM Kunde
WHERE strftime('%d.%m.%Y', Geburtsdatum)
BETWEEN date('1993-01-01') AND date('2000-01-01');
Someone had the same problem and got it resolved. (use datetime function before comparison)
See SQLite DateTime comparison
Excerpt:
Following the datetime function and having a string format as YYYY-MM-DD HH:mm:ss i achieved good results as follows
select *
from table_1
where mydate >= Datetime('2009-11-13 00:00:00')
and mydate <= Datetime('2009-11-15 00:00:00')
--EDIT--
You are basically comparing strings. Which is why the unexpected behavior. Convert to datetime using the function right before comparison and it should work.
To be able to compare dates, you must store them in one of SQLite's supported date formats, such as a JJJJ-MM-TT string. Your dates are stored as strings in a localized date format which is not recognized by SQLite.
If the most significant field is not at the start of the string, string comparisons will not work for dates.
With the values currently in your table, you will not be able to do any comparisons.