Google bigquery 我可以在表名中使用查询参数吗?

Google bigquery 我可以在表名中使用查询参数吗?,google-bigquery,Google Bigquery,我想做以下几点: SELECT some_things FROM `myproject.mydataset.mytable_@suffix` 但这不起作用,因为参数没有在表名中展开 这是可行的,使用: 但是,它也存在一些问题: 如果我输入了错误的参数,这个查询将自动返回零行,而不是大声地对我吼叫 使用通配符进行查询时,查询缓存停止工作 如果存在前缀为mytable\uuu的其他表,则它们必须具有相同的架构,即使它们与后缀不匹配。否则,奇怪的事情就会发生。看起来BigQuery要么计算所有列的

我想做以下几点:

SELECT some_things
FROM `myproject.mydataset.mytable_@suffix`
但这不起作用,因为参数没有在表名中展开

这是可行的,使用:

但是,它也存在一些问题:

  • 如果我输入了错误的参数,这个查询将自动返回零行,而不是大声地对我吼叫

  • 使用通配符进行查询时,查询缓存停止工作

  • 如果存在前缀为
    mytable\uuu
    的其他表,则它们必须具有相同的架构,即使它们与后缀不匹配。否则,奇怪的事情就会发生。看起来BigQuery要么计算所有列的并集,要么采用任意表的模式;它没有文档记录,我也没有详细查看它


是否有更好的方法查询名称取决于查询参数的单个表?

为了回答您所述的问题:

  • 表扫描发生在FROM子句中,WHERE子句发生在筛选[]中,因此,如果WHERE条件不匹配,将返回空结果

  • 当前,使用通配符“[]查询时不支持缓存结果

  • “BigQuery将与通配符匹配的最近创建的表的架构用作架构”[]。在您的用例中,您遇到了什么样的奇怪情况?“通配符表表示与通配符表达式”[]匹配的所有表的并集


  • 在BigQuery中,可以运行参数化查询,但不能参数化表名[]。您的通配符解决方案似乎是唯一的方法

    如果您使用的是Python API,那么实际上可以使用表作为参数,但是还没有文档记录。如果通过格式化的文本字符串与docstring将表作为参数传递,则查询应该可以工作

    SQL示例:

    sql = "SELECT max(_last_updt) FROM `{0}.{1}.{2}` WHERE _last_updt >= TIMESTAMP(" +
        "CURRENT_DATE('-06:00'))".format(project_id, dataset_name, table_name)
    
    bigquery_client = bigquery.Client() #setup the client
    query_job = bigquery_client.query(sql) #run the query
    results = query_job.result() # waits for job to complete
    for row in results:
        print row
    
    Python API上下文中的SQL:

    sql = "SELECT max(_last_updt) FROM `{0}.{1}.{2}` WHERE _last_updt >= TIMESTAMP(" +
        "CURRENT_DATE('-06:00'))".format(project_id, dataset_name, table_name)
    
    bigquery_client = bigquery.Client() #setup the client
    query_job = bigquery_client.query(sql) #run the query
    results = query_job.result() # waits for job to complete
    for row in results:
        print row
    

    是的,您可以,下面是一个工作示例:

    DECLARE tablename STRING;
    DECLARE tableQuery STRING;
    
    ##get list of tables
    CREATE TEMP TABLE tableNames as select table_name from nomo_nausea.INFORMATION_SCHEMA.TABLES where table_name not in ('_sdc_primary_keys', '_sdc_rejected', 'fba_all_order_report_data');
    
    WHILE (select count(*) from tableNames) >= 1 DO
      SET tablename = (select table_name from tableNames LIMIT 1);
      ##build dataset + table name
      SET tableQuery = CONCAT('nomo_nausea.' , tablename);
      ##use concat to build string and execute
      EXECUTE IMMEDIATE CONCAT('SELECT * from `', tableQuery, '` where _sdc_deleted_at is not null');
      DELETE FROM tableNames where table_name = tablename;
    END WHILE;
    

    “奇怪的东西”是尚未传播到所有表的模式更改。例如,
    mytable_2017
    有旧模式,
    mytable_2018
    有新模式;现在你不能再可靠地使用通配符结构了。但是,是的,你的结论性回答了我的问题:“参数不能用作标识符、列名、表名或查询的其他部分的替代品。”我怀疑你所做的让sql注入攻击的可能性成为可能,因为format函数只是执行字符串操作,而没有SQL查询的适当参数化逻辑。这只是字符串格式。与BigQuery API无关,您可以从
    psycopg2
    的sql Formatter中借用这一伟大的答案!2019年11月,在我写了这个问题一年多之后,BigQuery就开始使用脚本了,但现在它是一个很好的解决方案。