Question on seting a default on a table column

  • Hi,

    it is a long story, but I have a process that enters dates incorrectly in a table, that I can not change.  It enters the dates with the slashes going the wrong way. that is 04/25/2019 is shown incorrectly as 04\25\2019.

    So I would like to put this as a check in the column REPLACE(status_date,'\','/'), not sure is that a default or a constraint. but either way not sure how to do that, and have not been able to find exactly how to do this online.

    any ideas would be really appreciated.

     

    Thank you

  • Neither defaults nor constraints will help here.

    But an INSTEAD OF INSERT trigger could do the work. Have a look here for an example/walkthrough.

    Incidentally, what is the datatype of the target column? I'm hoping it's not varchar() ... If it is, I will have a different suggestion.

    If you haven't even tried to resolve your issue, please don't expect the hard-working volunteers here to waste their time providing links to answers which you could easily have found yourself.

  • yes, it is a varchar(), and yes I know it should be a Date but I do not think I will be able to change it.

    And I could use a trigger but would really rather sue a constraint if that is possible.

    Would you know how to do that?

    Thnak you

  • Would you know how to do that?

    No I don't. Constraints and checks are there to prevent bad things happening. They do not change data.

    Have you considered leaving the column as it stands and adding a new computed date column which does the transformation work for you & gives you a column of the proper type as a bonus?

    If you haven't even tried to resolve your issue, please don't expect the hard-working volunteers here to waste their time providing links to answers which you could easily have found yourself.

  • Typically you'd use an AFTER trigger to correct the data.  If you wanted to, you could also have the trigger verify whether the value is a valid date or not.

    SET ANSI_NULLS ON;
    SET QUOTED_IDENTIFIER ON;
    GO
    CREATE TRIGGER table_name__TR_correct_status_date
    ON dbo.table_name
    AFTER INSERT, UPDATE
    AS
    SET NOCOUNT ON
    IF TRIGGER_NESTLEVEL(@@PROCID, 'AFTER' , 'DML') = 1
    BEGIN
    UPDATE tn
    SET status_date = REPLACE(i.status_date, '\', '/')
    FROM inserted i
    INNER JOIN dbo.table_name tn ON tn.$IDENTITY = i.$IDENTITY /*or tn.<key_col> = i.<key_col>*/
    WHERE UPDATE(status_date) AND i.status_date LIKE '\'
    END /*IF*/
    /*end of trigger*/
    GO

     

    SQL DBA,SQL Server MVP(07, 08, 09) "Money can't buy you happiness." Maybe so, but it can make your unhappiness a LOT more comfortable!

  • Okay, that does look good.

    Thanks

  • I like Scott's approach but honestly, I'd avoid the LIKE. If this changes, it would likely be quicker to just update all rows inserted.

  • Steve Jones - SSC Editor wrote:

    I like Sue's approach but honestly, I'd avoid the LIKE. If this changes, it would likely be quicker to just update all rows inserted.

    Sue?

    If you haven't even tried to resolve your issue, please don't expect the hard-working volunteers here to waste their time providing links to answers which you could easily have found yourself.

  • Oops, I left out one important line, to prevent run-away trigger recursion.  In this case the UPDATE itself would prevent recursion, but it's safer to always check, in case other UPDATE(s) are added later.   Therefore, I added this into the original code:

    IF TRIGGER_NESTLEVEL(@@PROCID, 'AFTER' , 'DML') = 1

    SQL DBA,SQL Server MVP(07, 08, 09) "Money can't buy you happiness." Maybe so, but it can make your unhappiness a LOT more comfortable!

  • I'm dating myself here, but:

    Bill or George! Anything but Sue!

    SQL DBA,SQL Server MVP(07, 08, 09) "Money can't buy you happiness." Maybe so, but it can make your unhappiness a LOT more comfortable!

  • Thanks again for everyone's help here

  • ScottPletcher wrote:

    I'm dating myself here, but:

    Bill or George! Anything but Sue!

    I just noticed this in one of the OP's earlier posts – maybe it's what triggered Steve

    And I could use a trigger but would really rather sue a constraint if that is possible.

    If you haven't even tried to resolve your issue, please don't expect the hard-working volunteers here to waste their time providing links to answers which you could easily have found yourself.

  • sorry, I meant use

  • I'm a moron. Was responding to Sue H in another thread and that was on my mind when I read Scott's post. I try to avoid triggers, but if users are entering this data and you have to accept it, the trigger makes sense for a quick REPLACE() and cleanup.

  • Rather than a trigger, you could add a calculated column to handle the replace and convert the result to an actual date at the same time, e.g.

    Drop Table If Exists #Temp
    Create Table #Temp
    (
    UserEnteredDate VarChar(10) Not Null,
    ActualDate As Try_Convert(Date, Replace(UserEnteredDate, '\', '/'), 103) Persisted
    )

    Insert into #temp(UserEnteredDate)
    values ('12/02/2019'),('12\02\2019'),('bob')

    Select * from #temp

    Replace the Try_Convert with a Convert if you want entering an invalid string to fail (I'm guessing not based on currently allowing the wrong type of slashes)

Viewing 15 posts - 1 through 14 (of 14 total)

You must be logged in to reply to this topic. Login to reply