I have made cursor which updates table values by using provided Oracle API. My question is how can I see which tables are affected? I would like to revert change in case that I need to so I would like to preserve those data first. Our Oracle database is version 12.1.0.2.
If trace can manage this how exactly can i do that? I tried with trace before but is pretty much unreadable to me :)
Thank you
This is not answer, I cannot reply on comment. Yes this is API block code which I have used, my apologies for not being detailed previously:
declare
--cursor to get all inactive users
cursor cur_inactive_user
is
select fu.user_id,
fd.responsibility_id,
fd.responsibility_application_id,
fd.security_group_id,
fd.start_date,
fu.end_date
from fnd_user fu, fnd_user_resp_groups_direct fd
where fu.user_id = fd.user_id
and (fu.end_date < sysdate or fu.end_date is not null)
and fd.end_date is null;
--and fu.user_name='HFORD';
begin
for rec_inactive_user in cur_inactive_user
loop
-- checking if the responsibillity is assigned to the user
if (fnd_user_resp_groups_api.assignment_exists (
rec_inactive_user.user_id,
rec_inactive_user.responsibility_id,
rec_inactive_user.responsibility_application_id,
rec_inactive_user.security_group_id))
then
-- Call API to End date the responsibillity
fnd_user_resp_groups_api.update_assignment (
user_id => rec_inactive_user.user_id,
responsibility_id => rec_inactive_user.responsibility_id,
responsibility_application_id => rec_inactive_user.responsibility_application_id,
security_group_id => rec_inactive_user.security_group_id,
start_date => rec_inactive_user.start_date,
end_date => rec_inactive_user.end_date,
description => null );
--commit;
end if;
end loop;
end;
Related
we're just migrating from mariadb (galera) to MSSQL.
One of our applications has a very special behaviour - from time to time (I have not found a pattern, the vendor uses very fancy AI-related stuff which noone can debug :-/) it will block the monitor-user of our loadbalancers because of too many connects, so the loadbalancer is no longer able to get the health state, suspends all services on all servers and the whole service is going down.
So I wrote a trigger which enables this user after he will be disabled.
I've already thought about a constraint which prohibits this, but then the application goes nuts if it will disable the user.
Anyway - in mysql this works perfectly for us:
delimiter $$
CREATE TRIGGER f5mon_no_disable AFTER UPDATE ON dpa_web_user
FOR EACH ROW
BEGIN
IF NEW.user_id = '99999999' AND NEW.enabled = 0 THEN
UPDATE dpa_web_user SET enabled = 1 WHERE user_id = '9999999';
END IF;
END$$
delimiter ;
I tried this in T-SQL (if it's important, it is MSSQL 2016)
CREATE TRIGGER f5mon_no_disable ON [dbo].[dpa_web_user]
AFTER UPDATE
AS
BEGIN
IF ( inserted.[user_id] = '9999999' AND inserted.[enabled] = 0 )
BEGIN
UPDATE dpa_web_user SET enabled = 1 WHERE user_id = '9999999';
END
END
I think it's the if-statement which is totally wrong in more than one way - but I do not have an idea how the syntax is in t-sql.
Thanks in advance for your help.
You can use IF EXISTS but you can't reference column values in inserted without set-based access to inserted:
IF EXISTS (SELECT 1 FROM inserted WHERE [user_id] = '9999999' AND [enabled] = 0)
BEGIN
UPDATE dpa_web_user SET enabled = 1 WHERE user_id = '9999999';
END
You may want to add AND enabled <> 1 to prevent updating a row for no reason.
You can do this in a single statement though:
UPDATE u
SET enabled = 1
FROM dbo.dpa_web_user AS u
INNER JOIN inserted AS i
ON u.[user_id] = i.[user_id]
WHERE u.[user_id] = '9999999'
AND i.[user_id] = '9999999'
AND u.enabled <> 1
AND i.enabled = 0;
I am developing an application using Laravel 5.5 and SQLServer. I was asked to create a 'History' table, in which we keep track of UPDATE actions. For example, if we update the description of a ticket, we insert the id, the field, the previous value and the new value of that field.
Usually, this is done with Triggers in the Database, so I have set up an after_update trigger.
Now, my trigger works, but not when the queries are written with Eloquent. If I use the PDO object of the same connection used by my Models, the triggers work. If I write a query in the Database interface, using the same connection, they work. But if I write the same query with Eloquent, the field is updated, but the triggers do not fire.
I am aware that Observers exist to act like triggers, and I did set them up to do pretty much the same thing. But, I don't understand why the triggers do not work, and i wonder if it is a normal behavior or if my set up is faulty in some way.
My connection in the database.php file looks like this (with default values i removed here) :
'uti' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'prefix' => '',
'charset' => 'iso-8859-1',
'characterset' => 'iso-8859-1',
'collation' => 'French_CI_AS',
],
The code with which the trigger works :
use Illuminate\Support\Facades\DB;
$oPdo = DB::connection('uti')->getPdo();
$sQuery = $oPdo->prepare("
UPDATE TICKET SET
T_DESC = :sDesc
WHERE T_CODE = :iCode");
$sQuery->execute([':sDesc' => $sDesc, ':iCode' => $code]);
The code with which it does not work :
$oTicket = Ticket::find($code);
$oTicket->T_DESC = $sDesc;
$oTicket->save();
The trigger is something like this (with more 'IF UPDATE()' for each field of the table TICKET):
USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[after_update_ticket]
ON [dbo].[TICKET]
AFTER UPDATE
AS
BEGIN -- begin trigger
SET NOCOUNT ON
IF EXISTS (SELECT * FROM INSERTED) And EXISTS(SELECT * FROM DELETED)
-- Is an update --
BEGIN -- begin if update
DECLARE #user int = 1;
IF NOT UPDATE (MODIFICATION_DATE) AND NOT UPDATE (MODIFICATION_USER)
BEGIN -- begin if not update
-- If database connection user is letter + number, user id = number
IF (ISNUMERIC(SUBSTRING(USER_NAME(USER_ID (CURRENT_USER)),2, LEN(USER_NAME(USER_ID (CURRENT_USER)))))=1)
BEGIN
SET #user = SUBSTRING(USER_NAME(USER_ID (CURRENT_USER)),2, LEN(USER_NAME(USER_ID (CURRENT_USER))));
END
-- Update MODIFICATION date and user --
UPDATE [TICKET] SET
MODIFICATION_DATE = CURRENT_TIMESTAMP,
MODIFICATION_USER = #user
WHERE CODE = (SELECT T_CODE FROM inserted)
-- History trigger --
IF UPDATE(T_DESC)
BEGIN
INSERT INTO HISTORIQUE
(H_DATE,H_TABLE,H_FIELD,H_BEFORE,H_AFTER,H_CODE,CREATION_USER,CREATION_DATE)
VALUES
(CURRENT_TIMESTAMP,'TICKET','T_DESC',(SELECT T_DESC FROM deleted),(SELECT T_DESC FROM inserted),(SELECT T_CODE FROM inserted),#user,CURRENT_TIMESTAMP)
END
END -- end if no update
END -- end if update
END -- end trigger
I have tried researching triggers, laravel and eloquent, but looking at the docs and several stackoverflow questions did not provide me with information about the expected behavior of Triggers with Eloquent. I found that some people created them manually with migrations, so I am supposing they are supposed to work, but I could not find information to help me.
Thank you.
UPDATE
Eloquent handles the automatic updating method on the created_at and updated_at at the same time as the update on the field. (here, updated_at defined as MODIFICATION_DATE). As a result, only one query is sent to the database :
update [TICKET] set [T_DESC] = 'desc with eloquent', [MODIFICATION_DATE] = '2019-05-02 08:45:53' where [T_CODE] = 16770
Because of my IF NOT UPDATE (MODIFICATION_DATE) statement in the trigger, this blocked it from getting fired.
I set public $timestamps = false; in my Ticket model, so that Laravel's automatic update on the updated_at does not happen, and the trigger fires as usual.
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
I have a table where data does not initially exist until an action is taken that stores all settings made by client in one-go. To illustrate this simply, a button click that stores all column values off a (HTML) table into a database table (let's call this dbo.Settings).
So instead of inserting into this dbo.Settings all the default values prior to user making any changes to their individual settings (ever), I kind of created the pseudo data for them that will be returned whenever requested, kind of like SELECT-ing the default values:
SELECT
CanView = ISNULL(CanView, 1),
CanRead = ISNULL(CanRead, 1),
CanWrite = ISNULL(CanWrite, 0)
FROM
dbo.Settings AS s
WHERE
UserId = #id
Rather than doing:
IF NOT EXISTS(SELECT * FROM dbo.Settings WHERE UserId = #id)
BEGIN
INSERT INTO dbo.Settings (UserId, CanView, CanRead, CanWrite)
VALUES (#id, 1, 1, 0)
END
The problem with this is whenever I need to add a new setting column in the future, I now have to note one more procedure to modify/add the default value for this column as well -- which I don't like. Using TRIGGER would be an option but I wonder what the best practice in managing data like this would be. Or would you do something like this:
CREATE PROC Settings_CreateOrModify
#userId INT,
#canView BIT = NULL,
#canRead BIT = NULL,
#canWrite BIT = NULL
AS
BEGIN
IF EXISTS(SELECT * FROM dbo.Settings WHERE UserId = #userId) BEGIN
UPDATE s
SET
CanView = #canView,
CanRead = #canRead,
CanWrite = #canWrite
FROM
dbo.Settings AS s
WHERE
s.UserId = #userId AND
(#canView IS NULL OR #canView <> s.CanView) AND
(#canRead IS NULL OR #canRead <> s.CanRead) AND
(#canWrite IS NULL OR #canWrite <> s.CanWrite)
END
ELSE BEGIN
INSERT INTO
dbo.Settings(UserId, CanView, CanRead, CanWrite)
SELECT
#userId, #canView, #canRead, #canWrite
END
END
How would you handle data structure like this? Any recommendation or correction would be greatly appreciated. Thanks in advance!
Your SP is a good way to go, and doing it like this is commonly called an "UPSERT".
It also looks to me as if the block:
(#canView IS NULL OR #canView <> s.CanView) AND
(#canRead IS NULL OR #canRead <> s.CanRead) AND
(#canWrite IS NULL OR #canWrite <> s.CanWrite)
is problematic since it causes the UPDATE to run only if ALL parameters changed their value. I don't think that's what you wanted to say. Just SET the three values regardless of what's already there.
You still end up with three places to change when you add a new setting: The Table, the Upsert and the Defaults.
One very different approach is this:
Apply the defaults to the columns in the table definition.
Whenever you need the values for a new user, do: INSERT INTO dbo.Settings(UserId) The defaults will fill the rest of the columns.
Now you can retrieve the values for ALL users (new or not) in the same way from the table.
Since you already inserted the user in step 2, you know the userid is there already and you can always save the changes via a simple update.
This eliminates the SP and the need of providing the defaults in one extra place.
I have to implement a trigger which would:
7) Show the DDL for how a trigger can be used to transfer all rental copies from a store being deleted from the Store information table to the central store
8) Show how this trigger can be extended to make
sure that the central store is never deleted from the database
So far I have done this:
CREATE OR REPLACE TRIGGER stores BEFORE DELETE ON stores FOR
EACH ROW BEGIN IF DELETING WHERE cvr = 123456789 THEN
Raise_Application_Error ( num => -20050, msg => 'You can
not delete Main Store.'); END IF; IF DELETING THEN
UPDATE store_id=123456789 ON movies WHERE isActive = 0 END
IF; END;
so main store is with cvr which is written, but it gives me a compilation error. Any help? Thanks in advance.
You have two errors in your code.
there is no "DELETING WHERE" expression, you have to use two boolean exceptions like this:
IF DELETING AND :old.cvr = 123456789 THEN...
:old.cvr refers to value of cvr column in deleted record
Syntax of UPDATE clause is
UPDATE table_name
SET column_name1 = value1,
column_name1 = value2
WHERE where_clause;
in your case probably somethink like this:
UPDATE movies
set store_id = 123456789
WHERE store_id = :old.cvr
I guess, I don't know required functionality