Skip to Main Content
  • Questions
  • Why I can't use stored function in select list of select function.

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, aaa.

Asked: February 17, 2008 - 1:43 pm UTC

Last updated: March 15, 2008 - 9:49 am UTC

Version: 9.2.4

Viewed 1000+ times

You Asked

Hi tom,
Thanks for accepting my question.

my question is why we can't we perform dml operation in query?

thanks
gautam

and Tom said...

well, you can. (technically DML includes select, but you probably mean "dml that modifies things") even if the dml modifies stuff.

but - you probably don't want to.

why not? because modifications should be something deterministic, something you can count on, predicable.

and you have NO CONTROL WHATSOEVER AS TO HOW MANY TIMES WE CALL YOUR FUNCTION.

none, zippo, zero.


ops$tkyte%ORA10GR2> create table t ( id number, msg varchar2(4000) );

Table created.

ops$tkyte%ORA10GR2> create sequence s;

Sequence created.

ops$tkyte%ORA10GR2> create table data as select * from all_users;

Table created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> create or replace function f return number
  2  as
  3          pragma autonomous_transaction;
  4  begin
  5          insert into t values ( s.nextval, 'i was called ' );
  6          commit;
  7          return 42;
  8  end;
  9  /

Function created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> select * from data where user_id = f;

no rows selected

ops$tkyte%ORA10GR2> select min(id), max(id), count(*) from t;

   MIN(ID)    MAX(ID)   COUNT(*)
---------- ---------- ----------
         1         39         39


so, apparently, we call it once per row (there are 39 rows in my data table), or do we...


ops$tkyte%ORA10GR2> create index t_idx on data(user_id);

Index created.

ops$tkyte%ORA10GR2> select * from data where user_id = f;

no rows selected

ops$tkyte%ORA10GR2> select min(id), max(id), count(*) from t;

   MIN(ID)    MAX(ID)   COUNT(*)
---------- ---------- ----------
         1         41         41



ok, so maybe we call it 2 times per query? sometimes? when we feel like it?


ops$tkyte%ORA10GR2> select * from data where user_id = (select f from dual);

no rows selected

ops$tkyte%ORA10GR2> select min(id), max(id), count(*) from t;

   MIN(ID)    MAX(ID)   COUNT(*)
---------- ---------- ----------
         1         42         42



Oh, I see, depending on how the query plan is done, it only calls it once



You have NO CONTROL over how many times we invoke your function, none.

and a simple plan change will change how many times we do.
an upgrade to the next release might change it.
gathering statistics, adding an index might change it.


So, while you can do it, it is not very useful or practical...

Rating

  (9 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Clarify the question

Robert C, February 19, 2008 - 10:16 am UTC

....Hi tom,
Thanks for accepting my question.

my question is why we can't we perform dml operation in query?

thanks
gautam...

I presume this wasn't a trick question?

Insert into.. = Query
Select .. = Query
Update = Query
Delete .. = Query

Although I did find it rather difficult to understand the grammar in the question.


Tom Kyte
February 19, 2008 - 5:01 pm UTC

Yeah, I pointed out in my response it was a trick question:

well, you can. (technically DML includes select, but you probably mean "dml that modifies things") even if the dml modifies stuff.

OK

A reader, February 19, 2008 - 6:50 pm UTC

OK. I just found it rather amusing that you were able to write a reply which included some code samples in response to a question that didn't make sense at all.
Tom Kyte
February 20, 2008 - 8:16 am UTC

absolutely no idea what you mean by that at all.

Is SELECT a DML?

Michel Cadot, February 20, 2008 - 2:02 am UTC


Sometimes it is inside DML and sometimes not.
But it is often simpler or shorter to write "DML statements" for "DML and SELECT statements" or, if you assume the opposite, "DML statements" for "DML statements but SELECT".

Wikipedia ( http://en.wikipedia.org/wiki/Data_Manipulation_Language ) and Orafaq ( http://www.orafaq.com/faq/what_are_the_difference_between_ddl_dml_and_dcl_commands ) assumes SELECT is in DML (but it also includes LOCK TABLE).

For Oracle, SELECT is not inside DML defintion in glossary: http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/glossary.htm#sthref4150 but it is not said it is an exhaustive list.
And in the section "DML Locks Automatically Acquired for DML Statements" ( http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/consist.htm#sthref2102 ) it includes SELECT and LOCK TABLE.
SQL Reference in Data Manipulation Language (DML) Statements ( http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_1001.htm#sthref3216 ) includes SELECT and also EXPLAIN PLAN and CALL.

So no conclusion, I don't have ISO/ANSI standard by hand so can't verify if there is a definition of it inside.

Regards
Michel

Tom Kyte
February 20, 2008 - 8:25 am UTC

when you read something that says "includes statements like..." that means "I am not being entirely inclusive.

Oracle defines (as does ANSI) dml to include all data manipulation statements.

http://docs.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_1001.htm#i2099257

there is a list that says "I am inclusive"


Select is absolutely DML - there is DML, DDL and DCL - if select were not DML, and obviously isn't DDL or DCL - what would it be.

Yes

Robert, February 20, 2008 - 5:37 am UTC

OK. I would argue that DML includes any of the following:

SELECT
DELETE
INSERT
UPDATE

I would argue that a SELECT statement does indeed modify the data. The direction of the modification is just outwards, as opposed to inwards. We modify the contents of some set to produce a new set which meets the criteria specified in the definition of the SELECT statement. In the simplest example, this may involve the removal of two columns during the projection.

SELECT and Data Modification

SeánMacGC, February 20, 2008 - 8:36 am UTC

Would disagree entirely that SELECT modifies data.

Modification is the (persistent) changing of data within the database.

SELECT is DM(anipulation)L perhaps, but never modification.

New DQL for SELECT?

Sarma, February 25, 2008 - 1:58 am UTC

<quote>- if select were not DML, and obviously isn't DDL or DCL - what would it be. <unquote>

Data Query Language - DQL?

I've seen many of the newbies to database add this new set DQL to the RDBMS set, wrong though.

How about we authenticating and defining this new set Tom?


Tom Kyte
February 25, 2008 - 2:26 am UTC

there are only DML, DCL and DDL

DQL is something made up, it doesn't exist when talking about SQL.

Who is correct?

Karthick Pattabiraman, March 13, 2008 - 5:03 am UTC

Tom Kyte
March 13, 2008 - 8:47 am UTC

neither - TCL is somewhat made up, but orafaq is closer than close enough to correct.


why we can't we perform dml operation in query?

krishna, March 13, 2008 - 12:49 pm UTC

Hi,

I have a question? How can we access a remote function in select statement?

I tried in the following way it given the "right parenthesis missing"

select test@prd.cardnum('12345'), card_exp_dt from card_exp;

Thanks,
Krishna
Tom Kyte
March 15, 2008 - 8:53 am UTC

looks like a *packaged* function maybe? (you are making me guess at LOTS of stuff here, what is test, what is prd, what is cardnum??)

ops$tkyte%ORA10GR2> create database link remote connect to ops$tkyte identified by foobar using 'ora10gr2';

Database link created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> create or replace function f(x in number) return number
  2  as
  3  begin
  4          return 42;
  5  end;
  6  /

Function created.

ops$tkyte%ORA10GR2> create or replace package my_pkg
  2  as
  3  function f (x in number) return number;
  4  end;
  5  /

Package created.

ops$tkyte%ORA10GR2> create or replace package body my_pkg
  2  as
  3  function f (x in number) return number
  4  is
  5  begin
  6          return 42;
  7  end;
  8
  9  end;
 10  /

Package body created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> select f(1), f@remote(1) from dual;

      F(1) F@REMOTE(1)
---------- -----------
        42          42

ops$tkyte%ORA10GR2> select my_pkg.f(1), my_pkg.f@remote(1) from dual;

MY_PKG.F(1) MY_PKG.F@REMOTE(1)
----------- ------------------
         42                 42

To : Krishna

A reader, March 14, 2008 - 12:42 pm UTC

Syntax looks ok to me. Test this

1. select * from dual@prd.cardnum

2. Login to the schema where the db-link is pointing and run
select test('12345') from dual;



Tom Kyte
March 15, 2008 - 9:49 am UTC

well, we do not know what is what here...

is this a standalone function
a packaged function
what is the dblink

more questions than answers :)

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library