postgresql Postgres不接受在列名之前使用表别名

dauxcl2d  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(5)|浏览(168)

我使用的是一个框架(Jodd),它将表别名添加到SQL Select中的列名中。它看起来像格式良好的SQL,但Postgres会阻塞它。

update GREETING Greeting 
     set Greeting.ID=5, 
         Greeting.NAME='World', 
         Greeting.PHRASE='Hello World!'  
where (Greeting.ID=5)

字符串
给出一个错误:

Error: ERROR: column "greeting" of relation "greeting" does not exist
SQLState:  42703


有没有办法让Postgres接受这个SQL?我的另一个选择是破解框架,我不想这样做。

cnh2zyt3

cnh2zyt31#

问题是您在SET子句中的列中包含了表别名。请参阅UPDATE in Postgres docs的文档:

  • column*
  • table * 中列的名称。如果需要,列名可以用子字段名称或数组下标限定。不要在目标列的规范中包括表的名称-例如,**UPDATE tab SET tab.col = 1**无效。

这在Postgres中是有效的:

update GREETING Greeting 
set 
    NAME='World', 
    PHRASE='Hello World!' 
where Greeting.ID=5 ;

字符串

kcwpcxri

kcwpcxri2#

查看UPDATE语句的文档,特别是 * column * 部分:在SET子句中使用表别名作为列前缀是非法的。

UPDATE GREETING Greeting
   SET ID=5, NAME='World', PHRASE='Hello World!'
 WHERE (Greeting.ID=5);

字符串

nwlqm0z1

nwlqm0z13#

请尝试使用最新的Jodd v3.3.7,其中修复了此问题。
问题出在Jodd库中:实体更新方法会生成带有表别名的更新语句。新版本只是不放表别名;这适用于Postgres和其他数据库。

vwhgwdsa

vwhgwdsa4#

正如其他人所说的,在postgres中使用别名作为被更新的列的名称是非法的,但请注意,在rhs表达式中使用别名是可能的(有时是必要的)。例如:

CREATE TABLE greetings (name VARCHAR(20), phrase VARCHAR(100));
INSERT INTO greetings (name, phrase);
VALUES ('palindrome_1', 'Rise to vote sir'),
       ('palindrome_2', 'Race fast, safe car');

-- You can do something like this:
UPDATE greetings g SET phrase = REVERSE (g.phrase);
                                      -- ^
                                      -- |
                                      -- +--- this works

字符串
在这个例子中这有点傻,因为我们不需要这个别名。当涉及多个表时,这变得更有用。

pexxcrt2

pexxcrt25#

答案是否定的。你不能在SET子句的左边使用它们。你应该设法阻止Jodd在那里添加它们。
我认为在UPDATE中,当你从另一个表中更新数据时,表别名是最有用的,因为这样的查询往往比单表更新更快,但是没有其他答案给出这样的例子。
需要记住的重要一点是,SET子句中的目标字段根本不需要命名。所以,是的,您确实可以使用前缀;只需从SET目标字段中省略它们,一切都正常。
以下内容有效:

UPDATE my_target_table_with_a_long_name t
  SET (target_field_a, target_field_b) = (s.source_field_a, s.source_field_b)
FROM my_source_table_with_another_long_name s
WHERE t.id = s.target_id;

字符串
注意表别名是如何在所有地方使用的,除了SET子句比较左侧的**,这里的表名引用完全省略了。
在您的情况下,最好只编写查询而不使用任何别名:

UPDATE "GREETING"
  SET "ID"=5, "NAME"='World', "PHRASE"='Hello World!'  
WHERE (ID=5);


您可以添加别名并在WHERE子句中使用别名(例如greet."ID"=5),但是由于您的查询不引用其他表,那么这究竟有什么意义呢?

相关问题