问题
I have a quite complicated data structure that lies in several tables. I have a function that makes a copy of that structure. I want to make a copy and get newly created data in a single query like this:
SELECT
*
FROM
main_table
JOIN other_table
ON (main_table.id = other_table.main_id)
WHERE
main_table.id = make_copy(old_id);
The copy is successfully created, but is not returned by the above query. I guess it is not yet visible for the outer query or somehow committed.
I have also tried to use WITH ... SELECT ...
but with no success...
The function make_copy(id)
is declared as VOLATILE
because it modifies the database, and multiple calls with the same parameter will create multiple copies.
Possible solution could be that make_copy(id)
function would return the whole new data structure (SELECT * FROM make_copy(old_id)
) but it would require many aliasing (many tables have id
or name
column). Also I would end up with many places to build (read) that data structure.
How can I call that function and use its result (and all side effects) in one query?
回答1:
I'm afraid that's not possible without splitting it into two queries.
CTE can't help you - Data-Modifying Statements in WITH (See there example with updating table inside of the cte):
...The sub-statements in WITH are executed concurrently with each other and with the main query. Therefore, when using data-modifying statements in WITH, the order in which the specified updates actually happen is unpredictable. All the statements are executed with the same snapshot (see Chapter 13), so they cannot “see” one another's effects on the target tables. This alleviates the effects of the unpredictability of the actual order of row updates, and means that RETURNING data is the only way to communicate changes between different WITH sub-statements and the main query...
And I guess you cannot do this with function either - Function Volatility Categories:
For functions written in SQL or in any of the standard procedural languages, there is a second important property determined by the volatility category, namely the visibility of any data changes that have been made by the SQL command that is calling the function. A VOLATILE function will see such changes, a STABLE or IMMUTABLE function will not. ... VOLATILE functions obtain a fresh snapshot at the start of each query they execute.
来源:https://stackoverflow.com/questions/55766949/get-data-copied-by-a-function