insert null date interbase - database

I need to insert a null or '00/00/00' date value.
Is it possible to do it on interbase?
I already tried to insert '00/00/00' and it wasn't possible.

According to the literature (I have zero experience with InterBase) you can use standard SQL
see section 6-56 "NULLing columns with UPDATE"
UPDATE TABLENAME
SET DATEVALUE = NULL
WHERE SOME_ID = 123
you might have more options depending on your client

Related

SQL server GetDate in trigger called sequentially has the same value

I have a trigger on a table for insert, delete, update that on the first line gets the current date with GetDate() method.
The trigger will compare the deleted and inserted table to determine what field has been changed and stores in another table the id, datetime and the field changed. This combination must be unique
A stored procedure does an insert and an update sequentially on the table. Sometimes I get a violation of primary key and I suspect that the GetDate() returns the same value.
How can I make the GetDate() return different values in the trigger.
EDIT
Here is the code of the trigger
CREATE TRIGGER dbo.TR
ON table
FOR DELETE, INSERT, UPDATE
AS
BEGIN
SET NoCount ON
DECLARE #dt Datetime
SELECT #dt = GetDate()
insert tableLog (id, date, field, old, new)
select I.id, #dt, 'field', D.field, I.field
from INSERTED I LEFT JOIN DELETED D ON I.id=D.id
where IsNull(I.field, -1) <> IsNull(D.field, -1)
END
and the code of the calls
...
insert into table ( anotherfield)
values (#anotherfield)
if ##rowcount=1 SET #ID=##Identity
...
update table
set field = #field
where Id = #ID
...
Sometimes the GetDate() between the 2 calls (insert and update) takes 7 milliseconds and sometimes it has the same value.
That's not exactly full solution but try using SYSDATETIME instead and of course make sure that target table can store up datetime2 up to microseconds.
Note that you can't force different datetime regardless of precision (unless you will start counting up to ticks) as stuff can just happen at the same time wihthin given precision.
If stretching up to microseconds won't solve the issue on practical level, I think you will have to either redesign this logging schema (perhaps add identity column on top of what you have) or add some dirty trick - like make this insert in try catch block and add like microsecond (nanosecond?) in a loop until you insert successfully. Definitely not s.t. I would recommend.
Look at this answer: SQL Server: intrigued by GETDATE()
If you are inserting multiple ROWS, they will all use the same value of GetDate(), so you can try wrapping it in a UDF to get unique values. But as I said, this is just a guess unless you post the code of your trigger so we can see what you are actually doing?
It sounds like you're trying to create an audit trail - but now you want to forge some of the entries?
I'd suggest instead adding a rowversion column to the table and including that in your uniqueness criteria - either instead of or as well as the datetime value that is being recorded.
In this way, even if two rows are inserted with identical date/time data, you can still tell the actual insertion order.

T-SQL Select where Subselect or Default

I have a SELECT that retrieves ROWS comparing a DATETIME field to the highest available value of another TABLE.
The Two Tables have the following structure
DeletedRecords
- Id (Guid)
- RecordId (Guid)
- TableName (varchar)
- DeletionDate (datetime)
And Another table which keep track of synchronizations using the following structure
SynchronizationLog
- Id (Guid)
- SynchronizationDate (datetime)
In order to get all the RECORDS that have been deleted since the last synchronization, I run the following SELECT:
SELECT
[Id],[RecordId],[TableName],[DeletionDate]
FROM
[DeletedRecords]
WHERE
[TableName] = '[dbo].[Person]'
AND [DeletionDate] >
(SELECT TOP 1 [SynchronizationDate]
FROM [dbo].[SynchronizationLog]
ORDER BY [SynchronizationDate] DESC)
The problem occurs if I do not have synchronizations available yet, the T-SQL SELECT does not return any row while it should returns all the rows cause there are no synchronization records available.
Is there a T-SQL function like COALESCE that I can use with DateTime?
Your subquery should look like something like this:
SELECT COALESCE(MAX([SynchronizationDate]), '0001-01-01')
FROM [dbo].[SynchronizationLog]
It says: Get the last date, but if there is no record (or all values are NULL), then use the '0001-01-01' date as start date.
NOTE '0001-01-01' is for DATETIME2, if you are using the old DATETIME data type, it should be '1753-01-01'.
Also please note (from https://msdn.microsoft.com/en-us/library/ms187819(v=sql.100).aspx)
Use the time, date, datetime2 and datetimeoffset data types for new work. These types align with the SQL Standard. They are more portable. time, datetime2 and datetimeoffset provide more seconds precision. datetimeoffset provides time zone support for globally deployed applications.
EDIT
An alternative solution is to use NOT EXISTS (you have to test it if its performance is better or not):
SELECT
[Id],[RecordId],[TableName],[DeletionDate]
FROM
[DeletedRecords] DR
WHERE
[TableName] = '[dbo].[Person]'
AND NOT EXISTS (
SELECT 1
FROM [dbo].[SynchronizationLog] SL
WHERE DR.[DeletionDate] <= SL.[SynchronizationDate]
)

Query help to track daily updates made to table(for specific column)

I have 2 tables Individual(IndividualId is primary key) and IndividualAudit. Every time update is made on individual table
record goes to audit table. There are many columns that can be modified but i am interested only in picking up records where SSN is modified.
I m using below query:
Select DI.IndividualId,DI.ssn FRom Individual I
INNER JOIN IndividualAudit A
ON(I.IndividualId = A.IndividualId and A.UpdateDate = GETDATE())
where i.updatedate = GETDATE() and I.ssn <> a.ssn
group by I.IndividualId,I.ssn
Can someone please tell me whether my approach is correct.
Actually i was searching on google and got scared looking at below link:
Query help when using audit table
the person who answered similar query on this post seem to be very good with sql and comparing with his answer my approach looks quite naive.
so i just want to know where am i wrong in my understanding.
Thanks a lot
Rather than fixing the query, I'd suggest instead using an update trigger aimed specifically at changes to that SSN column you're concerned about. The query you've supplied won't work because of the date comparison (as user2159471 has pointed out). But even after you get the query fixed, you'll still have to run it in order to see which SSNs have been updated.
Instead use a SQL update trigger that, perhaps, inserts an entry into a third table each time an individual's SSN get changed. Then you can look at that table any time you, or run a report against it, to see who's been changed.
The trigger code looks like this:
CREATE TRIGGER MyCoolNewTrigger ON Individual
FOR UPDATE
AS
SET NOCOUNT ON
IF (UPDATE(SSN))
BEGIN
Declare #oldSSN as varchar(40)
Declare #NewSSN as varchar(40)
set #oldSSN = deleted.SSN --holds the old SSN being changes
Set #NewSSN = inserted.SSN -- holds the new SSN inserted
Insert into IndividualUpdateLog (NewSSN, OldSSN, ChangeDate)
values (#NewSSN, #oldSSN, getdate)
END

Linq to SQL with INSTEAD OF Trigger and an Identity Column

I need to use the clock on my SQL Server to write a time to one of my tables, so I thought I'd just use GETDATE(). The problem is that I'm getting an error because of my INSTEAD OF trigger. Is there a way to set one column to GETDATE() when another column is an identity column?
This is the Linq-to-SQL:
internal void LogProcessPoint(WorkflowCreated workflowCreated, int processCode)
{
ProcessLoggingRecord processLoggingRecord = new ProcessLoggingRecord()
{
ProcessCode = processCode,
SubId = workflowCreated.SubId,
EventTime = DateTime.Now // I don't care what this is. SQL Server will use GETDATE() instead.
};
this.Database.Add<ProcessLoggingRecord>(processLoggingRecord);
}
This is the table. EventTime is what I want to have as GETDATE(). I don't want the column to be null.
And here is the trigger:
ALTER TRIGGER [Master].[ProcessLoggingEventTimeTrigger]
ON [Master].[ProcessLogging]
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
SET IDENTITY_INSERT [Master].[ProcessLogging] ON;
INSERT INTO ProcessLogging (ProcessLoggingId, ProcessCode, SubId, EventTime, LastModifiedUser)
SELECT ProcessLoggingId, ProcessCode, SubId, GETDATE(), LastModifiedUser FROM inserted
SET IDENTITY_INSERT [Master].[ProcessLogging] OFF;
END
Without getting into all of the variations I've tried, this last attempt produces this error:
InvalidOperationException
Member AutoSync failure. For members to be AutoSynced after insert, the type must either have an auto-generated identity, or a key that is not modified by the database after insert.
I could remove EventTime from my entity, but I don't want to do that. If it was gone though, then it would be NULL during the INSERT and GETDATE() would be used.
Is there a way that I can simply use GETDATE() on the EventTime column for INSERTs?
Note: I do not want to use C#'s DateTime.Now for two reasons:
1. One of these inserts is generated by SQL Server itself (from another stored procedure)
2. Times can be different on different machines, and I'd like to know exactly how fast my processes are happening.
Bob,
It seems you are attempting to solve two different problems here. One of which has to do with a L2S error with an Instead Of trigger and another with using the date on the SQL Server box for your column. I think you might have problems with Instead of Triggers and L2S. You might want to try an approach that uses an After trigger, like this. I think this will solve both your problems.
ALTER TRIGGER [Master].[ProcessLoggingEventTimeTrigger]
ON [Master].[ProcessLogging]
AFTER INSERT
AS
BEGIN
UPDATE [Master].[ProcessLogging] SET EventTime = GETDATE() WHERE ProcessLoggingId = (SELECT ProcessLoggingId FROM inserted)
END
Don't use a trigger, use a defualt:
create table X
(id int identity primary key,
value varchar(20),
eventdate datetime default(getdate()))
insert into x(value) values('Try')
insert into x(value) values('this')
select * from X
It's much better.
Have you tried using a default value of (getdate()) for the EventTime colum?
You wouldn't then need to set the value in the trigger, it would be set automatically.
A default value is used when you don't explicitly supply a value, e.g.
INSERT INTO ProcessLogging (ProcessLoggingId, ProcessCode, SubId, LastModifiedUser)
SELECT ProcessLoggingId, ProcessCode, SubId, LastModifiedUser FROM inserted
Bob,
I see it is better to don't use triggers in SQL server; it have a lot of disadvantage and not recommended for database performance enhancements. Please check SQL Authority blog for more information about the Triggers problems.
You can achieve what you want without Triggers using the following steps:
Change Eventime column to allow null
Set Eventtime column Default Value to GetDate(). So it always will have a the current insertion value.
Don't set Eventtime value to DateTime.Now from your LinqToSQL code, so it will take the default value in the SQL Server.

Inserting the values with condition

Using SQL Server 2005
When i insert the date it should compare the date in the table.
If it is equal with other date, it should display a error message and also it should allow only to insert the next date.
For Example
Table1
Date
20091201
20091202
Insert into table1 values('20091202')
The above query should not allow to insert the same value
Insert into table1 values('20091204')
The above query also should not allow to insert the long gap date.
The query should allow only the next date.
It should not allow same date and long gap date.
How to insert a query with this condition.
Is Possible in SQL or VB.Net
Need SQL Query or VB.Net code Help
You could use a where clause to ensure that the previous day is present in the table, and the current day is not:
insert into table1 ([dateColumn])
select '20091204'
where exists (
select * from table1 where [dateColumn] = dateadd(d,-1,'20091204')
)
and not exists (
select * from table1 where [dateColumn] = '20091204'
)
if ##rowcount <> 1
raiserror ('Oops', 16, 1)
If the insert succeeds, ##rowcount will be set to 1. Otherwise, an error is returned to VB using raiserror.
Why not just have a table of dates set up in advance, and update a row once you want to "insert" that date?
I'm not sure I understand the point of inserting a new date only once, and never allowing a gap. Could you describe your business problem in a little more detail?
Of course you could use an IDENTITY column, and then have a computed column or a view that calculates the date from the number of days since (some date). But IDENTITY columns do not guarantee contiguity, nor do they even guarantee uniqueness on their own (unless you set up suc a constraint separately).
Preventing duplicates should be done at the table level with a unique constraint, not with a query. You can check for duplicates first so that you can handle errors in your own way (rather than let the engine raise an exception for you), but that shouldn't be your only check.
Sounds like your date field should just be unique with auto-increment.

Resources