Posts Tagged mssql

MSSQL and ON UPDATE

I had to add a column to a database table on an MSSQL server today. It had to have the most recent update/insert time that the row was inserted/updated. MySQL has a very easy way of doing this with a TIMESTAMP column type, with a DEFAULT value of CURRENT_TIMESTAMP, and then also an additional ON UPDATE CURRENT_TIMESTAMP clause in the column definition to auto-update the value when the row is updated.
So I thought that if MySQL could do it, so should MSSQL be able too, right? Wrong. I’m not expert in MSSQL, I know MySQL fairly well, so my first surprise was to find out that the TIMESTAMP column type in MSSQL is *so* not the same as in MySQL, and in fact is rather completely useless in this example.

The solution turned out to be external to the table definition, by using a trigger.
So here’s how you update a column in your table with the current time whenever that row is update. I’m assuming you know your way around MSSQL and it’s multitudes of tools available, so I won’t be giving you screenshots.

First, add a column to your table as either a DATETIME or SMALLDATETIME, make the default value be: (GETDATE())
The default value takes care of setting the value of the column to the current date/time when a new record is inserted.

Then, add a trigger onto your table, that looks similar to this:

CREATE TRIGGER trg_updateLastUpdated ON [dbo].[your_table_name]
FOR UPDATE
AS
if not update(last_updated)
UPDATE your_table_name
SET last_updated = GETDATE()
FROM your_table_name
INNER JOIN Inserted
ON your_table_name.unique_id = Inserted.unique_id

And that’s that. The trigger makes sure to check that it’s not the last_updated column’s UPDATE that triggers the trigger, as without it, it will cause some nasty recursion to happen.
Your INNER JOIN can be on multiple columns too, if you have more than one column that is required to uniquely identify the single row that you’re updating.

Yes, you could probably update the last_updated column’s value from within whatever code you’ve got, that is an alternative, depending on exactly what you use that column for.
Anyway, this solution worked for me. Did it work for you?

, ,

1 Comment

Perl, FreeTDS and Cron issues

While converting some dodgy nagios-commands into cron scripts today, I came across an age-old issue when scheduling the final script in cron: The script works perfectly when running it on the command-line, but fails miserably when cron runs it.

The usual answer here is “Check the environment variables”.

The error I was getting was from perl’s DBD library when trying to connect to the MSSQL database:

failed: (DBD: dbd_db_login/SQLSetConnectOption err=-2)

Hunting around I wasn’t 100% sure what environment variables I needed.
Turns out we’re using FreeTDS to get Linux to talk to an MSSQL server.

I tried several of the environment variables I found in my shell’s environment, and a mix of several, and as it turns out I was missing only one:

PERL_DL_NONLAZY=1

Seems the previous Windows Admin Guy came across the same problem, didn’t document it anywhere, but did add the variable to the Linux machine’s global profile. This worked while Nagios was calling the perl-script, but cron runs with a nice clean environment, so didn’t help there.
So just export the PERL_DL_NONLAZY variable before you run your perl-script, and voila, there it is.

, , , ,

No Comments