文档中心 > 云数据库 RDS 版

PostgreSQL UPSERT 的功能与用法

更新时间: 访问次数:2508

PostgreSQL 9.5引入了一项新功能,即UPSERT(insert on conflict do)。当插入遇到约束错误时,直接返回或者改为执行UPDATE。

UPSERT语法

UPSERT的语法如下所示。PostgreSQL 9.5以前的版本,可以通过函数或者with语法来实现与UPSERT类似的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<ol class="linenums">
  
 <li class="L0"><span class="typ">Command</span><span class="pun">:</span><span class="pln">     INSERT  </span></li>
  
 <li class="L1"><span class="typ">Description</span><span class="pun">:</span><span class="pln"> create </span><span class="kwd">new</span><span class="pln"> rows </span><span class="kwd">in</span><span class="pln"> a table  </span></li>
  
 <li class="L2"><span class="typ">Syntax</span><span class="pun">:</span><span class="pln">  </span></li>
  
 <li class="L3"><span class="pun">[</span><span class="pln"> WITH </span><span class="pun">[</span><span class="pln"> RECURSIVE </span><span class="pun">]</span><span class="pln"> with_query </span><span class="pun">[,</span><span class="pln"> </span><span class="pun">...]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">  </span></li>
  
 <li class="L4"><span class="pln">INSERT INTO table_name </span><span class="pun">[</span><span class="pln"> AS </span><span class="kwd">alias</span><span class="pln"> </span><span class="pun">]</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">(</span><span class="pln"> column_name </span><span class="pun">[,</span><span class="pln"> </span><span class="pun">...]</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> </span><span class="pun">]</span><span class="pln">  </span></li>
  
 <li class="L5"><span class="pln">    </span><span class="pun">{</span><span class="pln"> DEFAULT VALUES </span><span class="pun">|</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> expression </span><span class="pun">|</span><span class="pln"> DEFAULT </span><span class="pun">}</span><span class="pln"> </span><span class="pun">[,</span><span class="pln"> </span><span class="pun">...]</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> </span><span class="pun">[,</span><span class="pln"> </span><span class="pun">...]</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> query </span><span class="pun">}</span><span class="pln">  </span></li>
  
 <li class="L6"><span class="pln">    </span><span class="pun">[</span><span class="pln"> ON CONFLICT </span><span class="pun">[</span><span class="pln"> conflict_target </span><span class="pun">]</span><span class="pln"> conflict_action </span><span class="pun">]</span><span class="pln">  </span></li>
  
 <li class="L7"><span class="pln">    </span><span class="pun">[</span><span class="pln"> RETURNING </span><span class="pun">*</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> output_expression </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> AS </span><span class="pun">]</span><span class="pln"> output_name </span><span class="pun">]</span><span class="pln"> </span><span class="pun">[,</span><span class="pln"> </span><span class="pun">...]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">  </span></li>
  
 <li class="L8"></li>
  
 <li class="L9"><span class="kwd">where</span><span class="pln"> conflict_target can be one of</span><span class="pun">:</span><span class="pln">  </span></li>
  
 <li class="L0"></li>
  
 <li class="L1"><span class="pln">    </span><span class="pun">(</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> index_column_name </span><span class="pun">|</span><span class="pln"> </span><span class="pun">(</span><span class="pln"> index_expression </span><span class="pun">)</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> COLLATE collation </span><span class="pun">]</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> opclass </span><span class="pun">]</span><span class="pln"> </span><span class="pun">[,</span><span class="pln"> </span><span class="pun">...]</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> WHERE index_predicate </span><span class="pun">]</span><span class="pln">  </span></li>
  
 <li class="L2"><span class="pln">    ON CONSTRAINT constraint_name  </span></li>
  
 <li class="L3"></li>
  
 <li class="L4"><span class="kwd">and</span><span class="pln"> conflict_action </span><span class="kwd">is</span><span class="pln"> one of</span><span class="pun">:</span><span class="pln">  </span></li>
  
 <li class="L5"></li>
  
 <li class="L6"><span class="pln">    DO NOTHING  </span></li>
  
 <li class="L7"><span class="pln">    DO UPDATE SET </span><span class="pun">{</span><span class="pln"> column_name </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> expression </span><span class="pun">|</span><span class="pln"> DEFAULT </span><span class="pun">}</span><span class="pln"> </span><span class="pun">|</span><span class="pln">  </span></li>
  
 <li class="L8"><span class="pln">                    </span><span class="pun">(</span><span class="pln"> column_name </span><span class="pun">[,</span><span class="pln"> </span><span class="pun">...]</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> expression </span><span class="pun">|</span><span class="pln"> DEFAULT </span><span class="pun">}</span><span class="pln"> </span><span class="pun">[,</span><span class="pln"> </span><span class="pun">...]</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> </span><span class="pun">|</span><span class="pln">  </span></li>
  
 <li class="L9"><span class="pln">                    </span><span class="pun">(</span><span class="pln"> column_name </span><span class="pun">[,</span><span class="pln"> </span><span class="pun">...]</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln"> </span><span class="kwd">sub</span><span class="pun">-</span><span class="pln">SELECT </span><span class="pun">)</span><span class="pln">  </span></li>
  
 <li class="L0"><span class="pln">                  </span><span class="pun">}</span><span class="pln"> </span><span class="pun">[,</span><span class="pln"> </span><span class="pun">...]</span><span class="pln">  </span></li>
  
 <li class="L1"><span class="pln">              </span><span class="pun">[</span><span class="pln"> WHERE condition </span><span class="pun">]</span></li>
 
</ol>

PostgreSQL 9.5及以上版本的UPSERT用法示例

  1. 执行如下命令,创建一张测试表,其中一个字段为唯一键或者主键。

    1
    2
    3
    4
    5
    <ol class="linenums">
      
     <li class="L0"><span class="pln">create table test</span><span class="pun">(</span><span class="pln">id </span><span class="kwd">int</span><span class="pln"> primary key</span><span class="pun">,</span><span class="pln"> info text</span><span class="pun">,</span><span class="pln"> crt_time timestamp</span><span class="pun">);</span></li>
     
    </ol>
  2. 执行如下任一命令,选择插入数据时,若数据存在是进行更新还是直接返回。

    • 不存在则插入,存在则更新,其命令如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      <ol class="linenums">
        
       <li class="L0"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> insert </span><span class="kwd">into</span><span class="pln"> test values </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="str">'test'</span><span class="pun">,</span><span class="pln">now</span><span class="pun">())</span><span class="pln"> on conflict </span><span class="pun">(</span><span class="pln">id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> update </span><span class="kwd">set</span><span class="pln">     info</span><span class="pun">=</span><span class="pln">excluded</span><span class="pun">.</span><span class="pln">info</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">=</span><span class="pln">excluded</span><span class="pun">.</span><span class="pln">crt_time</span><span class="pun">;</span><span class="pln">  </span></li>
        
       <li class="L1"><span class="pln">INSERT </span><span class="lit">0</span><span class="pln"> </span><span class="lit">1</span><span class="pln">  </span></li>
        
       <li class="L2"></li>
        
       <li class="L3"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> test</span><span class="pun">;</span><span class="pln">  </span></li>
        
       <li class="L4"><span class="pln">id </span><span class="pun">|</span><span class="pln"> info </span><span class="pun">|</span><span class="pln">          crt_time            </span></li>
        
       <li class="L5"><span class="pun">----+------+----------------------------</span><span class="pln">  </span></li>
        
       <li class="L6"><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> test </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">27</span><span class="pun">:</span><span class="lit">25.393948</span><span class="pln">  </span></li>
        
       <li class="L7"><span class="pun">(</span><span class="lit">1</span><span class="pln"> row</span><span class="pun">)</span><span class="pln">  </span></li>
        
       <li class="L8"></li>
        
       <li class="L9"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> insert </span><span class="kwd">into</span><span class="pln"> test values </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="str">'hello digoal'</span><span class="pun">,</span><span class="pln">now</span><span class="pun">())</span><span class="pln"> on conflict </span><span class="pun">(</span><span class="pln">id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> update </span><span class="kwd">set</span><span class="pln"> info</span><span class="pun">=</span><span class="pln">excluded</span><span class="pun">.</span><span class="pln">info</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">=</span><span class="pln">excluded</span><span class="pun">.</span><span class="pln">crt_time</span><span class="pun">;</span><span class="pln">  </span></li>
        
       <li class="L0"><span class="pln">INSERT </span><span class="lit">0</span><span class="pln"> </span><span class="lit">1</span><span class="pln">  </span></li>
        
       <li class="L1"></li>
        
       <li class="L2"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> test</span><span class="pun">;</span><span class="pln">  </span></li>
        
       <li class="L3"><span class="pln">id </span><span class="pun">|</span><span class="pln">     info     </span><span class="pun">|</span><span class="pln">          crt_time            </span></li>
        
       <li class="L4"><span class="pun">----+--------------+----------------------------</span><span class="pln">  </span></li>
        
       <li class="L5"><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> hello digoal </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">27</span><span class="pun">:</span><span class="lit">39.140877</span><span class="pln">  </span></li>
        
       <li class="L6"><span class="pun">(</span><span class="lit">1</span><span class="pln"> row</span><span class="pun">)</span></li>
       
      </ol>
    • 不存在则插入,存在则直接返回,即不做任何处理,其命令如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      <ol class="linenums">
        
       <li class="L0"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> insert </span><span class="kwd">into</span><span class="pln"> test values </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="str">'hello digoal'</span><span class="pun">,</span><span class="pln">now</span><span class="pun">())</span><span class="pln"> on conflict </span><span class="pun">(</span><span class="pln">id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> nothing</span><span class="pun">;</span><span class="pln">  </span></li>
        
       <li class="L1"><span class="pln">INSERT </span><span class="lit">0</span><span class="pln"> </span><span class="lit">0</span><span class="pln">  </span></li>
        
       <li class="L2"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> insert </span><span class="kwd">into</span><span class="pln"> test values </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="str">'pu'</span><span class="pun">,</span><span class="pln">now</span><span class="pun">())</span><span class="pln"> on conflict </span><span class="pun">(</span><span class="pln">id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> nothing</span><span class="pun">;</span><span class="pln">  </span></li>
        
       <li class="L3"><span class="pln">INSERT </span><span class="lit">0</span><span class="pln"> </span><span class="lit">0</span><span class="pln">  </span></li>
        
       <li class="L4"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> insert </span><span class="kwd">into</span><span class="pln"> test values </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="str">'pu'</span><span class="pun">,</span><span class="pln">now</span><span class="pun">())</span><span class="pln"> on conflict </span><span class="pun">(</span><span class="pln">id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> nothing</span><span class="pun">;</span><span class="pln">  </span></li>
        
       <li class="L5"><span class="pln">INSERT </span><span class="lit">0</span><span class="pln"> </span><span class="lit">1</span><span class="pln">  </span></li>
        
       <li class="L6"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> test</span><span class="pun">;</span><span class="pln">  </span></li>
        
       <li class="L7"><span class="pln">id </span><span class="pun">|</span><span class="pln">     info     </span><span class="pun">|</span><span class="pln">          crt_time            </span></li>
        
       <li class="L8"><span class="pun">----+--------------+----------------------------</span><span class="pln">  </span></li>
        
       <li class="L9"><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> hello digoal </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">27</span><span class="pun">:</span><span class="lit">39.140877</span><span class="pln">  </span></li>
        
       <li class="L0"><span class="lit">2</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> pu           </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">28</span><span class="pun">:</span><span class="lit">20.37392</span><span class="pln">  </span></li>
        
       <li class="L1"><span class="pun">(</span><span class="lit">2</span><span class="pln"> rows</span><span class="pun">)</span></li>
       
      </ol>

PostgreSQL 9.5以下版本的UPSERT用法示例

您可以根据需求,通过如下三种方法实现类似UPSERT的功能:

  • 通过函数实现。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    <ol class="linenums">
      
     <li class="L0"><span class="pln">  test03</span><span class="pun">=#</span><span class="pln"> create </span><span class="kwd">or</span><span class="pln"> replace </span><span class="kwd">function</span><span class="pln"> f_upsert</span><span class="pun">(</span><span class="kwd">int</span><span class="pun">,</span><span class="pln">text</span><span class="pun">,</span><span class="pln">timestamp</span><span class="pun">)</span><span class="pln"> returns </span><span class="kwd">void</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> $$  </span></li>
      
     <li class="L1"><span class="pln">  declare  </span></li>
      
     <li class="L2"><span class="pln">    res </span><span class="kwd">int</span><span class="pun">;</span><span class="pln">  </span></li>
      
     <li class="L3"><span class="pln">  </span><span class="kwd">begin</span><span class="pln">  </span></li>
      
     <li class="L4"><span class="pln">    update test </span><span class="kwd">set</span><span class="pln"> info</span><span class="pun">=</span><span class="pln">$2</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">=</span><span class="pln">$3 </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="pln">$1</span><span class="pun">;</span><span class="pln">  </span></li>
      
     <li class="L5"><span class="pln">    </span><span class="kwd">if</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> found </span><span class="kwd">then</span><span class="pln">  </span></li>
      
     <li class="L6"><span class="pln">      insert </span><span class="kwd">into</span><span class="pln"> test </span><span class="pun">(</span><span class="pln">id</span><span class="pun">,</span><span class="pln">info</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">)</span><span class="pln"> values </span><span class="pun">(</span><span class="pln">$1</span><span class="pun">,</span><span class="pln">$2</span><span class="pun">,</span><span class="pln">$3</span><span class="pun">);</span><span class="pln">  </span></li>
      
     <li class="L7"><span class="pln">    </span><span class="kwd">end</span><span class="pln"> </span><span class="kwd">if</span><span class="pun">;</span><span class="pln">  </span></li>
      
     <li class="L8"><span class="pln">    exception </span><span class="kwd">when</span><span class="pln"> others </span><span class="kwd">then</span><span class="pln">  </span></li>
      
     <li class="L9"><span class="pln">      </span><span class="kwd">return</span><span class="pun">;</span><span class="pln">  </span></li>
      
     <li class="L0"><span class="pln">  </span><span class="kwd">end</span><span class="pun">;</span><span class="pln">  </span></li>
      
     <li class="L1"><span class="pln">  $$ language plpgsql strict</span><span class="pun">;</span><span class="pln">  </span></li>
      
     <li class="L2"><span class="pln">  CREATE FUNCTION  </span></li>
      
     <li class="L3"></li>
      
     <li class="L4"><span class="pln">  test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> f_upsert</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="str">'digoal'</span><span class="pun">,</span><span class="pln">now</span><span class="pun">()::</span><span class="pln">timestamp</span><span class="pun">);</span><span class="pln">  </span></li>
      
     <li class="L5"><span class="pln">   f_upsert   </span></li>
      
     <li class="L6"><span class="pln">  </span><span class="pun">----------</span><span class="pln">  </span></li>
      
     <li class="L7"></li>
      
     <li class="L8"><span class="pln">  </span><span class="pun">(</span><span class="lit">1</span><span class="pln"> row</span><span class="pun">)</span><span class="pln">  </span></li>
      
     <li class="L9"></li>
      
     <li class="L0"><span class="pln">  test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> test</span><span class="pun">;</span><span class="pln">  </span></li>
      
     <li class="L1"><span class="pln">   id </span><span class="pun">|</span><span class="pln">  info  </span><span class="pun">|</span><span class="pln">          crt_time            </span></li>
      
     <li class="L2"><span class="pln">  </span><span class="pun">----+--------+----------------------------</span><span class="pln">  </span></li>
      
     <li class="L3"><span class="pln">    </span><span class="lit">2</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> pu     </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">28</span><span class="pun">:</span><span class="lit">20.37392</span><span class="pln">  </span></li>
      
     <li class="L4"><span class="pln">    </span><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> digoal </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">31</span><span class="pun">:</span><span class="lit">29.254325</span><span class="pln">  </span></li>
      
     <li class="L5"><span class="pln">  </span><span class="pun">(</span><span class="lit">2</span><span class="pln"> rows</span><span class="pun">)</span><span class="pln">  </span></li>
      
     <li class="L6"></li>
      
     <li class="L7"><span class="pln">  test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> f_upsert</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="str">'digoal001'</span><span class="pun">,</span><span class="pln">now</span><span class="pun">()::</span><span class="pln">timestamp</span><span class="pun">);</span><span class="pln">  </span></li>
      
     <li class="L8"><span class="pln">   f_upsert   </span></li>
      
     <li class="L9"><span class="pln">  </span><span class="pun">----------</span><span class="pln">  </span></li>
      
     <li class="L0"></li>
      
     <li class="L1"><span class="pln">  </span><span class="pun">(</span><span class="lit">1</span><span class="pln"> row</span><span class="pun">)</span><span class="pln">  </span></li>
      
     <li class="L2"></li>
      
     <li class="L3"><span class="pln">  test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> test</span><span class="pun">;</span><span class="pln">  </span></li>
      
     <li class="L4"><span class="pln">   id </span><span class="pun">|</span><span class="pln">   info    </span><span class="pun">|</span><span class="pln">         crt_time            </span></li>
      
     <li class="L5"><span class="pln">  </span><span class="pun">----+-----------+---------------------------</span><span class="pln">  </span></li>
      
     <li class="L6"><span class="pln">    </span><span class="lit">2</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> pu        </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">28</span><span class="pun">:</span><span class="lit">20.37392</span><span class="pln">  </span></li>
      
     <li class="L7"><span class="pln">    </span><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> digoal001 </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">31</span><span class="pun">:</span><span class="lit">38.0529</span><span class="pln">  </span></li>
      
     <li class="L8"><span class="pln">  </span><span class="pun">(</span><span class="lit">2</span><span class="pln"> rows</span><span class="pun">)</span><span class="pln">  </span></li>
      
     <li class="L9"></li>
      
     <li class="L0"><span class="pln">  test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> f_upsert</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="str">'hello'</span><span class="pun">,</span><span class="pln">now</span><span class="pun">()::</span><span class="pln">timestamp</span><span class="pun">);</span><span class="pln">  </span></li>
      
     <li class="L1"><span class="pln">   f_upsert   </span></li>
      
     <li class="L2"><span class="pln">  </span><span class="pun">----------</span><span class="pln">  </span></li>
      
     <li class="L3"></li>
      
     <li class="L4"><span class="pln">  </span><span class="pun">(</span><span class="lit">1</span><span class="pln"> row</span><span class="pun">)</span><span class="pln">  </span></li>
      
     <li class="L5"></li>
      
     <li class="L6"><span class="pln">  test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> test</span><span class="pun">;</span><span class="pln">  </span></li>
      
     <li class="L7"><span class="pln">   id </span><span class="pun">|</span><span class="pln">   info    </span><span class="pun">|</span><span class="pln">         crt_time            </span></li>
      
     <li class="L8"><span class="pln">  </span><span class="pun">----+-----------+---------------------------</span><span class="pln">  </span></li>
      
     <li class="L9"><span class="pln">    </span><span class="lit">2</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> pu        </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">28</span><span class="pun">:</span><span class="lit">20.37392</span><span class="pln">  </span></li>
      
     <li class="L0"><span class="pln">    </span><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> digoal001 </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">31</span><span class="pun">:</span><span class="lit">38.0529</span><span class="pln">  </span></li>
      
     <li class="L1"><span class="pln">    </span><span class="lit">3</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> hello     </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">31</span><span class="pun">:</span><span class="lit">49.14291</span><span class="pln">  </span></li>
      
     <li class="L2"><span class="pln">  </span><span class="pun">(</span><span class="lit">3</span><span class="pln"> rows</span><span class="pun">)</span></li>
     
    </ol>
  • 通过WITH语法,用法1,操作步骤如下:

    1. 执行如下命令,创建一张测试表,其中一个字段为唯一键或者主键。

      1
      2
      3
      4
      5
      <ol class="linenums">
        
       <li class="L0"><span class="pln">create table test</span><span class="pun">(</span><span class="pln">id </span><span class="kwd">int</span><span class="pln"> primary key</span><span class="pun">,</span><span class="pln"> info text</span><span class="pun">,</span><span class="pln"> crt_time timestamp</span><span class="pun">);</span></li>
       
      </ol>
    2. 执行如下命令,若数据存在则更新,不存在则插入。

      1
      2
      3
      4
      5
      <ol class="linenums">
        
       <li class="L0"><span class="kwd">with</span><span class="pln"> upsert </span><span class="kwd">as</span><span class="pln"> </span><span class="pun">(</span><span class="pln">update test </span><span class="kwd">set</span><span class="pln"> info</span><span class="pun">=</span><span class="pln">$info</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">=</span><span class="pln">$crt_time </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="pln">$id returning </span><span class="pun">*)</span><span class="pln"> insert </span><span class="kwd">into</span><span class="pln"> test </span><span class="kwd">select</span><span class="pln"> $id</span><span class="pun">,</span><span class="pln">$info</span><span class="pun">,</span><span class="pln">$crt_time </span><span class="kwd">where</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> exists </span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> upsert </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="pln">$id</span><span class="pun">);</span></li>
       
      </ol>
    3. 执行如下命令,替换变量,进行测试。同时插入一条不存在的值,只有一个会话成功,另一个会话会报主键约束错误。

      1
      2
      3
      4
      5
      <ol class="linenums">
        
       <li class="L0"><span class="kwd">with</span><span class="pln"> upsert </span><span class="kwd">as</span><span class="pln"> </span><span class="pun">(</span><span class="pln">update test </span><span class="kwd">set</span><span class="pln"> info</span><span class="pun">=</span><span class="str">'test'</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">=</span><span class="pln">now</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="lit">1</span><span class="pln"> returning </span><span class="pun">*)</span><span class="pln"> insert </span><span class="kwd">into</span><span class="pln"> test </span><span class="kwd">select</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="str">'test'</span><span class="pun">,</span><span class="pln">now</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">where</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> exists </span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> upsert </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="lit">1</span><span class="pun">);</span></li>
       
      </ol>
  • 通过WITH语法,用法2,操作步骤如下:

    1. 执行如下命令,创建一张数据表,即使表没有主键或者唯一约束,也能保证并发。

      1
      2
      3
      4
      5
      <ol class="linenums">
        
       <li class="L0"><span class="pln">create table test</span><span class="pun">(</span><span class="pln">id </span><span class="kwd">int</span><span class="pun">,</span><span class="pln"> info text</span><span class="pun">,</span><span class="pln"> crt_time timestamp</span><span class="pun">);</span></li>
       
      </ol>
    2. 进行如下任一操作步骤,选择记录不存在时,对于同一条数据更新的处理结果。

      • 对于记录不存在,可以保证只有一个session插入数据,对于同一条数据更新,先来的session会lock记录,后来的session会wait。操作步骤如下所示:

        1. 执行如下命令,确定对数据更新的处理结果。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          <ol class="linenums">
            
           <li class="L0"><span class="kwd">with</span><span class="pln">     </span></li>
            
           <li class="L1"><span class="pln">w1 </span><span class="kwd">as</span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="pun">(</span><span class="str">'x'</span><span class="pun">||</span><span class="pln">substr</span><span class="pun">(</span><span class="pln">md5</span><span class="pun">(</span><span class="str">'$id'</span><span class="pun">),</span><span class="lit">1</span><span class="pun">,</span><span class="lit">16</span><span class="pun">))::</span><span class="pln">bit</span><span class="pun">(</span><span class="lit">64</span><span class="pun">)::</span><span class="pln">bigint </span><span class="kwd">as</span><span class="pln"> tra_id</span><span class="pun">),</span><span class="pln">    </span></li>
            
           <li class="L2"><span class="pln">upsert </span><span class="kwd">as</span><span class="pln"> </span><span class="pun">(</span><span class="pln">update test </span><span class="kwd">set</span><span class="pln"> info</span><span class="pun">=</span><span class="pln">$info</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">=</span><span class="pln">$crt_time </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="pln">$id returning </span><span class="pun">*)</span><span class="pln">    </span></li>
            
           <li class="L3"><span class="pln">insert </span><span class="kwd">into</span><span class="pln"> test </span><span class="kwd">select</span><span class="pln"> $id</span><span class="pun">,</span><span class="pln"> $info</span><span class="pun">,</span><span class="pln"> $crt_time </span><span class="kwd">from</span><span class="pln"> w1     </span></li>
            
           <li class="L4"><span class="kwd">where</span><span class="pln"> pg_try_advisory_xact_lock</span><span class="pun">(</span><span class="pln">tra_id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> exists </span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> upsert </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="pln">$id</span><span class="pun">);</span></li>
           
          </ol>
        2. 替换变量,进行测试。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          <ol class="linenums">
            
           <li class="L0"><span class="kwd">with</span><span class="pln">     </span></li>
            
           <li class="L1"><span class="pln">w1 </span><span class="kwd">as</span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="pun">(</span><span class="str">'x'</span><span class="pun">||</span><span class="pln">substr</span><span class="pun">(</span><span class="pln">md5</span><span class="pun">(</span><span class="str">'1'</span><span class="pun">),</span><span class="lit">1</span><span class="pun">,</span><span class="lit">16</span><span class="pun">))::</span><span class="pln">bit</span><span class="pun">(</span><span class="lit">64</span><span class="pun">)::</span><span class="pln">bigint </span><span class="kwd">as</span><span class="pln"> tra_id</span><span class="pun">),</span><span class="pln">    </span></li>
            
           <li class="L2"><span class="pln">upsert </span><span class="kwd">as</span><span class="pln"> </span><span class="pun">(</span><span class="pln">update test </span><span class="kwd">set</span><span class="pln"> info</span><span class="pun">=</span><span class="str">'digoal0123'</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">=</span><span class="pln">now</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="lit">1</span><span class="pln"> returning </span><span class="pun">*)</span><span class="pln">    </span></li>
            
           <li class="L3"><span class="pln">insert </span><span class="kwd">into</span><span class="pln"> test </span><span class="kwd">select</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'digoal0123'</span><span class="pun">,</span><span class="pln"> now</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> w1     </span></li>
            
           <li class="L4"><span class="pln"> </span><span class="kwd">where</span><span class="pln"> pg_try_advisory_xact_lock</span><span class="pun">(</span><span class="pln">tra_id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> exists </span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> upsert </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="lit">1</span><span class="pun">);</span><span class="pln">    </span></li>
            
           <li class="L5"></li>
            
           <li class="L6"><span class="pln">INSERT </span><span class="lit">0</span><span class="pln"> </span><span class="lit">0</span><span class="pln">  </span></li>
            
           <li class="L7"></li>
            
           <li class="L8"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> test</span><span class="pun">;</span><span class="pln">  </span></li>
            
           <li class="L9"><span class="pln">id </span><span class="pun">|</span><span class="pln">    info    </span><span class="pun">|</span><span class="pln">         crt_time            </span></li>
            
           <li class="L0"><span class="pun">----+------------+---------------------------</span><span class="pln">  </span></li>
            
           <li class="L1"><span class="lit">2</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> pu         </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">28</span><span class="pun">:</span><span class="lit">20.37392</span><span class="pln">  </span></li>
            
           <li class="L2"><span class="lit">3</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> hello      </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">31</span><span class="pun">:</span><span class="lit">49.14291</span><span class="pln">  </span></li>
            
           <li class="L3"><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> digoal0123 </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">31</span><span class="pun">:</span><span class="lit">38.0529</span><span class="pln">  </span></li>
            
           <li class="L4"><span class="pun">(</span><span class="lit">3</span><span class="pln"> rows</span><span class="pun">)</span><span class="pln">  </span></li>
            
           <li class="L5"></li>
            
           <li class="L6"><span class="kwd">with</span><span class="pln">     </span></li>
            
           <li class="L7"><span class="pln">w1 </span><span class="kwd">as</span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="pun">(</span><span class="str">'x'</span><span class="pun">||</span><span class="pln">substr</span><span class="pun">(</span><span class="pln">md5</span><span class="pun">(</span><span class="str">'4'</span><span class="pun">),</span><span class="lit">1</span><span class="pun">,</span><span class="lit">16</span><span class="pun">))::</span><span class="pln">bit</span><span class="pun">(</span><span class="lit">64</span><span class="pun">)::</span><span class="pln">bigint </span><span class="kwd">as</span><span class="pln"> tra_id</span><span class="pun">),</span><span class="pln">    </span></li>
            
           <li class="L8"><span class="pln">upsert </span><span class="kwd">as</span><span class="pln"> </span><span class="pun">(</span><span class="pln">update test </span><span class="kwd">set</span><span class="pln"> info</span><span class="pun">=</span><span class="str">'digoal0123'</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">=</span><span class="pln">now</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="lit">4</span><span class="pln"> returning </span><span class="pun">*)</span><span class="pln">    </span></li>
            
           <li class="L9"><span class="pln">insert </span><span class="kwd">into</span><span class="pln"> test </span><span class="kwd">select</span><span class="pln"> </span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="str">'digoal0123'</span><span class="pun">,</span><span class="pln"> now</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> w1     </span></li>
            
           <li class="L0"><span class="pln"> </span><span class="kwd">where</span><span class="pln"> pg_try_advisory_xact_lock</span><span class="pun">(</span><span class="pln">tra_id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> exists </span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> upsert </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="lit">4</span><span class="pun">);</span><span class="pln">    </span></li>
            
           <li class="L1"></li>
            
           <li class="L2"><span class="pln">INSERT </span><span class="lit">0</span><span class="pln"> </span><span class="lit">1</span><span class="pln">  </span></li>
            
           <li class="L3"></li>
            
           <li class="L4"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> test</span><span class="pun">;</span><span class="pln">  </span></li>
            
           <li class="L5"><span class="pln">id </span><span class="pun">|</span><span class="pln">    info    </span><span class="pun">|</span><span class="pln">          crt_time            </span></li>
            
           <li class="L6"><span class="pun">----+------------+----------------------------</span><span class="pln">  </span></li>
            
           <li class="L7"><span class="lit">2</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> pu         </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">28</span><span class="pun">:</span><span class="lit">20.37392</span><span class="pln">  </span></li>
            
           <li class="L8"><span class="lit">3</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> hello      </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">31</span><span class="pun">:</span><span class="lit">49.14291</span><span class="pln">  </span></li>
            
           <li class="L9"><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> digoal0123 </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">31</span><span class="pun">:</span><span class="lit">38.0529</span><span class="pln">  </span></li>
            
           <li class="L0"><span class="lit">4</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> digoal0123 </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">38</span><span class="pun">:</span><span class="lit">39.801908</span><span class="pln">  </span></li>
            
           <li class="L1"><span class="pun">(</span><span class="lit">4</span><span class="pln"> rows</span><span class="pun">)</span></li>
           
          </ol>
      • 对于记录不存在,可以保证只有一个session插入数据,对于同一条数据更新,先来的session会更新数据,后来的session不等待,直接失败。操作步骤如下所示:

        1. 执行如下命令,确定对数据更新的处理结果。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          <ol class="linenums">
            
           <li class="L0"><span class="kwd">with</span><span class="pln"> w1 </span><span class="kwd">as</span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="pun">(</span><span class="str">'x'</span><span class="pun">||</span><span class="pln">substr</span><span class="pun">(</span><span class="pln">md5</span><span class="pun">(</span><span class="str">'$id'</span><span class="pun">),</span><span class="lit">1</span><span class="pun">,</span><span class="lit">16</span><span class="pun">))::</span><span class="pln">bit</span><span class="pun">(</span><span class="lit">64</span><span class="pun">)::</span><span class="pln">bigint </span><span class="kwd">as</span><span class="pln"> tra_id</span><span class="pun">),</span><span class="pln">    </span></li>
            
           <li class="L1"><span class="pln">upsert </span><span class="kwd">as</span><span class="pln"> </span><span class="pun">(</span><span class="pln">update test </span><span class="kwd">set</span><span class="pln"> info</span><span class="pun">=</span><span class="pln">$info</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">=</span><span class="pln">$crt_time </span><span class="kwd">from</span><span class="pln"> w1 </span><span class="kwd">where</span><span class="pln"> pg_try_advisory_xact_lock</span><span class="pun">(</span><span class="pln">tra_id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> id</span><span class="pun">=</span><span class="pln">$id returning </span><span class="pun">*)</span><span class="pln">    </span></li>
            
           <li class="L2"><span class="pln">insert </span><span class="kwd">into</span><span class="pln"> test </span><span class="kwd">select</span><span class="pln"> $id</span><span class="pun">,</span><span class="pln">$info</span><span class="pun">,</span><span class="pln">$crt_time </span><span class="kwd">from</span><span class="pln"> w1   </span></li>
            
           <li class="L3"><span class="kwd">where</span><span class="pln"> pg_try_advisory_xact_lock</span><span class="pun">(</span><span class="pln">tra_id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> exists </span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> upsert </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="pln">$id</span><span class="pun">);</span></li>
           
          </ol>
        2. 替换变量,进行测试。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          <ol class="linenums">
            
           <li class="L0"><span class="kwd">with</span><span class="pln"> w1 </span><span class="kwd">as</span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="pun">(</span><span class="str">'x'</span><span class="pun">||</span><span class="pln">substr</span><span class="pun">(</span><span class="pln">md5</span><span class="pun">(</span><span class="str">'1'</span><span class="pun">),</span><span class="lit">1</span><span class="pun">,</span><span class="lit">16</span><span class="pun">))::</span><span class="pln">bit</span><span class="pun">(</span><span class="lit">64</span><span class="pun">)::</span><span class="pln">bigint </span><span class="kwd">as</span><span class="pln"> tra_id</span><span class="pun">),</span><span class="pln">    </span></li>
            
           <li class="L1"><span class="pln">upsert </span><span class="kwd">as</span><span class="pln"> </span><span class="pun">(</span><span class="pln">update test </span><span class="kwd">set</span><span class="pln"> info</span><span class="pun">=</span><span class="str">'test'</span><span class="pun">,</span><span class="pln">crt_time</span><span class="pun">=</span><span class="pln">now</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> w1 </span><span class="kwd">where</span><span class="pln">             pg_try_advisory_xact_lock</span><span class="pun">(</span><span class="pln">tra_id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> id</span><span class="pun">=</span><span class="lit">1</span><span class="pln"> returning </span><span class="pun">*)</span><span class="pln">    </span></li>
            
           <li class="L2"><span class="pln">insert </span><span class="kwd">into</span><span class="pln"> test </span><span class="kwd">select</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="str">'test'</span><span class="pun">,</span><span class="pln">now</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> w1   </span></li>
            
           <li class="L3"><span class="pln"> </span><span class="kwd">where</span><span class="pln"> pg_try_advisory_xact_lock</span><span class="pun">(</span><span class="pln">tra_id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> exists </span><span class="pun">(</span><span class="kwd">select</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> upsert </span><span class="kwd">where</span><span class="pln"> id</span><span class="pun">=</span><span class="lit">1</span><span class="pun">);</span><span class="pln">    </span></li>
            
           <li class="L4"></li>
            
           <li class="L5"><span class="pln">INSERT </span><span class="lit">0</span><span class="pln"> </span><span class="lit">0</span><span class="pln">  </span></li>
            
           <li class="L6"></li>
            
           <li class="L7"><span class="pln">test03</span><span class="pun">=#</span><span class="pln"> </span><span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> test</span><span class="pun">;</span><span class="pln">  </span></li>
            
           <li class="L8"><span class="pln">id </span><span class="pun">|</span><span class="pln">    info    </span><span class="pun">|</span><span class="pln">          crt_time            </span></li>
            
           <li class="L9"><span class="pun">----+------------+----------------------------</span><span class="pln">  </span></li>
            
           <li class="L0"><span class="lit">2</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> pu         </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">28</span><span class="pun">:</span><span class="lit">20.37392</span><span class="pln">  </span></li>
            
           <li class="L1"><span class="lit">3</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> hello      </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">31</span><span class="pun">:</span><span class="lit">49.14291</span><span class="pln">  </span></li>
            
           <li class="L2"><span class="lit">4</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> digoal0123 </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">42</span><span class="pun">:</span><span class="lit">50.912887</span><span class="pln">  </span></li>
            
           <li class="L3"><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> test       </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2017</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">24</span><span class="pln"> </span><span class="lit">15</span><span class="pun">:</span><span class="lit">44</span><span class="pun">:</span><span class="lit">44.245167</span><span class="pln">  </span></li>
            
           <li class="L4"><span class="pun">(</span><span class="lit">4</span><span class="pln"> rows</span><span class="pun">)</span></li>
           
          </ol>

FAQ

关于此文档暂时还没有FAQ
返回
顶部