{"Entry":{"collection":"sql","key":"savepoint","name":"SAVEPOINT","aliases":["savepoint"],"metadata":{"aliases":["savepoint"],"changed_in":[],"changes":[{"from":"7.4","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":[],"removed":[]},"status":"added","synopsis":null,"to":"8.0"},{"from":"8.4","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["compatibility"],"removed":[]},"status":"changed","synopsis":null,"to":"9.0"},{"from":"9.6","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["parameters","examples"],"removed":[]},"status":"changed","synopsis":null,"to":"10"},{"from":"13","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["notes"],"removed":[]},"status":"changed","synopsis":null,"to":"14"}],"content_hash":"62e42559c4574a000b7eb53392bf6cd3b7d953cff91e2a70704bed77a8e827ce","editorial":{},"first_version":"8.0","group":"transaction","imported_at":"2026-09-30T17:43:39.348425+08:00","last_version":"20","name":"SAVEPOINT","object":"","position":13005,"present_in":["8.0","8.1","8.2","8.3","8.4","9.0","9.1","9.2","9.3","9.4","9.5","9.6","10","11","12","13","14","15","16","17","18","19","20"],"purpose":"define a new savepoint within the current transaction","purpose_zh":"","related":["begin","commit","release-savepoint","rollback","rollback-to-savepoint"],"slug":"savepoint","source_rev":"a709ab85","synopsis":"SAVEPOINT savepoint_name","verb":"SAVEPOINT"}},"Definition":{"Collection":"sql","Key":"savepoint","SourceDatabase":"center","Version":"18","SourceTable":"sqlcmd","SourceKey":"savepoint","SourceRevision":"a709ab85","Facts":{"anchor":"SQL-SAVEPOINT","file":"sql-savepoint.html","lang":"en","name":"SAVEPOINT","purpose":"define a new savepoint within the current transaction","purpose_zh":"","related":["begin","commit","release-savepoint","rollback","rollback-to-savepoint"],"sections":[{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eSAVEPOINT\u003c/code\u003e establishes a new savepoint within the current transaction.\u003c/p\u003e\u003cp\u003eA savepoint is a special mark inside a transaction that allows all commands that are executed after it was established to be rolled back, restoring the transaction state to what it was at the time of the savepoint.\u003c/p\u003e","key":"description","title":"Description"},{"html":"\u003cdiv class=\"variablelist\"\u003e\u003cdl class=\"variablelist\"\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003esavepoint_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe name to give to the new savepoint. If savepoints with the same name already exist, they will be inaccessible until newer identically-named savepoints are released.\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e","key":"parameters","title":"Parameters"},{"html":"\u003cp\u003eUse \u003ca href=\"/docs/18/sql-rollback-to.html\" title=\"ROLLBACK TO SAVEPOINT\"\u003e\u003ccode class=\"command\"\u003eROLLBACK TO\u003c/code\u003e\u003c/a\u003e to rollback to a savepoint. Use \u003ca href=\"/docs/18/sql-release-savepoint.html\" title=\"RELEASE SAVEPOINT\"\u003e\u003ccode class=\"command\"\u003eRELEASE SAVEPOINT\u003c/code\u003e\u003c/a\u003e to destroy a savepoint, keeping the effects of commands executed after it was established.\u003c/p\u003e\u003cp\u003eSavepoints can only be established when inside a transaction block. There can be multiple savepoints defined within a transaction.\u003c/p\u003e","key":"notes","title":"Notes"},{"html":"\u003cp\u003eTo establish a savepoint and later undo the effects of all commands executed after it was established:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eBEGIN;\n    INSERT INTO table1 VALUES (1);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (2);\n    ROLLBACK TO SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (3);\nCOMMIT;\n\u003c/pre\u003e\u003cp\u003eThe above transaction will insert the values 1 and 3, but not 2.\u003c/p\u003e\u003cp\u003eTo establish and later destroy a savepoint:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eBEGIN;\n    INSERT INTO table1 VALUES (3);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (4);\n    RELEASE SAVEPOINT my_savepoint;\nCOMMIT;\n\u003c/pre\u003e\u003cp\u003eThe above transaction will insert both 3 and 4.\u003c/p\u003e\u003cp\u003eTo use a single savepoint name:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eBEGIN;\n    INSERT INTO table1 VALUES (1);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (2);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (3);\n\n    -- rollback to the second savepoint\n    ROLLBACK TO SAVEPOINT my_savepoint;\n    SELECT * FROM table1;               -- shows rows 1 and 2\n\n    -- release the second savepoint\n    RELEASE SAVEPOINT my_savepoint;\n\n    -- rollback to the first savepoint\n    ROLLBACK TO SAVEPOINT my_savepoint;\n    SELECT * FROM table1;               -- shows only row 1\nCOMMIT;\n\u003c/pre\u003e\u003cp\u003eThe above transaction shows row 3 being rolled back first, then row 2.\u003c/p\u003e","key":"examples","title":"Examples"},{"html":"\u003cp\u003eSQL requires a savepoint to be destroyed automatically when another savepoint with the same name is established. In \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e, the old savepoint is kept, though only the more recent one will be used when rolling back or releasing. (Releasing the newer savepoint with \u003ccode class=\"command\"\u003eRELEASE SAVEPOINT\u003c/code\u003e will cause the older one to again become accessible to \u003ccode class=\"command\"\u003eROLLBACK TO SAVEPOINT\u003c/code\u003e and \u003ccode class=\"command\"\u003eRELEASE SAVEPOINT\u003c/code\u003e.) Otherwise, \u003ccode class=\"command\"\u003eSAVEPOINT\u003c/code\u003e is fully SQL conforming.\u003c/p\u003e","key":"compatibility","title":"Compatibility"},{"html":"\u003cspan class=\"simplelist\"\u003e\u003ca href=\"/wiki/sql/begin/?v=18\" title=\"BEGIN\"\u003e\u003cspan class=\"refentrytitle\"\u003eBEGIN\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/commit/?v=18\" title=\"COMMIT\"\u003e\u003cspan class=\"refentrytitle\"\u003eCOMMIT\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/release-savepoint/?v=18\" title=\"RELEASE SAVEPOINT\"\u003e\u003cspan class=\"refentrytitle\"\u003eRELEASE SAVEPOINT\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/rollback/?v=18\" title=\"ROLLBACK\"\u003e\u003cspan class=\"refentrytitle\"\u003eROLLBACK\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/rollback-to-savepoint/?v=18\" title=\"ROLLBACK TO SAVEPOINT\"\u003e\u003cspan class=\"refentrytitle\"\u003eROLLBACK TO SAVEPOINT\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e","key":"see_also","title":"See Also"}],"sections_same_as":"","slug":"18","synopsis_html":"SAVEPOINT \u003cem class=\"replaceable\"\u003e\u003ccode\u003esavepoint_name\u003c/code\u003e\u003c/em\u003e","synopsis_text":"SAVEPOINT savepoint_name"},"ManualEvidence":{},"MeasuredEvidence":{}},"Text":{"Collection":"sql","Key":"savepoint","SourceDatabase":"pgweb","Version":"18","Locale":"zh-Hans","Title":"SAVEPOINT","Summary":"在当前事务中定义一个新的保存点","BodyHTML":"\u003cpre\u003eSAVEPOINT savepoint_name\u003c/pre\u003e\u003csection\u003e\u003ch2\u003e描述\u003c/h2\u003e\u003cp\u003e\u003ccode\u003eSAVEPOINT\u003c/code\u003e在当前事务中建立一个新的保存点。\u003c/p\u003e\u003cp\u003e保存点是事务中的一种特殊标记，它允许回滚在其建立之后执行的所有命令，从而将事务状态恢复到建立保存点时的状态。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e参数\u003c/h2\u003e\u003cdiv\u003e\u003cdl\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003esavepoint_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e赋予新保存点的名称。如果已经存在同名保存点，则在较新的同名保存点被释放之前，较旧的保存点将无法访问。\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e注解\u003c/h2\u003e\u003cp\u003e使用\u003ca href=\"/docs/18/sql-rollback-to.html\" title=\"ROLLBACK TO SAVEPOINT\" rel=\"nofollow\"\u003e\u003ccode\u003eROLLBACK TO\u003c/code\u003e\u003c/a\u003e回滚到保存点。使用\u003ca href=\"/docs/18/sql-release-savepoint.html\" title=\"RELEASE SAVEPOINT\" rel=\"nofollow\"\u003e\u003ccode\u003eRELEASE SAVEPOINT\u003c/code\u003e\u003c/a\u003e 销毁保存点，同时保留其建立后执行的命令所产生的效果。\u003c/p\u003e\u003cp\u003e保存点只能在事务块内部建立。一个事务中可以定义多个保存点。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e示例\u003c/h2\u003e\u003cp\u003e要建立一个保存点，并在稍后撤销其建立后执行的所有命令的效果：\u003c/p\u003e\u003cpre\u003eBEGIN;\n    INSERT INTO table1 VALUES (1);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (2);\n    ROLLBACK TO SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (3);\nCOMMIT;\n\u003c/pre\u003e\u003cp\u003e上述事务将插入值 1 和 3，而不会插入 2。\u003c/p\u003e\u003cp\u003e要建立保存点，并在稍后销毁它：\u003c/p\u003e\u003cpre\u003eBEGIN;\n    INSERT INTO table1 VALUES (3);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (4);\n    RELEASE SAVEPOINT my_savepoint;\nCOMMIT;\n\u003c/pre\u003e\u003cp\u003e上述事务将同时插入 3 和 4。\u003c/p\u003e\u003cp\u003e要重复使用同一个保存点名称：\u003c/p\u003e\u003cpre\u003eBEGIN;\n    INSERT INTO table1 VALUES (1);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (2);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (3);\n\n    -- 回滚到第二个保存点\n    ROLLBACK TO SAVEPOINT my_savepoint;\n    SELECT * FROM table1;               -- 显示值为 1 和 2 的行\n\n    -- 释放第二个保存点\n    RELEASE SAVEPOINT my_savepoint;\n\n    -- 回滚到第一个保存点\n    ROLLBACK TO SAVEPOINT my_savepoint;\n    SELECT * FROM table1;               -- 仅显示值为 1 的行\nCOMMIT;\n\u003c/pre\u003e\u003cp\u003e上述事务展示了先回滚值为 3 的行，再回滚值为 2 的行。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e兼容性\u003c/h2\u003e\u003cp\u003eSQL 要求在建立另一个同名保存点时自动销毁原有保存点。在 \u003cspan\u003ePostgreSQL\u003c/span\u003e中，旧保存点会被保留，不过在回滚或释放时只会使用最近建立的那个。（如果使用 \u003ccode\u003eRELEASE SAVEPOINT\u003c/code\u003e释放较新的保存点，较旧的保存点将再次可供 \u003ccode\u003eROLLBACK TO SAVEPOINT\u003c/code\u003e 和 \u003ccode\u003eRELEASE SAVEPOINT\u003c/code\u003e 使用。）除此之外，\u003ccode\u003eSAVEPOINT\u003c/code\u003e 完全符合 SQL。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e另见\u003c/h2\u003e\u003cspan\u003e\u003ca href=\"/wiki/sql/begin/?v=18\" title=\"BEGIN\" rel=\"nofollow\"\u003e\u003cspan\u003eBEGIN\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/commit/?v=18\" title=\"COMMIT\" rel=\"nofollow\"\u003e\u003cspan\u003eCOMMIT\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/release-savepoint/?v=18\" title=\"RELEASE SAVEPOINT\" rel=\"nofollow\"\u003e\u003cspan\u003eRELEASE SAVEPOINT\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/rollback/?v=18\" title=\"ROLLBACK\" rel=\"nofollow\"\u003e\u003cspan\u003eROLLBACK\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/rollback-to-savepoint/?v=18\" title=\"ROLLBACK TO SAVEPOINT\" rel=\"nofollow\"\u003e\u003cspan\u003eROLLBACK TO SAVEPOINT\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e\u003c/section\u003e","SourceRevision":"1b5ca64c","ContentHash":"8ddda51a86b52ab3ceb5873d93157f68a184feb3910f50f3aa37cfbf43a5b794","Payload":{"purpose_zh":"在当前事务中定义一个新的保存点","sections":[{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eSAVEPOINT\u003c/code\u003e在当前事务中建立一个新的保存点。\u003c/p\u003e\u003cp\u003e保存点是事务中的一种特殊标记，它允许回滚在其建立之后执行的所有命令，从而将事务状态恢复到建立保存点时的状态。\u003c/p\u003e","key":"description","title":"描述"},{"html":"\u003cdiv class=\"variablelist\"\u003e\u003cdl class=\"variablelist\"\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003esavepoint_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e赋予新保存点的名称。如果已经存在同名保存点，则在较新的同名保存点被释放之前，较旧的保存点将无法访问。\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e","key":"parameters","title":"参数"},{"html":"\u003cp\u003e使用\u003ca href=\"/docs/18/sql-rollback-to.html\" title=\"ROLLBACK TO SAVEPOINT\"\u003e\u003ccode class=\"command\"\u003eROLLBACK TO\u003c/code\u003e\u003c/a\u003e回滚到保存点。使用\u003ca href=\"/docs/18/sql-release-savepoint.html\" title=\"RELEASE SAVEPOINT\"\u003e\u003ccode class=\"command\"\u003eRELEASE SAVEPOINT\u003c/code\u003e\u003c/a\u003e 销毁保存点，同时保留其建立后执行的命令所产生的效果。\u003c/p\u003e\u003cp\u003e保存点只能在事务块内部建立。一个事务中可以定义多个保存点。\u003c/p\u003e","key":"notes","title":"注解"},{"html":"\u003cp\u003e要建立一个保存点，并在稍后撤销其建立后执行的所有命令的效果：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eBEGIN;\n    INSERT INTO table1 VALUES (1);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (2);\n    ROLLBACK TO SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (3);\nCOMMIT;\n\u003c/pre\u003e\u003cp\u003e上述事务将插入值 1 和 3，而不会插入 2。\u003c/p\u003e\u003cp\u003e要建立保存点，并在稍后销毁它：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eBEGIN;\n    INSERT INTO table1 VALUES (3);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (4);\n    RELEASE SAVEPOINT my_savepoint;\nCOMMIT;\n\u003c/pre\u003e\u003cp\u003e上述事务将同时插入 3 和 4。\u003c/p\u003e\u003cp\u003e要重复使用同一个保存点名称：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eBEGIN;\n    INSERT INTO table1 VALUES (1);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (2);\n    SAVEPOINT my_savepoint;\n    INSERT INTO table1 VALUES (3);\n\n    -- 回滚到第二个保存点\n    ROLLBACK TO SAVEPOINT my_savepoint;\n    SELECT * FROM table1;               -- 显示值为 1 和 2 的行\n\n    -- 释放第二个保存点\n    RELEASE SAVEPOINT my_savepoint;\n\n    -- 回滚到第一个保存点\n    ROLLBACK TO SAVEPOINT my_savepoint;\n    SELECT * FROM table1;               -- 仅显示值为 1 的行\nCOMMIT;\n\u003c/pre\u003e\u003cp\u003e上述事务展示了先回滚值为 3 的行，再回滚值为 2 的行。\u003c/p\u003e","key":"examples","title":"示例"},{"html":"\u003cp\u003eSQL 要求在建立另一个同名保存点时自动销毁原有保存点。在 \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e中，旧保存点会被保留，不过在回滚或释放时只会使用最近建立的那个。（如果使用 \u003ccode class=\"command\"\u003eRELEASE SAVEPOINT\u003c/code\u003e释放较新的保存点，较旧的保存点将再次可供 \u003ccode class=\"command\"\u003eROLLBACK TO SAVEPOINT\u003c/code\u003e 和 \u003ccode class=\"command\"\u003eRELEASE SAVEPOINT\u003c/code\u003e 使用。）除此之外，\u003ccode class=\"command\"\u003eSAVEPOINT\u003c/code\u003e 完全符合 SQL。\u003c/p\u003e","key":"compatibility","title":"兼容性"},{"html":"\u003cspan class=\"simplelist\"\u003e\u003ca href=\"/wiki/sql/begin/?v=18\" title=\"BEGIN\"\u003e\u003cspan class=\"refentrytitle\"\u003eBEGIN\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/commit/?v=18\" title=\"COMMIT\"\u003e\u003cspan class=\"refentrytitle\"\u003eCOMMIT\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/release-savepoint/?v=18\" title=\"RELEASE SAVEPOINT\"\u003e\u003cspan class=\"refentrytitle\"\u003eRELEASE SAVEPOINT\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/rollback/?v=18\" title=\"ROLLBACK\"\u003e\u003cspan class=\"refentrytitle\"\u003eROLLBACK\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/rollback-to-savepoint/?v=18\" title=\"ROLLBACK TO SAVEPOINT\"\u003e\u003cspan class=\"refentrytitle\"\u003eROLLBACK TO SAVEPOINT\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e","key":"see_also","title":"另见"}],"sections_same_as":"","synopsis_html":"SAVEPOINT \u003cem class=\"replaceable\"\u003e\u003ccode\u003esavepoint_name\u003c/code\u003e\u003c/em\u003e","synopsis_text":"SAVEPOINT savepoint_name"}},"RequestedLocale":"zh-Hans","Fallback":false,"Versions":["10","11","12","13","14","15","16","17","18","19","20","8.0","8.1","8.2","8.3","8.4","9.0","9.1","9.2","9.3","9.4","9.5","9.6"],"Locales":["en","zh-Hans"],"Signatures":null,"Spellings":null,"SQLState":null,"Evidence":null}
