如果search_patch中已经存在另一个名为"foo"的表(并且您没有使用冲突的列名),则Postgres将基于该表来计划INSERT.如果任何值导致(错误!)表中的冲突,通常会在执行时出现错误.或者,如果运气不好,它甚至可能在没有错误消息的情况下写入该表!非常狡猾的错误.使用 PL/pgSQL 函数不会发生这种情况,因为它会将SQL命令像已准备好的语句一样处理,并按 顺序计划和执行.因此,每个语句都可以查看先前语句中创建的对象.因此,从未访问过的语句甚至都不会被计划-与SQL函数不同.语句的执行计划可以缓存在同一会话中-与SQL函数不同. 阅读有关PL/pgSQL函数中计划缓存的详细信息在此处的手册中.对于某些用例,每种方法都具有优势.进一步阅读: 差异PostgreSQL函数中的语言sql和语言plpgsql之间PostgreSQL document says:Why "It's recommended to use PL/pgSQL instead of a SQL function in this type of situation", where the PL/pgSQL or SQL function contains commands that alter the system catalogs, such as CREATE TABLE foo (...); INSERT INTO foo VALUES(...); ?"The entire body of a SQL function is parsed before any of it is executed". Is it not true for a PL/pgSQL function? What differences are between SQL functions and PL/pgSQL functions, in terms of parsing and executing the commands in their bodies? 解决方案 You bolded the key sentence in the manual yourself:Also read about The Parser Stage in the manual.It consists of two major parts: the parser and the transformation process. Quoting the manual:If an SQL function contains these commands:CREATE TABLE foo (...);INSERT INTO foo VALUES(...);Both statements are planned at virtually the same time (based on the same snapshot of the system catalogs). Hence, the INSERT cannot see the table "foo" presumably created with the previous CREATE command. That creates one of the following problems:If there is no other table named "foo" in your search_patch (yet), Postgres complains when trying to create the function:If another table named "foo" already exists in your search_patch (and you don't use conflicting column names), Postgres will plan the INSERT based on that pre-existing table. Typically that results in an error at execution time, if any values cause conflicts in the (wrong!) table. Or, with some bad luck, it might even write to that table without error message! Very sneaky bug.That cannot happen with a PL/pgSQL function, because it treats SQL commands like prepared statements, planned and executed sequentially. So each statement can see objects created in previous statements.Consequently, statements that are never visited are never even planned - unlike with SQL functions. And the execution plan for statements can be cached within the same session - also unlike SQL functions. Read details about plan caching in PL/pgSQL functions in the manual here.Each approach has advantages for some use cases. Further reading:Difference between language sql and language plpgsql in PostgreSQL functions 这篇关于为什么PL/pgSQL函数会有副作用,而SQL函数却没有?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-16 14:34
查看更多