查询sqlite_master时出现SQL错误或缺少THEN附近的数据库

问题描述 投票:0回答:1

我正在尝试从数据库中的表中检索列信息,但我首先检查以确保该表存在。单独运行

SELECT
效果很好,但是当我尝试将它们组合到
IF
结构中时,出现以下错误:

SQL 错误[1]:[SQLITE_ERROR] SQL 错误或丢失数据库(“THEN”附近:语法错误)

这是我的 SQL:

IF EXISTS(
    SELECT
        [name]
    FROM
        [main].[sqlite_master]
    WHERE
        [type] = 'table'
    AND
        [name] = 'myTableName'
)

THEN
    SELECT
        *
    FROM
        PRAGMA_table_info('myTableName')
    WHERE
        [name] = 'myColumnName';
        
END;

我假设我的问题是缺少数据库名称,但我不明白要使用什么数据库名称。我尝试在

main
前面使用
PRAGMA_table_info
,但出现了同样的错误。我尝试过带括号和不带括号。我也试过
[dbo]

我曾尝试寻找答案,但惨遭失败。其他类似的问题有更明显的问题,例如连接字符串时缺少空格、忘记关闭

IF
等。

如果重要的话,我正在使用 DBeaver 23.2.1。

任何帮助将不胜感激。

sql database sqlite
1个回答
0
投票

我相信你所需要的就是

SELECT * FROM PRAGMA_table_info('myTableName') WHERE name = 'myColumnName';

如果表或列不存在,则输出将为 1 行或无行。

但我不明白要使用什么数据库名称

错误消息告知您 2 个潜在原因:-

  1. SQL 错误,
  2. 缺少数据库

问题在于 SQLite 中没有

IF .... THEN .... ELSE .... END
构造,因此发现 THEN 时 SQL 存在问题。
IF EXISTS
是一个特定的用例。

IF .... THEN .... ELSE .... END
结构等效的是
CASE .... WHEN .... THEN .... ELSE .... END
结构;请参阅https://www.sqlite.org/lang_expr.html#the_case_expression

但是,该构造在等于单个值的表达式中使用(对于

IN
可能是值列表)。

您实际上需要多个值(所有列或您所说的列信息),因此是建议的。

作为演示,它显示了 a)

CASE....
构造的两个示例,其中;

  1. 表和列存在,并且
  2. 表不存在且结果为“OOOPS”

最后是建议的直接建议查询的几个示例(通过 UNION):-

DROP TABLE IF EXISTS x;
CREATE TABLE IF NOT EXISTS x (c1 'whatever', c2 'blah');
/* Example utilising CASE.... construct where table and column found */
SELECT
    CASE 
        WHEN EXISTS(
            SELECT * FROM [main].sqlite_master WHERE [type] = 'table' AND name = 'x'
        )
            THEN (SELECT [name]   FROM PRAGMA_table_info('x') WHERE [name] = 'c1')
        ELSE 'OOOPS'
    END
;
/* Same example BUT for a rouge table i.e. works but returns OOOPS */
SELECT
    CASE 
        WHEN EXISTS(
            SELECT * FROM [main].sqlite_master WHERE [type] = 'table' AND name = 'y'
        )
            THEN (SELECT [name]   FROM PRAGMA_table_info('y') WHERE [name] = 'c1')
        ELSE 'OOOPS'
    END
;
/* Multiple unioned suggested */
SELECT
    /* 1. table and column exists = ALL GOOD */
    'attempt1',* FROM PRAGMA_table_info('x') WHERE name = 'c1' 
    /* 2. OUCH table z DOES NOT EXIST */
    UNION ALL SELECT 'attempt2',* FROM PRAGMA_table_info('z') WHERE name = 'obviously_not+a_name_as_table_does_not_exist'
    /* 3. table x does exists but OUCH column does not */
    UNION ALL SELECT 'attempt3',* FROM PRAGMA_table_info('x') WHERE name = 'obviously_not+a_name_as_table_does_not_exist'
    /* 4. OUCH table c1 does not exist*/
    UNION ALL SELECT 'attempt4',* FROM PRAGMA_table_info('c1') WHERE name LIKE '%2'
    /* 5. ALL GOOD table exists and so does a column c2 (column named abcdefghi2, if it existed would also match  LIKE ) */
    UNION ALL SELECT 'attempt5',* FROM PRAGMA_table_info('x') WHERE name LIKE '%2' AND type LIKE 'b%'
;
DROP TABLE IF EXISTS x;

第一个结果(CASE WHEN):-

  • 注意只能提取单个值(从表达式 SELECT * 返回将导致
    sub-select returns 6 columns - expected 1

第二个结果(CASE ELSE):-

第三个结果:-

  • 注意到 UNION 纯粹是为了区分尝试和结果

因此,根据注释,尝试 1 和 5 各返回一行(其中添加了尝试以指示哪个返回结果)。尝试 2,3 和 4 没有返回任何结果。因此只有两行输出(在您的情况下,您会期望 1 行或没有行)。

  • 请注意,类型不是列的类型关联,而是列定义中的实际类型(因此类型定义为
    whatever
    blah
© www.soinside.com 2019 - 2024. All rights reserved.