代码之家  ›  专栏  ›  技术社区  ›  er0

将表名作为参数的大型查询存储过程错误

  •  0
  • er0  · 技术社区  · 4 年前

    我有一个存储过程,如下所示:

    CREATE OR REPLACE PROCEDURE `myapp.dataset.count_data`(table_name STRING, start_date DATE)
    BEGIN
      CREATE TEMP TABLE distinct_values AS (
        SELECT *, LAST_VALUE(v ignore NULLS) OVER(ORDER BY id) as last_v FROM `"||table_name||"`
      );
    ...
    

    但当我调用它时,我会得到错误, Invalid value: Table ""||table_name||"" must be qualified with a dataset (e.g. dataset.table).

    我按如下方式调用该过程,并在调用中限定表名:

    CALL `myapp.dataset.compute_stats`(
      'myapp.dataset.first_sampling',
      DATE(2021,1,1)
    )
    

    将表名作为参数传递的正确语法是什么?

    0 回复  |  直到 4 年前
        1
  •  2
  •   Nestor    4 年前

    由于@jaytiger提到的表名不能参数化,请考虑下面的查询,因为我使用execute immediate来动态运行查询。

    CREATE OR REPLACE PROCEDURE `myProject.myDataset.myProcedure`(table_name STRING, start_date DATE)
    BEGIN
    DECLARE table_name STRING DEFAULT NULL;
    SET table_name = `table_name`;
    EXECUTE IMMEDIATE format("""
      CREATE TEMP TABLE distinct_values AS (
        SELECT *, LAST_VALUE(v ignore NULLS) OVER(ORDER BY id) as last_v FROM %s
      );
    """, table_name);
    END
    

    我试着唤起下面的程序:

    DECLARE table_name STRING DEFAULT NULL;
    DECLARE start_date DATE DEFAULT NULL;
    set table_name = "myDataset.SampleTable";
    CALL `myProject.myDataset.myProcedure`(table_name, start_date);
    

    我成功地调用了该过程(我的示例表是空的,所以它不会显示任何数据。) enter image description here