简体   繁体   中英

Call a stored procedure from within a view

I have a procedure that creates a table, is it possible to have a view (or similar) that can call the procedure then select from the table?

I've tried this:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` FUNCTION `new_routine`(p1 INT) RETURNS int(1)
BEGIN
    CALL rMergeDateFields();
    RETURN 1;
END


CREATE VIEW `db`.`vIntervals` AS
  SELECT new_routine(0) AS col1;
  SELECT * FROM MergedData;

but I get this error

Error 1422: Explicit or implicit commit is not allowed in stored function or trigger.

Any ideas?

No, you cannot. Views are typically read-only operations; and that behavior cannot be guaranteed if stored-procedures are invoked.

Related question:

How to call Stored Procedure in a View?

Is it possible to call stored procedure in view?

Here is a canonical resource:

http://dev.mysql.com/doc/refman/5.1/en/view-updatability.html

Some views are updatable. That is, you can use them in statements such as UPDATE, DELETE, or INSERT to update the contents of the underlying table. For a view to be updatable, there must be a one-to-one relationship between the rows in the view and the rows in the underlying table. There are also certain other constructs that make a view nonupdatable.

As invoking the stored procedure cannot assure 1:1 relationships with view rows, the update is not permitted.

The question asks about calling a stored procedure in a view.

But the code in the question is attempting to create a view from within a user-defined function.

Those are two very different things.

The CREATE VIEW statement is allowed in a PROCEDURE, but is prohibited in a FUNCTION.

The error message actually gives an indication of why this is.

A DDL operation (as opposed to a DML operation) performs a COMMIT, and that operation is not allowed in a user-defined function.

DML (Data Manipulation Language) statements operate on rows . These include INSERT, UPDATE, DELETE, REPLACE.

DDL (Data Definition Language) statements operate on the definition of the data, such as adding a column, creating a table, dropping an index, etc.

By design, all DDL statements perform an implicit COMMIT. Any changes made my DML statements that are not yet committed will be finalized, and the current transaction will be ended.

The design issue with a user-defined function is that it can be used in a DML statement...

UPDATE mytable SET mycolumn = my_user_defined_function()

As the rows in my table, the functions "my_user_defined_function" will be executed. The UPDATE statement is atomic, either all of the changes it makes will be applied, or none of them. Issuing a COMMIT (from inside the function) while the UPDATE statement is executing would effectively "break" the DML operation.

The same restriction applies to a TRIGGER, for the same reason. A trigger can be fired by the operation of a DML statement. So again, a COMMIT cannot be issued.

A PROCEDURE on the other hand cannot be executed from a DML statement, so COMMIT statements are allowed, including the implicit commit performed by a DDL statement.

You can't do this from a view, but a stored procedure itself can return a result set.

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `merge_and_select` ()
BEGIN
    CALL rMergeDateFields();
    SELECT * FROM MergeData;
END $$

If you CALL merge_and_select() the rMergeDateFields procedure will be run and then you will get the contents of the MergeData table returned to you, in one step... which sounds like what you're wanting.

This is, however, a really bad implementation, because there's no control for concurrent calls to merge_and_select(), so all kinds of things could go wrong if it's run more than once at the same time.

However, depending on what you really need rMergeDateFields() to do, it's possible that you could rewrite rMergeDateFields() to actually perform whatever work you need done and return it directly to the client without using the MergeData table using an unbounded SELECT, as shown above.

Anything you SELECT in a stored procedure without using INTO a variable is returned to the client as a response from the CALL .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM