【问题标题】:PostgreSQL: Select from table only if table existsPostgreSQL:仅当表存在时才从表中选择
【发布时间】:2021-04-02 13:22:20
【问题描述】:

我是一个 SQL 菜鸟,我一直在尝试仅在表存在时选择数据,如果不存在则不选择任何数据。我查看了各种解决方案,这是我能想到的最好的解决方案:

DO $$                  
    BEGIN 
        IF EXISTS
            ( SELECT 1
              FROM   information_schema.tables 
              WHERE  table_schema = 'public'
              AND    table_name = "Test_Table"
            )
        THEN
            SELECT
              test_col
            FROM "Test_Table"
            ORDER BY time ASC
        END IF ;
    END
$$ ;

但这给出了:

ERROR:  syntax error at or near "END"
LINE 14:         END IF ;

注意表名可能包含大写字符,所以我认为双引号是必要的。

有什么想法吗?也许尝试捕获异常会是更好的方法?

谢谢!

【问题讨论】:

  • 完全不清楚您要做什么。你知道select into 创建一个而不是一个列的值吗?

标签: sql database postgresql psql postgresql-12


【解决方案1】:
DO $$                  
    BEGIN 
        IF EXISTS
            ( SELECT 1
              FROM   information_schema.tables 
              WHERE  table_schema = 'public'
              AND    table_name = 'Test_Table' -- use single quotes, it's value
            )
        THEN
            SELECT
              test_col
            FROM "Test_Table" -- advice: never use Upper case and you don't need double quotes
            ORDER BY time ASC; -- use a ; at the end of the query
        END IF ;
    END
$$ ;

【讨论】:

  • 感谢您的建议! ; 确实修复了语法错误,如果表不存在,查询将按需要工作。但是,如果该表确实存在,我会得到:ERROR: query has no destination for result data HINT: If you want to discard the results of a SELECT, use PERFORM instead. CONTEXT: PL/pgSQL function inline_code_block line 10 at SQL statement,而不是像我习惯的那样看到返回的结果。关于如何实际获取这些行的任何想法?
【解决方案2】:

您的块中有 2 个问题,都涉及 select 语句:

  1. select 语句没有所需的终止符 分号 (;)
  2. 由于选择位于 DO 块中,因此需要 INTO 子句 已选择列。

试试:

DO $$  
    declare 
       l_test_col "Test_Table".test_col%type = 'Nothing selected: table does not exist.'                
    BEGIN 
        IF EXISTS
            ( SELECT 1
              FROM   information_schema.tables 
              WHERE  table_schema = 'public'
              AND    table_name = "Test_Table"
            )
        THEN
            SELECT
              test_col
             into l_test_col
            FROM "Test_Table"
            ORDER BY time ASC
        END IF ;
        
        rise notice 'Result: %',l_test_col;  
    END
$$ ;

以上内容仅限于“Test_Table”,如果确实存在,则恰好包含 1 行。

【讨论】:

  • 当表不存在时,这将不起作用:l_test_col依赖于该表的存在。
  • @FrankHeikens:哎呀。是的,选择本身也是如此。猜测来自从不在过程中创建表。你只是忘记了这样的小事!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多