After Update, Insert Trigger not working on Update SQL Server VB.net - sql-server

I am building a personal comic book database and am having an issue with one of my SQL Server triggers.
My main comic entry (tabbed) form has a combo box for cover prices.
When the user clicks submit and inserts a comic into the database (comic_books table) on the comics entry page, I have a trigger that adds the cover price the user entered to a separate table (comic_prices table.) if the entry does not exist. This is working just fine.
However, I have a second tab ('Edit Comic') where the user can update an already inserted comic which uses a simple update script.
The user is able to change or add a new cover price of said comic from this tab also.
The issue I am having is that when the user clicks the 'Update Comic' button from the 'Edit Comic' tab, this newly entered comic price is not being inserted in the comic_prices table if it does not exist. So it looks like my trigger is only firing on my insert script and not on my update script.
Again, I have the trigger to only insert if the entry does not exist in the cover_prices table, otherwise it does nothing.
Please see my 'AFTER UPDATE, INSERT' trigger for this below and please let me know if you need any more information!
I appreciate any pointers or critiques!
DECLARE #cover_price varchar(50)
select #cover_price = cover_price from comic_books
If exists (SELECT cover_price FROM comic_prices where cover_price = #cover_price )
Begin
Return
End
IF not EXISTS (SELECT cover_price FROM comic_prices where cover_price = #cover_price)
INSERT INTO comic_prices(cover_price)VALUES(#cover_price)

UPDATE 04/22/17
After two or so weeks, I finally figured it out! I ended up making two separate triggers, one for the insert and another for the update. I kept the insert the same, however, the update looks like this:
DECLARE #publisher_name varchar(50)
--declare #comic_id bigint
select #publisher_name = inserted.issue_publisher from inserted
select #comic_id = comic_id from comic_books
If exists (select publisher_name from comic_publishers where publisher_name = #publisher_name)
Begin
return
End
IF not EXISTS (select publisher_name from comic_publishers where publisher_name = #publisher_name)
INSERT INTO comic_publishers (publisher_name)VALUES(#publisher_name)
I needed to tell the trigger to look for the inserted publisher!

Related

Oracle (v18/19) Trigger on Materialized View does not know about old values

In our tool we use triggers on materialized views in order to create log-entries (and do some other things) when a transaction is commited.
The code works good in Oracle 12. In Oracle 19 the old values in that trigger (":old") seems to be lost.
Investigations:
This seems to be the case in the combination of materialized views/triggers. If we set the same trigger on a table the logs are generated correctly (but we do not get the transaction-awareness which is required).
I have created a MWE and added comments to the DBMS_OUTPUT-Lines which describe what we see in oracle 12 and Oracle 18/19:
/*Create Test-Table*/
CREATE TABLE MAT_VIEW_TEST (
PK number(10,0) PRIMARY KEY ,
NAME NVARCHAR2(50)
);
/*insert some values*/
insert into MAT_VIEW_TEST values (1, 'Herbert');
insert into MAT_VIEW_TEST values (2, 'Hubert');
commit;
/*Create mateterialized view (log) in order to set trigger on it*/
CREATE MATERIALIZED VIEW LOG ON MAT_VIEW_TEST WITH PRIMARY KEY, ROWID including new values;
CREATE MATERIALIZED VIEW MV_MAT_VIEW_TEST
refresh fast on commit
AS select * from MAT_VIEW_TEST;
/*Create trigger to log old and new value*/
CREATE OR REPLACE TRIGGER MAT_VIEW_TRIGGER
BEFORE INSERT OR UPDATE
ON MV_MAT_VIEW_TEST
FOR EACH ROW
DECLARE
old_pk number(10,0);
new_pk number(10,0);
old_name NVARCHAR2(50);
new_name NVARCHAR2(50);
BEGIN
old_pk := :old.pk;
old_name := :old.name;
new_pk := :new.pk;
new_name := :new.name;
DBMS_OUTPUT.PUT_LINE('TEST BEGIN');
DBMS_OUTPUT.PUT_LINE('old p ' || old_pk); /*old is set in oracle 12, but not in oracle18/19*/
DBMS_OUTPUT.PUT_LINE('old n ' || old_name); /*old is set in oracle 12, but not in oracle18/19*/
DBMS_OUTPUT.PUT_LINE('new p ' || new_pk); /*new is set correctly*/
DBMS_OUTPUT.PUT_LINE('new n ' || new_name); /*new is set correctly*/
DBMS_OUTPUT.PUT_LINE('TEST END');
END;
/
/*test the log*/
update MAT_VIEW_TEST set name = 'Test' where pk = 1;
commit;
Any ideas what was changed in Oracle or what we could do to get the old values in our trigger?
I don't have a 12c to rerun your tests, but I did on a 21c, and with the trigger you show, the old values are never shown, neither on insert (normal) nor on update( which is what you're complaining about). When I changed the trigger to be 'on insert or update or delete', and reran an update, I can see the old values. So, the refresh process is converting your UPDATE to DELETE/INSERT, hence the old values when it is deleting the old row.

Sql server scope identity with return id save and update

I am saving a photo to another table when saving the form. everything works very well. but the update does not work when updating, so the error is "can not be cast from dbnull to other types"
I wrote the problem I was researching for days, and after 5 minutes, something came to my mind and my problem was resolved. friends who will have the same problem use this rationale
Declare #NMID int
if exists(Select 1 from Musteriler where MID=#MID)
BEGIN
Update Musteriler Set MusteriKategori=#MusteriKategori, AdiSoyadi = #AdiSoyadi, TelefonNo=#TelefonNo, Eposta=#Eposta, Memleketi=#Memleketi, Meslegi=#Meslegi, Adres=#Adres, MusteriHakkindaNot=#MusteriHakkindaNot, Maker=#Maker, Updated=GETDATE()
where MID=#MID
Select #NMID=#MID
END
ELSE
BEGIN
Insert Into Musteriler(MusteriKategori, AdiSoyadi, TelefonNo, Eposta, Memleketi, Meslegi, Adres, MusteriHakkindaNot, Maker, Updated) values (#MusteriKategori, #AdiSoyadi, #TelefonNo, #Eposta, #Memleketi, #Meslegi, #Adres, #MusteriHakkindaNot, #Maker, GETDATE())
SELECT #NMID=SCOPE_IDENTITY();
END
SELECT #NMID
END

SqlDataAdapter taking too long to Fill VB.NET SQL Server 2012

I'm working on a winform application and I'm using a table named [File] in my SQL Server database.
I have a form that views some of "[File]" fields fID and fName in a combobox named SearchName. fID for Value and fName for Display.
SearchName Combobox is bound to dataset with dataadapter filling table with fID, fName, fPhoneNumber, fBalance, so I can use fName and fID.
I have also textboxes to add new "File" data like : fName, fAge, fNationality,fSex with a Save button with another combobox showing something called "Source".
When User clicks Save the data is saved to table [File] In DB and the adapter is filled again.
The dataset tableadapter was using a stored procedure as the following:
create proc [dbo].[ReadFileData](#fid int,#filter varchar(20))
as
begin
declare #f varchar(20)=#filter;
declare #id int =#fid;
if(#id=-1)
begin
if(#f='All')
select fID,fName,fPhoneNumbers,fBalance from [File]
else
if(#f='Blocked')
select fID,fName,fNotes,fBalance,fBlockDate,uFullName
from [File],[User] where fBlocked='True' and fBlocker=[uID]
order by fBlockDate desc
else
if(#f='nonBlocked')
select fID,fName,fPhoneNumbers,fBalance from [File] where fBlocked='False'
else
if(#f='notReady')
select fID,fName,fPhoneNumbers,fBalance from [File] where fAllTestsOK='False' and fBlocked='False'
else
if(#f='Ready')
select fID,fName,fPhoneNumbers,fBalance from [File] where fAllTestsOK='True' and fBlocked='False'
else
if(#f='NegBalanced')
select fID,fName,fPhoneNumbers,fBalance from [File] where fBalance<0
end
else
select f.fID,fName,fSex,fBirthDate,fPhoneNumbers,fAddress,fNationality,fNotes,fBalance,fBlocked,(select uFullName from [User] where uid=f.fBlocker) as fBlocker,
fLastEdited,(select uFullName from [User] where [uID]=f.fEditor) as fEditor, fBlockDate from [File] f where fID=#fid
end
It was taking too much time to save and fill the combobox again. I searched over the internet and I found out the problem is called "Patamter Sniffing/spoofing", because my procedure was selecting fields based on the values of the parameter it receives. I tried different ways to solve it, but nothing worked out for me. (P.S. I am using the same SP on other forms and data is filled immediately with no problems).
I deleted the whole dataset and created a new one with a new dataadapter using new Stored Procedure, this:
create proc [dbo].[GetAllFiles]
as
begin
select fID,fName,fPhoneNumbers,fBalance from [File]
end
Now first time the save and fill is done in no time, but after that it takes like 10+ seconds to fill.
I want to know what can I do to continue using the dataadapter to fill the combobox and solve time consuming problem?
If you have any suspicions that might cause these kind of problems, please let me know.
What other code parts or even design pictures can I provide to make my problem clearer?
Thanks to #Plutonix. He wrote it in a reply, just to make it clearer.
"You should spend a few hours on MSDN. You do not need to requery/refill/rebuild a datatable when you add rows; they can be refreshed. – Plutonix"
I used DataAdapterName.Adapter.Update(DatasetName) in save button and other update places. And kept fill only in page load event.

Add Multiple IDs in a Transaction to a LinkSet in Orientdb

I'm trying to add IDs from a inserted column to another inserted column in a Transaction. I tried like this:
begin
let doorOne = INSERT INTO doors SET color = green
let doorTwo = INSERT INTO doors SET color = blue
let car = INSERT INTO Cars SET doors = [$doorOne , $doorTwo]
commit retry 100
return $car
I get:
Unhandled rejection OrientDB.RequestError: The field 'Cars.doors' has been declared as LINKSET but the value is not a record or a record-id
I also tried to update it afterwards in the Transaction, but this won't work either (i think because the car is not created yet, so nothing to update) and i dont want to do it in two different calls, if there is a way to do it in one Transaction.
This is because INSERT returns, by default, the number of inserted entries. Try adding this clause at the end of each INSERT statement: RETURN #rid

Database Update Trigger to prevent removing specific characters at the end of the word

I'd like to have an Update Trigger that will let user update first part of the name but will will prevent the last part from being removed.
For example I have a column Srt_Name with CAR_GID23232 entry.
User should not have possibility to remove '_GID23232' part.
Here's what I came to, but it doesn't work:
IF EXISTS (
SELECT Srt_Name,Srt_Id
FROM inserted
WHERE Srt_Name not like '%_GID'+CONVERT(varchar(max),Srt_GidNumer)
)
BEGIN
RAISERROR ('Make sure that name ends with _GIDXXXX pattern.', 16, 1)
END
Try this one :
IF EXISTS (
SELECT Srt_Name,Srt_Id
FROM inserted
WHERE Srt_Name not like '%[_]GID'+CONVERT(varchar(max),Srt_GidNumer
)

Resources