I have a table which has undesired characters(Ý) and I want to replace it with "I". Before I have tried that code for another column name and it worked perfect. But now while debuging I can see it fixes the rows but at the end db has no change... This is my code below:
DECLARE #CARI_NAME varchar(100)
DECLARE CRS_FixCariNameCURSOR FOR
SELECT CARI_NAME FROM TBLCASABIT
OPEN CRS_CariIsimDuzelt
FETCH NEXT FROM CRS_FixCariNameINTO #CARI_NAME
WHILE ##FETCH_STATUS=0
BEGIN
IF #CARI_NAME LIKE '%Ý%'
UPDATE TBLCASABIT SET #CARI_NAME = REPLACE(#CARI_NAME ,'Ý','I')
WHERE CURRENT OF CRS_FixCariName
FETCH NEXT FROM CRS_FixCariNameINTO #CARI_NAME
END
CLOSE CRS_FixCariName
DEALLOCATE CRS_FixCariName
with UPDATE TBLCASABIT SET #CARI_NAME = REPLACE(#CARI_NAME ,'Ý','I')
you update the variable and not the column!
use:
UPDATE TBLCASABIT SET CARI_NAME = REPLACE(#CARI_NAME ,'Ý','I')
if the column you want to update is called CARI_NAME
But what's more - Why do you even use a cursor here?
Simple Update does the same work more efficient (correct me if i am wrong):
UPDATE TBLCASABIT
SET CARI_NAME = REPLACE(CARI_NAME ,'Ý','I')
WHERE CARI_NAME LIKE '%Ý%'
Related
Is it possible to make such a trigger that runs when you try to delete a row and prints something like this: "Attempting to delete row ROW_ID", instead of actually deleting the row?
UPD: Thanks. Worked for me:
GO
CREATE OR ALTER TRIGGER Trigger_2 ON Authors
INSTEAD OF DELETE
AS BEGIN
DECLARE #deleted_id INT;
DECLARE cursor_deleted CURSOR
FOR SELECT au_id FROM deleted;
OPEN cursor_deleted;
FETCH NEXT FROM cursor_deleted INTO #deleted_id;
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT('Attempting to delete author ' + STR(#deleted_id));
FETCH NEXT FROM cursor_deleted INTO #deleted_id;
END;
CLOSE cursor_deleted;
DEALLOCATE cursor_deleted;
END;
GO
DELETE FROM Authors WHERE au_id BETWEEN 1 AND 10;
Yeah it is, and there are many approaches.
using a trigger you can either set the trigger to run after a deletion and u will have to use "ROLLBACK" to undo the deletion operation.
or just simply use INSTEAD OF where as the name suggests the trigger will replace the who deletion operation.
hope this helps in any way.
ps: after a deletion operation deleted data are stored in a Global table named "deleted" use to get any data or metaData that u need.
CREATE TRIGGER schema_name.trigger_name
ON table_name
// this trigger is executed instead of any deletion
INSTEAD OF DELETE
AS
BEGIN
// return the one to be deleted's id.
return deleted.id
END
First I know that using a cursor is not the best way of doing this but the IT manager is an old SQL person and that is the way he wants it done, otherwise I wouldn't be doing it this way.
I am using a stored procedure that does among other things create a temp table and try to fill it with data from another table that has been concatenated in the stored procedure. I can not seem to get the problem description, the field that needs to be concatenated, to update correctly. Actually not all.
Here is the part of the stored procedure that builds the temp table and tries to update it.
--Build problem entry
Create Table ##tmp_problem
(
prbqarnum varchar(7),
prbdesc varchar(max)
)
--Dump problem(s) into tbl based on qar#
Insert Into ##tmp_problem(prbqarnum) Select qarnum From tbl_qarbase Where currstatus = #qarstatus
--Declare tbl cursor
Declare tbl_Cursor CURSOR For
Select tbl_problems.qarnum, tbl_problems.problemdesc
From tbl_problems
Join tbl_qarbase On tbl_problems.qarnum = tbl_qarbase.qarnum
Where tbl_qarbase.currstatus = #qarstatus
--Open the tbl cursor
Open tbl_Cursor
--Fetch first row of data
Fetch next From tbl_Cursor Into #qarparm, #desc
--Declare temp problem desc variable
Declare #tmpproblem varchar(max)
--Loop to get problem data
While ##FETCH_STATUS = 0
Begin
Set #tmpproblem = (Select prbdesc From ##tmp_problem Where prbqarnum = #qarparm) + ' ' + #desc
Update ##tmp_problem Set prbdesc = #tmpproblem
--Get Next Row of Data
Fetch next From tbl_Cursor Into #qarparm, #desc
End
--Close tbl cursor
Close tbl_Cursor
--Deallocate tbl cursor
Deallocate tbl_Cursor
I know that the temp table is working because after the procedure runs i am able to query the temp table and see that the qarnum's are being put in.
What isn't happening is that there is a description field, that may have anywhere from one to N lines, and based on the qar # I need to concatenate the descriptions into one string and then insert it into the temp table, which isn't happening.
Here is a picture on the queries out puts. The top is the temp table and the bottom is the table that the cursor is built on.
So the question is, besides using a cursor, what i am doing wrong?? I have been Googling for several hours but nothing seems to work.
One last note: I am not seeing any errors anywhere.
You could GREATLY simplify this. There is no need for an update at all. Just populate both columns in your temp table. You entire code could be reduced to this.
Create Table #tmp_problem
(
prbqarnum varchar(7),
prbdesc varchar(max)
)
--Dump problem(s) into tbl based on qar#
Insert Into #tmp_problem(prbqarnum, prbdesc) Select qarnum, problemdesc From tbl_qarbase Where currstatus = #qarstatus
You should handle NULLs:
Set #tmpproblem = ISNULL(Select prbdesc From ##tmp_problem
Where prbqarnum = #qarparm), '') + ' '
+ ISNULL(#desc, '');
Plus you need to add some condition to UPDATE
Update ##tmp_problem Set prbdesc = #tmpproblem -- updates entire table
--WHERE ...
For a homework assignment, I'm trying to build a trigger that allows for multiple inserts/updates/deletes by utilizing a cursor. We have to use a cursor in order to practice the syntax. We know that there are very few practical scenarios for cursors in a production environment.
Here's what I'm trying to accomplish:
For each row inserted into the TAL_ORDER_LINE table, update the ON_HAND value in the TAL_ITEM table by subtracting the NUM_ORDERED value from the stored ON_HAND value.
Table Structure:
Current Query:
ALTER TRIGGER update_on_hand
ON TAL_ORDER_LINE
AFTER INSERT AS
DECLARE #vItemNum as char
DECLARE #vNumOrdered as int
DECLARE new_order CURSOR FOR
SELECT ITEM_NUM, NUM_ORDERED
FROM inserted
OPEN new_order;
FETCH NEXT FROM new_order INTO #vItemNum, #vNumOrdered;
WHILE ##FETCH_STATUS=0
BEGIN
UPDATE TAL_ITEM
SET ON_HAND = ON_HAND - #vNumOrdered
WHERE ITEM_NUM = #vItemNum
FETCH NEXT FROM new_order INTO #vItemNum, #vNumOrdered;
END
CLOSE new_order
DEALLOCATE new_order
My Insert Query:
INSERT INTO TAL_ORDER_LINE (ORDER_NUM, ITEM_NUM, NUM_ORDERED, QUOTED_PRICE)
VALUES (51626, 'KL78', 10, 10.95), (51626, 'DR67', 10, 29.95)
It runs successfully, but does not affect the ON_HAND value. I think the biggest problem is that I'm struggling to understand cursor syntax, especially the INTO clause in the FETCH statement and how data from the 'inserted' table is passed into the cursor. What do I need to know to get this to work? Thanks in advance!
Your problem is likely due to this:
DECLARE #vItemNum as char
it is HIGHLY unlikely that the ItemNum column is a single character. For future reference, you should always verify that you variable definitions are consistent with the values you expect to store in them. And as has been hinted - you will get better answers by posting a complete script rather than a picture.
Big question,how you gonna debug ?
Is On_Hand col NULL , then do this isnull(on_Hand,0)
DECLARE #vItemNum as char
DECLARE #vNumOrdered as int
DECLARE new_order CURSOR FOR
SELECT ITEM_NUM, NUM_ORDERED
FROM TAL_ORDER_LINE
OPEN new_order;
FETCH NEXT FROM new_order INTO #vItemNum, #vNumOrdered;
WHILE ##FETCH_STATUS=0
BEGIN
--UPDATE TAL_ITEM
--SET ON_HAND = ON_HAND - #vNumOrdered
--WHERE ITEM_NUM = #vItemNum
print #vItemNum
print vNumOrdered
FETCH NEXT FROM new_order INTO #vItemNum, #vNumOrdered;
END
CLOSE new_order
DEALLOCATE new_order
Try this :
ALTER TRIGGER update_on_hand ON TAL_ORDER_LINE
FOR INSERT AS
BEGIN
UPDATE TI
SET TI.ON_HAND = TI.ON_HAND - I.NUM_ORDERED
TAL_ITEM TI INNER JOIN
INSERTED I ON I.ITEM_NUM = TI.ITEM_NUM
END
Changed Trigger to FOR INSERT Trigger
Removed Cursor
Note: NOT Tested. ( If you post the sql scripts for create table + sample inserts I can give it a try )
Here is my trigger
Create TRIGGER [dbo].[tri_before_update]
ON [dbo].[test]
instead of update
AS
BEGIN
SET NOCOUNT ON;
if update (test_a)
begin
*.. my update & insert query*
end
END
create TRIGGER [dbo].[tri_before_update_price]
ON [dbo].[co_ticket]
instead of update
AS
BEGIN
SET NOCOUNT ON;
if update (t_price)
begin
insert into old_price_log (t_id,insert_time,process_id,old_t_price)
select i.t_id,getdate(),2,t_price
from Inserted i,co_ticket t where i.t_id = t.t_id
update t set t_price = i.t_price
from co_ticket t, inserted i
where t.t_id = i.t_id
end
else
begin
-- if update other then (t_price) then the update comand not execute.
-- example when i update t_cancel_flag or t_quantity and etc. end
END
This trigger execute perfectly when i update on column "test_a". HOWEVER, when i update other than column "test_a" it won't be execute. I know i can put "else" command, but i got a lot of column. sometimes will update two other column , sometimes three or four column. I don't wish to update all column everytime. Is it possible ELSE "then execute original query"?
I tried a lot different way but still can't work. :( Please HELP!
create TRIGGER [dbo].[tri_on_update_price]
ON [dbo].[co_ticket]
AS
BEGIN
SET NOCOUNT ON;
if update (t_price)
begin
insert into old_price_log (t_id,insert_time,process_id,old_t_price)
select d.t_id, getutcdate(),2,d.price
from deleted d
END
end
An ordinary after trigger will do just what you want: insert a log of the price change, if the price was updated. No need for INSTEAD OF. You need to look into the deleted pseudo-table to get the old price. Never store local times in a database.
I currently working with an old application that I don't own any source code but I really need to add some new logic to the app.
The only way I found to do it is to mess up with database data, and change whatever I need with a trigger.
I wrote the following trigger that should update 2 columns of a just inserted row:
CREATE TRIGGER addLoteInfo ON fi
FOR INSERT
AS
DECLARE
#loteN varchar(15),
#refN varchar(18),
#CientifN varchar(40),
#CaptureZ varchar(20)
declare MY_CURSOR cursor for
select
i.lote, i.ref
from inserted i
open MY_CURSOR
fetch next from MY_CURSORinto #loteN, #refN
while ##fetch_status = 0
begin
SELECT #CientifN = u_ncientif FROM SE where lote LIKE #loteN and ref LIKE #refN;
SELECT #CaptureZ = u_zcaptura FROM SE where lote LIKE #loteN and ref LIKE #refN;
UPDATE FI SET LNCIENT=#CientifN, LZCAP=#CaptureZ;
fetch next from CURSOR_TESTE into #loteN, #refN
end
close MY_CURSOR
deallocate MY_CURSOR
The problem is when a new registry is inserted, it seems it gets to a deadlock.
Its impossible to do what I'm trying to do?
Can you help me with another approach?
You need to use INSTEAD OF trigger if you want to modify newly inserted/updated record on the fly.