Sql 使用Snowflake函数的输入作为From子句

Sql 使用Snowflake函数的输入作为From子句,sql,function,snowflake-cloud-data-platform,sql-function,Sql,Function,Snowflake Cloud Data Platform,Sql Function,我有一个函数,它接受一个输入列表来起草一个查询,它是动态SQL,但并不复杂,输入直接传递到from和select子句。在Snowflake中,我无法让它允许我使用输入的名称作为表名。我尝试使用标识符函数,但仍然没有成功。如果有人有任何想法,这里是函数 CREATE OR REPLACE FUNCTION aggregate_string (p_table_name VARCHAR ,p_column_name VARCHAR ,p_where_column_name VARCHAR ,p_whe

我有一个函数,它接受一个输入列表来起草一个查询,它是动态SQL,但并不复杂,输入直接传递到from和select子句。在Snowflake中,我无法让它允许我使用输入的名称作为表名。我尝试使用
标识符
函数,但仍然没有成功。如果有人有任何想法,这里是函数

CREATE OR REPLACE FUNCTION aggregate_string
(p_table_name VARCHAR
,p_column_name VARCHAR
,p_where_column_name VARCHAR
,p_where_value VARCHAR
,p_order_by_YN VARCHAR
,p_order_by_column VARCHAR
)

RETURNS VARCHAR

AS

$$

SELECT
    CASE 
        WHEN TRIM(upper(p_order_by_YN)) = 'Y' AND trim(p_order_by_column)> ' ' 
    THEN (SELECT as_array(p_column_name) from p_table_name where p_where_column_name = p_where_value order by p_order_by_column)
    ELSE (SELECT as_array(p_column_name) from p_table_name where p_where_column_name = p_where_value)
END AS V_CUR


$$
;

虽然文档没有显式地调用它,但我认为UDF不可能使用动态表名。但是,应该可以使用,它允许“动态创建SQL语句并执行它”

有关这方面的一个好例子,请参见(复制如下):

创建存储过程。此过程允许您通过 表的名称,并获取该表中的行数(等效) 要从表名称中选择计数(*):

调用存储过程:

call get_row_count('stproc_test_table1');
+---------------+
| GET_ROW_COUNT |
|---------------|
|             3 |
+---------------+
显示同一表格的select count(*)结果:

SELECT COUNT(*) FROM stproc_test_table1;
+----------+
| COUNT(*) |
|----------|
|        3 |
+----------+

请务必理解,使用该过程的结果将与函数略有不同,请参见

尽管文档没有明确地调用此函数,但我认为UDF不可能使用动态表名。但是,应该可以使用,它允许“动态创建SQL语句并执行它”

有关这方面的一个好例子,请参见(复制如下):

创建存储过程。此过程允许您通过 表的名称,并获取该表中的行数(等效) 要从表名称中选择计数(*):

调用存储过程:

call get_row_count('stproc_test_table1');
+---------------+
| GET_ROW_COUNT |
|---------------|
|             3 |
+---------------+
显示同一表格的select count(*)结果:

SELECT COUNT(*) FROM stproc_test_table1;
+----------+
| COUNT(*) |
|----------|
|        3 |
+----------+

请务必理解,使用过程的结果与函数略有不同,请参见

如果我理解正确,函数将从提供的输入生成SQL语句。如果是这种情况,可以使用JavaScript UDF执行此操作:

CREATE OR REPLACE FUNCTION aggregate_string
    (p_table_name VARCHAR
    ,p_column_name VARCHAR
    ,p_where_column_name VARCHAR
    ,p_where_value VARCHAR
    ,p_order_by_YN VARCHAR
    ,p_order_by_column VARCHAR
    )
    RETURNS VARCHAR
    LANGUAGE JAVASCRIPT
    AS
    $$
        var sql = "select " + P_COLUMN_NAME + " from " + P_TABLE_NAME + " where " + P_WHERE_COLUMN_NAME + " = ";

        if (isNaN(P_WHERE_VALUE)) {
            sql += "'" + P_WHERE_VALUE.replace(/'/g, "''") + "'";
        } else {
            sql += P_WHERE_VALUE;
        }

        if (P_ORDER_BY_YN.toUpperCase() == 'Y') {
            sql += " order by " + P_ORDER_BY_COLUMN;
        }

        return sql;

    $$
    ;

    -- Where is not a number, so the where condition is single quoted
    select aggregate_string('TABLE_NAME1', 'COL1, COL2, COL3', 'WHERE_COLUMN1', 'WHERE_VALUE', 'Y', 'ORDER_BY_COL1');

    -- Where is a number (whether or not passed in single quotes), so the where condition is not quoted.
    select aggregate_string('TABLE_NAME1', 'COL1, COL2, COL3', 'WHERE_COLUMN1', 5, 'Y', 'ORDER_BY_COL1');

    -- Order by is NO, so there is no order by clause
    select aggregate_string('TABLE_NAME1', 'COL1, COL2, COL3', 'WHERE_COLUMN1', 'WHERE_VALUE', 'N', '');

如果我理解正确,该函数将根据提供的输入生成SQL语句。如果是这种情况,可以使用JavaScript UDF执行此操作:

CREATE OR REPLACE FUNCTION aggregate_string
    (p_table_name VARCHAR
    ,p_column_name VARCHAR
    ,p_where_column_name VARCHAR
    ,p_where_value VARCHAR
    ,p_order_by_YN VARCHAR
    ,p_order_by_column VARCHAR
    )
    RETURNS VARCHAR
    LANGUAGE JAVASCRIPT
    AS
    $$
        var sql = "select " + P_COLUMN_NAME + " from " + P_TABLE_NAME + " where " + P_WHERE_COLUMN_NAME + " = ";

        if (isNaN(P_WHERE_VALUE)) {
            sql += "'" + P_WHERE_VALUE.replace(/'/g, "''") + "'";
        } else {
            sql += P_WHERE_VALUE;
        }

        if (P_ORDER_BY_YN.toUpperCase() == 'Y') {
            sql += " order by " + P_ORDER_BY_COLUMN;
        }

        return sql;

    $$
    ;

    -- Where is not a number, so the where condition is single quoted
    select aggregate_string('TABLE_NAME1', 'COL1, COL2, COL3', 'WHERE_COLUMN1', 'WHERE_VALUE', 'Y', 'ORDER_BY_COL1');

    -- Where is a number (whether or not passed in single quotes), so the where condition is not quoted.
    select aggregate_string('TABLE_NAME1', 'COL1, COL2, COL3', 'WHERE_COLUMN1', 5, 'Y', 'ORDER_BY_COL1');

    -- Order by is NO, so there is no order by clause
    select aggregate_string('TABLE_NAME1', 'COL1, COL2, COL3', 'WHERE_COLUMN1', 'WHERE_VALUE', 'N', '');

非常感谢您深思熟虑的回复-这只返回SQL语句,尽管正确吗?这实际上并不执行SQL语句?如果我理解执行生成的语句的关键问题,我需要使用存储过程,因为UDF不支持动态sql?是的,UDF示例将只生成该语句。我不确定你是想要这一代人还是执行它。当前,要在UDF中运行SQL,它必须是SQL UDF。JavaScript SP中上下文中的“雪花”对象不在JavaScript UDF中的上下文中。我会看看是否有一种方法可以使用SQL生成和执行,然后再回复给您。非常感谢您深思熟虑的回复-这只会返回SQL语句,尽管正确吗?这实际上并不执行SQL语句?如果我理解执行生成的语句的关键问题,我需要使用存储过程,因为UDF不支持动态sql?是的,UDF示例将只生成该语句。我不确定你是想要这一代人还是执行它。当前,要在UDF中运行SQL,它必须是SQL UDF。JavaScript SP中上下文中的“雪花”对象不在JavaScript UDF中的上下文中。我将看看是否有一种方法可以使用SQL生成和执行,然后返回给您。