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

k7fdbhmy  于 2023-10-23  发布在  SQLite
关注(0)|答案(1)|浏览(160)

我试图从数据库中的表中检索列信息,但我首先要检查以确保该表存在。单独运行SELECT s可以正常工作,但是当我尝试将它们合并组合到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;

我假设我的问题是缺乏数据库名称,但我不知道该使用什么数据库名称。我试着在PRAGMA_table_info前面使用main,但我得到了同样的错误。我试过有无括号。我也试过[dbo]
我试着寻找我的答案,但我失败了。其他类似的问题有更明显的问题,例如在连接字符串时缺少空格,忘记关闭IF等。
如果有问题,我使用DBeaver 23.2.1。
任何帮助将不胜感激。

z18hc3ub

z18hc3ub1#

我相信你需要的只是

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

如果表或列不存在,则输出将是1行或没有行。
但我不知道使用什么数据库名称
该错误消息告知您2个潜在原因:

  1. SQL错误,
    1.缺少数据库
    问题是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,可能是一个值列表)。
    实际上,您需要多个值(所有列或您所说的 * 列信息 *),因此建议使用。
    作为演示,它显示了CASE....构造的两个示例,其中;
    1.表和列存在,并且
    1.其中表不存在,结果为“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行或没有行)。

  • 请注意,类型不是列的类型亲和性,而是根据列定义的实际类型(因此类型定义为whateverblah

相关问题