Please be aware that the content in SAP SQL Anywhere Forum will be migrated to the SAP Community in June and this forum will be retired.

How can I change the user within a procedure?

I have a trigger t1 on a table T1, and I want to deactivate this trigger for all the transactions coming from a specific procedure1:

create "proc_user"."procedure1"()
begin
   insert into T1 values (value1, value2)
end;

create trigger t1 after insert on T1
....
if user_name() <> 'proc_user' then
    --real trigger here
end if;
end;

Now if I cam connected to the DB as DBA and I call the procedure:

call "proc_user"."procedure1"();

Then the trigger will be fired!!

I am also not able to write setuser proc_user within the procedure, so what could be the solution, to let a trigger ignore all inserts coming from a specific procedure?

Thanks in advance

asked 23 Sep '19, 07:04

Baron's gravatar image

Baron
2.1k136149177
accept rate: 48%

edited 23 Sep '19, 07:52

Volker%20Barth's gravatar image

Volker Barth
40.2k361550822


The best solution (for my case) was to create an event in the name of proc_user, and then call the procedure1 from within this event.

Now, once I want to call the procedure1 I have to trigger the event (and the event in turns will open a new connection in the name of proc_user, and call the procedure1 in the name of proc_user).

Here the trigger can recognize that the transaction is coming from this user (proc_user).

Thanks you all for your hints.

permanent link

answered 24 Sep '19, 08:21

Baron's gravatar image

Baron
2.1k136149177
accept rate: 48%

converted 27 Sep '19, 03:33

Have a look at the procedure's SQL SECURITY clause. If you specify SQL SECURITY INVOKER, user_name() will return the user calling the procedure instead of the procedure's owner which will be returned when the default SQL SECURITY DEFINER is used.

Note that if you use INVOKER you should qualify all database objects within the procedure's body and also within procedures/triggers that are called from there. Also note that when your "procedure1" is called from an outer procedure "procedure2" and that has the default SQL SECURITY DEFINER, the owner of "procedure2" will be the invoker of "procedure1".

v17 has added four new special values SESSION_USER, INVOKING_USER, EXECUTING_USER, and PROCEDURE OWNER which help to find out which is which...

permanent link

answered 23 Sep '19, 08:04

Volker%20Barth's gravatar image

Volker Barth
40.2k361550822
accept rate: 34%

And just to add:

Triggers execute with the privileges of the owner of the according table, not with that of the user whose actions cause the trigger to fire, so they run as "SQL SECURITY DEFINER" by design.

As a consequence, you can influence how procedures and functions behave based on their SQL SECURITY clause - but you cannot for triggers themselves.

(23 Sep '19, 08:07) Volker Barth
Replies hidden

Thank you for the reply. Is this available also in Sql Anywhere 10? I get syntax error when I type:

create "proc_user"."procedure1"()

SQL SECURITY DEFINER

Begin


End

(23 Sep '19, 09:08) Baron

No, according to the docs, it was introduced in V11...

For such retrieval, DCX is your friend, it contains the full doc sets from 10.0.1 up to 17...

(23 Sep '19, 09:32) Volker Barth

And is there any alternative for Sql Anywhere 10?

(23 Sep '19, 10:03) Baron

u-uh?! Yes, any other DB that exists in this world. E.g. Sql Anywhere 17 is a good alternative for SA10.

(23 Sep '19, 11:31) Vlad

Well, apparently you would need to "flag" the particular user in a different fashion, say by

  • using the user name from the current connection information (i.e. connection_property('UserID')), or
  • supplying an AppInfo value to the connection and distinguish based on that via e.g.connection_property('UserAppInfo')or
  • adding a field to your table with different values for that particular user and other users, or ...
(23 Sep '19, 12:04) Volker Barth
1

One option is to use a connection level variable i.e., CREATE VARIABLE _IsProcedure. It can be changed to 1 at the start of the procedure and set back to 0 at the end. The trigger can then process if _isProcedure <> 0 then...

(23 Sep '19, 14:43) Chris Keating
Replies hidden

But this does not exclude only transactions connections coming from the procedure! I think in this case all other parallel transactions on the table while the procedure is open will be also considered as trnasactions coming from the procedure (will be excluded in the trigger)!!

(24 Sep '19, 02:20) Baron

does connection_property('UserID') another value than user_name()?

Could you please tell me How I can assign a 'UserAppInfo' to a connection?

(24 Sep '19, 02:22) Baron

Chris's idea is to use a connection variable to influence whether the trigger does some action or not. You can create and modify such a connection variable anywhere in the course of the connection's livetime, i.e. you can create/set it during a login procedure, with some InitString setting, during some SQL code before you call the procedure or within the procedure itself. And the trigger itself could check whether the variable does exist (via the VAREXISTS function), and only if so and if it is set to a particular value, the trigger would ignore its usual action. I.e. for normal connections, you would not need to use that variable, just for your particular user.

Here's a sample with such a variable used to ignore the usual trigger action...

(24 Sep '19, 03:50) Volker Barth
showing 2 of 10 show all flat view
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×79
×34

question asked: 23 Sep '19, 07:04

question was seen: 1,019 times

last updated: 24 Sep '19, 08:21