Create a Trigger to change values before insert in Informix - sql

We have a table with a date field. Also there are some old apps we can't modify whose inserts that date field with string ("yyyy-mm-dd") (Yeah, SQL Injectión Party!!). Now it's needed to change that field to a Datetime year to second. This makes that old apps fail.
create table test(
testDate DATETIME YEAR TO SECOND
);
insert into test values("2018-12-12")
Error: A field in a datetime or interval value is incorrect or an illegal operation specified on datetime field.
We are trying to make a trigger to concatenate " 00:00:00" to the string if its length is 10. That should correct the problem.
It's that even posible?
Seems to me that if I use a before insert trigger, I can't modify the insert values. But if I use for each row instead, the trigger is not launched because the Error is throwed first.
Any Idea?

Related

How to stop the insertion of default date format 1900-01-01 in SQL Server when user input is null

I have an input field in my application,which accepts date through date picker. Sometimes users do not select any date and they may submit blank (client requirement) as it's not a mandatory field.
Once after blank submission the data which is stored into the SQL Server 2008 database is '1900-01-01'. Instead I need the data to be stored as 'NULL' or 'empty' or '0000-00-00' but not any other valid date format.
If the request.getparameter() is empty, I tried to insert '0000-00-00'. But it is stopping the insertion.
My aim is to insert either 'NULL' or '-' or '0000-00-00' when the user is submitting the blank field. Instead of '1900-01-01'.
Unfortunately, SQL Server interprets a "blank" (i.e. empty string) as a date with the value of 1900-01-01. So when you write:
insert into t (datecol)
values ('');
This is basically compiled into:
insert into t (datecol)
values ('1900-01-01');
What can you do? The most obvious is to not insert blank values. You want to insert NULL, so insert NULL. In this case, you can use NULLIF():
insert into t (datecol)
values (nullif('', ''));
That will turn the input into an appropriate value.
A second option is to reject such values using a check constraint:
alter table t add constraint chk_t_datecol
check (date >= '1950-01-01');
That is, dates are within some acceptable range.
A third option would be to add a trigger to convert '1900-01-01' to a NULL value when seen on input.
And a fourth option would be to allow such values but to use a computed column for reference purposes:
alter table t add datecol_good as ( nullif(datecol, '1900-01-01'));
All of these options assume that '1900-01-01' is not a valid date that you would want in your data.

SQL Server Add Default datetime column for existing table

I want to have a new column in the table that will show the date and time of the inserts, but without modifying the queries to include the column itself.
I have added the new column in the following way:
ALTER TABLE DBO.HOURLYMODULETIMES
ADD CreateTime datetime DEFAULT NOT NULL getdate()
This adds the values to previous entries, but when I try to INSERT INTO the table without including the new column
INSERT INTO DBO.HOURLYMODULETIMES VAlUES
(99999999,11111,2222,'JA')
Table has 5 columns ID, AVGMODULETIME, SUMHOURS, USERNAME, CreateTime(newly added). I get the following error:
Column name or number of supplied values does not match table definition.
Is it possible to create such a column without modifying the queries?
You have to specify the columns now when you want to omit one of them when doing INSERT:
INSERT INTO DBO.HOURLYMODULETIMES (ID, AVGMODULETIME, SUMHOURS, USERNAME)
VALUES (99999999,11111,2222,'TEST')
It's good programming practice to always do this, since table definitions may change over time - as you have noticed!

SQL : datatype as trunc(sysdate)

I was trying to create a table with a column's data type as trunc(sysdate).
Is that possible?
When I tried it , I got below error
SQL Error: ORA-00902: invalid datatype
I am trying this because I want to make sure data inserted into that column doesn't have timestamp.
Just create a trigger
CREATE TRIGGER schema.trigger_name
BEFORE INSERT OR UPDATE
ON schema.table_name
FOR EACH ROW
new.column_name = trunc(column_name);
No that is not possible.
Trunc() is a function that truncates date to a specific unit of measure.
The DATE datatype stores point-in-time values (dates and times) in a
table. The DATE datatype stores the year (including the century), the
month, the day, the hours, the minutes, and the seconds (after
midnight).

How do you update a datetime field in a table every time another field in the same table gets updated?

I have a table called YearTable with three columns (Year, Status, and LastUpdatedTime). Every time someone adds/updates a value into the year or status column LastUpdatedTime needs to be updated. I wrote a trigger for this, but now every time I try to add a new record I get an error message:
ErrorSource: .NetSqlClient Data Provider.
Error Message: Cannot insert the value NULL into Column 'Year', table 'Budget.YearTable'; column does not allow nulls. Insert fails.
This is the trigger:
CREATE TRIGGER UpdateTrigger
ON YearTable
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
insert into tblaudit(LastUpdatedTime)
values(GETDATE())
END
GO
You stated:
I wrote a trigger for this, but now every time I try to add a new record I get an error message:
ErrorSource: .NetSqlClient Data Provider. Error Message: Cannot insert the value NULL into Column 'Year', table 'Budget.YearTable'; column does not allow nulls. Insert fails.
From this, does this mean your updates and deletes are working? If that is the case, then it sounds like just like the error message states. When you're doing an insert into the table, you aren't supplying a value for the year column on the YearTable.
Have you tried disabling the trigger and seeing if the behavior exists when doing the same operations?
After further consideration of your question, I'm now assuming you're meaning that when a row in YearTable is updated, that that same row in YearTable has its LastUpdated column updated. Though now I'm not really sure where your tblAudit is coming from. Or why you would have the trigger created for deletes when there would be no row to update at that point.
I'm going to assume that your key on the table is year - if you don't currently have a key, you probably need one.
To handle the LastUpdated for inserts/updates you could use the following in your trigger (assuming year is your key):
UPDATE YearTable
SET LastUpdated = GetDate()
FROM inserted
where YearTable.Year = inserted.year

How do I set a value for existing rows when creating a new timestamp column?

I have the following table:
Study id
Pepsi 1
Coke 2
Sprite 3
I need to add a new column timestamp in the above table. i.e, study creation time and date will be stored in this column. What value should I have set for existing rows? Or should the "Timestamp" column have a value only for newly created rows?
I have used the following query to add the new column:
alter table Study add Timestamp datetime
There is no way to tell you what value you should set for existing rows - that is up to you to decide. If you can somehow retrieve the creation time by piecing together other information, then perhaps you can do this one by one, or you could just leave the existing rows to NULL.
Setting a default like GETDATE() for the column, and setting it to NOT NULL, forces all of the existing rows to inherit the current date and time - and you won't be able to set those back to NULL. I'm quite opposed to using garbage token values like 1900-01-01 to represent unknown, and I also don't believe in modifying the code to say something like "if the date is October 8, 2013 then that's because we just didn't know." So I would suggest adding a NULLable column with a default:
ALTER TABLE dbo.Study ADD CreationTime DATETIME NULL DEFAULT CURRENT_TIMESTAMP;
GO
Note that if you leave the column nullable, then the DEFAULT constraint is only useful if DML never sets it to NULL. If an INSERT statement, for example, explicitly places NULL there, the default is ignored. A way around this is to use a trigger (just like you would handle an update):
CREATE TRIGGER dbo.StudyCreationTime
ON dbo.Study
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
UPDATE s
SET s.CreationTime = CURRENT_TIMESTAMP
FROM dbo.Study AS s
INNER JOIN inserted AS i
ON s.StudyID = i.StudyID;
END
GO
what value should i have to set for previous studies
This would have to be defined by your business. This doesn't require a technical answer, so no one here can tell you what is right.
I have used below query to adding new column:
alter table Study add Timestamp datetime
This will work just fine, though this will allow nulls. I might suggest making this column non-null, adding a default, and changing the name of the column slightly since timestamp is a reserved word in SQL Server (a datatype that has not much to do with dates or times):
alter table Study add CreateDate datetime not null default current_timestamp;
Note that this will set all rows to the current date and time, so you may want to update them if you have more accurate data. Alternatively, simply create the column as nullable and existing rows won't get the default value, but rather null instead.
Another choice you might have to make is whether to use local time or UTC time (e.g. default getutcdate()). You might want to use the same time that your servers use or that other "CreateDate" columns use.