Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serial numbers, created and modified in SQL Server

I'm needing to add serial numbers to most of the entities in my application because I'm going to be running a Lucene search index side-by-side.

Rather than having to run an ongoing polling process, or manually run my indexer by my application I'm thinking of the following:

  • Add a Created column with a default value of GETUTCDATE().
  • Add a Modified column with a default value of GETUTCDATE().
  • Add an ON UPDATE trigger to the table that updates Modified to GETUTCDATE() (can this happen as the UPDATE is executed? i.e. it adds SET [Modified] = GETUTCDATE() to the SQL query instead of updating it individually afterwards?)
  • The ON UPDATE trigger will call my Lucene indexer to update its index (this would have to be an xp_cmdshell call presumably, but is there a way of sending a message to the process instead of starting a new one? I heard I could use Named Pipes, but how do you use named pipes from within a Sproc or trigger? (searching for "SQL Server named pipes" gives me irrelevant results, of course).

Does this sound okay, and how can I solve the small sub-problems?

like image 522
Dai Avatar asked Nov 13 '22 07:11

Dai


1 Answers

As I understood, you have to introduce two columns to your existing tables and have them processed (at east one of them) in 'runtime' and used by an external component.

Your first three points are nothing unusual. There are two types of triggers in SQL Server according to time when trigger get processed: INSTEAD OF trigger (actually processed before insert happens) and AFTER trigger. However, inside INSTEAD OF trigger you have to provide logic what to really insert data into the table, along with other custom processing you require. I usually avoid that if not really necessary.

Now about your fourth point - it's tricky and there are several approaches to solve this in SQL Server, but all of them are at least a bit ugly. Basically you have to either execute external process or send message to it. I really don't have any experience with Lucene indexer but I guess one of these methods (execute or send message) would apply.

So, you can do one of the the following to directly or indirectly access external component, meaning to access Lucene indexer directly or via some proxy module:

  1. Implement unsafe CLR trigger; basically you execute .NET code inside the trigger and thus get access to the whole (be careful with that - not entirely true) .NET framework
  2. Implement unsafe CLR procedure; only difference to CLR trigger is that you wouldn't call it imediatelly after INSERT, but you will do fine with some database job that runs periodically
  3. Use xp_cmdshell; you already know about this one, but you can combine this aproach with job-wrapping technique in last point
  4. Call web service; this technique is usually marked as experimental AND you have to implement the service by yourself (if Lucene indexer doesn't install some web service on its own)
  5. There surely are other methods I can't think of right now...

I would personally go with third point (job+xp_cmdshell) because of the simplicity, but that's just because I lack any knowledge of how does the Lucene indexer work.

EDIT (another option):

Use Query Notifications; SQL Server Service Broker allows an external application to connect and monitor interesting changes. You even have several options how to do that (basically synchronous or asynchronous), only precondition is that your Service Borker is up, running and available to your application. This is more sophisticated method to inform external component that something has changed.

like image 191
OzrenTkalcecKrznaric Avatar answered Nov 15 '22 05:11

OzrenTkalcecKrznaric