April 23, 2008 at 11:49 am
Hi All,
I have an issue where I am trying to create a trigger that will output a single row to a text file on insert, based on a field in that insert. rowID is a primary key that increments itself, triggerfield is user entered data. If I create this trigger and then try to insert, the inset statement hangs and I have to kill and restart the instance. Does any one know if this has to do with record locks or if there is an easier way to accomplish exporting a single row on insert?
This is the trigger I have right now--
CREATE TRIGGER [dbo].[T_OUTPUT_FILE]
ON [DATABASE].[dbo].
AFTER INSERT
AS
IF (SELECT COUNT(*) FROM inserted WHERE [TRIGGERFIELD] = 5) = 1
BEGIN
SET NOCOUNT ON;
DECLARE @FileName varchar(50),
@bcpCommand varchar(2000),
@Record varchar(10)
SET @Record = (Select rowID from inserted WHERE [TRIGGERFIELD] = 5)
SET @FileName = REPLACE('c:\Testing\DropFolder\row_'+CONVERT(char(8),GETDATE(),1)+'.txt','/','-')
SET @bcpCommand = 'bcp "SELECT * FROM database.dbo.table WHERE rowID = convert(int,'
SET @bcpCommand = @bcpCommand + @Record + ')" queryout "'
SET @bcpCommand = @bcpCommand + @FileName + '" -U Username -P Password -c -S Server\Instance'
exec master..xp_cmdshell @bcpCommand
END
April 23, 2008 at 12:29 pm
Hrrmm...
What if there are more than one record with TriggerField = 5 ???
N 56°04'39.16"
E 12°55'05.25"
April 23, 2008 at 12:46 pm
You are probably somewhat deadlocking yourself. The BCP cannot access the record because it is exclusively locked from the insert statement. You could use a NOLOCK hint in the BCP command and read the dirty page.
Now, this looks like a bad idea to begin with. Calling xp_cmdshell from a trigger is probably not a good idea. If you MUST write a file out from a trigger, you would be best off getting it out of your transaction. An option could be Service Broker. I think you could create a CLR procedure and call to a web service.
April 23, 2008 at 2:18 pm
Agree with Michael: using BCP from a trigger is a bad idea, and re-querying data from another process synched with your trigger code (and that is what you are doing here) is a deadlock that the deadlock manager can never find, so you will hang forever.
Even WITH (NOLOCK) has problems with this and Service Broker is what I have used in the past to fix it.
[font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
Proactive Performance Solutions, Inc. [/font][font="Verdana"] "Performance is our middle name."[/font]
April 25, 2008 at 7:28 pm
Another problem other than the ones already stated is that even if all of this worked correctly, BCP destroys existing files and overwrites them.
I may have a work-around for this, but I need to know... why do you only want 1 of the inserted rows instead of all that have been inserted?
--Jeff Moden
Change is inevitable... Change for the better is not.
March 18, 2010 at 1:02 am
In SQL, after creation of table we insert data using INSERT keyword. Suppose we have to insert 10 records, we write 10 INSERT statement for inserting them. However, in SQL Server 20008 a new feature called Row constructor has been introduced which allows us to write a single INSERT statement for inserting more than one record at a time.
Cheers,
Eliza
March 23, 2010 at 11:59 pm
you'll probably get a better response if you start a new thread for your question.
[font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
Proactive Performance Solutions, Inc. [/font][font="Verdana"] "Performance is our middle name."[/font]
November 20, 2017 at 10:11 pm
This was removed by the editor as SPAM
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply