BULK insert with FIRE_TRIGGERS not execute the trigger - sql

I am using the following code to Bulk insert a CSV file:
BULK
INSERT CustomSelection
FROM 'c:\asd\a1.csv'
WITH
(
FIRSTROW =2,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
FIRE_TRIGGERS
)
GO
I have the FIRE_TRIGGERS property but the trigger is still not executing.
The trigger works for sure because if i manually insert into the table then it executes. Any help to solve that ?

During a bulk-import operation, your trigger will be fired only once because it's considerated as a single statement that affects multiple rows of data.
Your trigger should be able to handle a set of rows instead a single rows. Maybe this is the reason because your manual insert test is working fine and your bulk import is failing.
The C section of this MSDN article, show you how to create an insert trigger to Handle Multiple Rows of Data: http://msdn.microsoft.com/en-us/library/ms190752.aspx
Hope it helps.

Related

SQL Server : Bulk Insert 0 Rows Affected

I'm new to SQL and I'm attempting to do a bulk insert into a view, however, when I execute the script the message says (0 row(s) affected).
This is what I'm executing:
BULK INSERT vwDocGeneration
FROM '\\servername\Data\Doc\Test.csv'
WITH
(
Fieldterminator = '|',
Rowterminator = '\r\n'
)
I've confirmed the row terminators in my source file and they end with CRLF. The view and the file being imported have the same number of columns. I'm stuck! Any ideas would be greatly appreciated!
Per Mike K 's suggestion I started looking at key constraints and after I adjusted on of them I was able to use the bulk insert! FYI I did insert into the view because the table had an additional field that wasn't included in my CSV file. Thanks for confirming its possible #Gordon Linoff.
If you are looking for the number of rows affected by that operation, then use this.
DECLARE #Rows int
DECLARE #TestTable table (col1 int, col2 int)
// your bulk insert operation
SELECT #Rows=##ROWCOUNT
SELECT #Rows AS Rows,##ROWCOUNT AS [ROWCOUNT]
Or you can first bulk insert into a table, then create an appropriate view from that table.
Following article might be useful -
http://www.w3schools.com/sql/sql_view.asp
http://www.codeproject.com/Articles/236425/How-to-insert-data-using-SQL-Views-created-using-m

need to delete bulk insert object to run again

i have a sql script I am supposed to run that starts with:
BULK INSERT #BridgeVendors
FROM 'D:\projects\databases\Scripts\Release\6.7.1\BridgeVendors.csv'
WITH ( FIELDTERMINATOR=',', FIRSTROW = 2 )
the first time I ran it I had the path name going toincorrect path so it didn't execute properly , but now - I can't run it again because I get the error :
There is already an object named '#BridgeVendors' in the database.
How do I UNDO or DELETE this "Object" that was a BULK INSERT??
You just need to drop the table :)
drop table #BridgeVendors

Issue with SQL Server trigger event firing

I have a trigger on a table that is something like this:
ALTER TRIGGER [shoot_sms]
ON [dbo].[MyTable]
AFTER INSERT
AS
begin
declare #number bigint
declare #body varchar(50)
declare #flag int
select #number=number,#body=body,#flag=flag from inserted
if(#flag=0)
begin
insert into temptable (number,body,status)
select #number,#body,'P'
end
end
Now I am making two entries in mytable as below:
insert into mytable(number, body, flag)
values(3018440225, 'This is test', 0)
insert into mytable(number, body, flag)
values(3018440225, 'This is test', 0)
I execute these queries at a time, but for both of the queries the trigger fires only once and performs the task for the first query only.
How can I make it work for both insert statements?
Just an idea but put a GO statement between those two insert statements and that might cause the trigger to fire twice.
You should probably rewrite your trigger to handle multiple row inserts I think.
Here is your query converted. You should get two rows now.
ALTER TRIGGER [shoot_sms]
ON [dbo].[MyTable]
AFTER INSERT
AS
begin
insert into temptable (number,body,status)
select number,body,'P'
from inserted
where flag = 0
end
Also notice your trigger is much simpler now.
Since those two statements are in one SQL batch, the trigger will (by design) only fire once.
Triggers don't fire once per row - they fire once per statement! So if you have an INSERT or UPDATE statement that affects more than one row, your trigger will have more than one row in the Inserted (and possibly Deleted) pseudo tables.
The way you wrote this trigger is really not taking into account that Inserted could contain multiple rows - what row do you select from the Inserted table if you're inserting 20 rows at once?
select #number = number, #body = body, #flag = flag from inserted
You need to change your trigger to take that into account!

To read CSV file data one by one from SQL Stored proc

Need to read CSV file information one by one. i.e. If the customer in the file is existing in Customer table insert into detail table otherwise insert into error table. So I can't use bulk insert method.
How to read one by one record from CSV file? How to give the path?
Bulk insert method is not going to work here.
One option is to use an INSTEAD OF INSERT trigger to selectively put the row in the correct table, and then use your normal BULK INSERT with the option FIRE_TRIGGERS.
Something close to;
CREATE TRIGGER bop ON MyTable INSTEAD OF INSERT AS
BEGIN
INSERT INTO MyTable
SELECT inserted.id,inserted.name,inserted.otherfield FROM inserted
WHERE inserted.id IN (SELECT id FROM customerTable);
INSERT INTO ErrorTable
SELECT inserted.id,inserted.name,inserted.otherfield FROM inserted
WHERE inserted.id NOT IN (SELECT id FROM customerTable);
END;
BULK INSERT MyTable FROM 'c:\temp\test.sql'
WITH (FIELDTERMINATOR=',', FIRE_TRIGGERS);
DROP TRIGGER bop;
If you're importing files regularly, you can create a table (ImportTable) with the same schema, set the trigger on that and do the imports to MyTable through bulk import to ImportTable. That way you can keep the trigger and as long as you're importing to ImportTable, you don't need to do any special setup/procedure for each import.
CREATE TABLE #ImportData
(
CVECount varchar(MAX),
ContentVulnCVE varchar(MAX),
ContentVulnCheckName varchar(MAX)
)
BULK INSERT #ImportData
FROM 'D:\test.csv'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = ',', --CSV field delimiter
ROWTERMINATOR = '\n', --Use to shift the control to next row
TABLOCK
)
select * from #ImportData
//Here you can write your script to user read data one by one
DROP TABLE #ImportData
Use bulk insert to load into a staging table and then process it line by line.

How to Use FIRE_TRIGGERS in insert sql statement

I am trying to copy data from table "tb_A" to itself (with different primary key).
When "tb_A" table is insert new record, I have written a trigger to populate another table "tb_B" with one record.
I ran the following statement.
INSERT INTO [tb_A]
([NAME])
select top (20)[NAME] from [tb_A]
I was expected 20 new records in "tb_B". But I didn't.
Anyway I saw FIRE_TRIGGERS is using during bulk insert to overcome this issue.
is there is a any way to use it on inset statements too ? Please provide me example.
Gayan
Trigger code (copied from Gayan's comment to gbn's answer):
CREATE TRIGGER UpdatetbB ON [dbo].[tb_A] FOR INSERT
AS
DECLARE #AID as int
SELECT #AID = [ID] FROM inserted
INSERT INTO [tb_B]([IDA]) VALUES (#AID)
The reason your trigger did not work properly is because it is poorly designed. Triggers fire once for each insert even if you are inserting a million records. You havea trigger that makes the assumption it will owrk one record at a time. Anytime you set a value form inserted or deleted to a scalar variable the trigger is wrong and needs to be rewritten. Try something like this instead.
CREATE TRIGGER UpdatetbB ON [dbo].[tb_A] FOR INSERT
AS
INSERT INTO [tb_B]([IDA])
SELECT [ID] FROM inserted
FIRE_TRIGGERS is only for BULK INSERT (and bcp), not "standard" INSERT
I'd expect your trigger to look something like
CREATE TRIGGER TRG_tbA_I ON tb_A FOR INSERT
AS
SET NOCOUNT ON
INSERT tb_B (col1, col2, ...)
SELECT col1, col2, ... FROM INSERTED
GO
You use the special INSERTED table to get the list of new rows in tb_A, then INSERT from this into tb_B. This works for more than one row
If you add the trigger code then we can explain what went wrong.
Edit: your trigger will only read a single row (any row, no particular order) from INSERTED. It isn't set based like my rough example.