Snowflake 存储过程中出现循环错误

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

我在雪花中有一个过程,它通过克隆数据库来创建数据库的备份。 此过程存在一个问题,因为它还将屏蔽策略和行策略从参考数据库克隆到克隆数据库。

我正在尝试向此过程添加一个循环,该循环将删除克隆数据库的行策略和屏蔽策略,但我遇到了一些问题:

我遇到的两个问题是:

  1. 我不确定雪花中循环游标的语法
  2. 我收到错误 “错误:创建备份 ZZ_BKP_STEWARDSHIP_20240531_1440522049:SQL 编译错误:位置 46 处的错误行 1 绑定变量:v_clone_db_name 未设置。”

以下是该过程的代码:

CREATE OR REPLACE PROCEDURE DBMGT.DBADMIN.XXtest_SNF_DB_BACKUP("P_SOURCE_DB_NAME" VARCHAR(16777216))
RETURNS VARCHAR(16777216)
LANGUAGE SQL
EXECUTE AS CALLER
AS '
DECLARE
    v_clone_db_name VARCHAR;
    v_sql VARCHAR;
    v_sql_loop VARCHAR;
    
    
    c1 CURSOR FOR SELECT ''ALTER ''|| REF_ENTITY_DOMAIN || '' '' || :v_clone_db_name || ''.'' ||REF_SCHEMA_NAME||''.''||REF_ENTITY_NAME||''  modify column ''||ref_column_name|| '' unset masking policy;'' AS sql_stmt from  SNOWFLAKE.ACCOUNT_USAGE.POLICY_REFERENCES where ref_database_name= upper(:p_source_db_name) ;



    
    c2 CURSOR FOR SELECT ''ALTER ''||REF_ENTITY_DOMAIN|| '' '' || :v_clone_db_name ||  ''.''||REF_SCHEMA_NAME||''.''||REF_ENTITY_NAME|| '' DROP ALL ROW ACCESS POLICIES;'' AS sql_stmt from  SNOWFLAKE.ACCOUNT_USAGE.POLICY_REFERENCES where ref_database_name= upper(:p_source_db_name) and ref_column_name is null;

    
BEGIN
    -- Check if the source database exists
    IF (NOT EXISTS (
        SELECT 1
        FROM "SNOWFLAKE"."INFORMATION_SCHEMA"."DATABASES"
        WHERE DATABASE_NAME = upper(:p_source_db_name)
    ) )THEN
        RETURN ''Source database does not exist'';
    END IF;

    -- Generate a unique clone database name with timestamp as prefix and ''_BKP'' as suffix
    v_clone_db_name := ''ZZ_BKP_'' || P_SOURCE_DB_NAME || ''_'' || TO_CHAR(CURRENT_TIMESTAMP(), ''YYYYMMDD_HH24MISS'');
    
    -- Create the SQL statement to clone the database
    v_sql := ''CREATE DATABASE "'' || v_clone_db_name || ''" CLONE "'' || P_SOURCE_DB_NAME || ''"''; 

    EXECUTE IMMEDIATE v_sql;



    OPEN c1;

    
    --Execute the output of the following to drop masking pols

    FOR row_variable IN c1 DO
    v_sql_loop := (row_variable.value);
    EXECUTE IMMEDIATE v_sql_loop;
    END FOR;

    CLOSE c1;


   OPEN c2;

    
    --Execute the output of the following to drop masking pols
     
     FOR row_variable IN c2 DO
    v_sql_loop := (row_variable.value);
    EXECUTE IMMEDIATE v_sql_loop;
    END FOR;

    ClOSE c2;
    
    
    

    -- Log the backup status
    INSERT INTO DBMGT.DBADMIN.XXX_BKP_DBLOGS (LOG_MESSAGE, action, status)
    VALUES (''created backup '' || :v_clone_db_name, ''Backup'',''Success'');

    RETURN ''Backup successful'';
    
            
    exception when other then
    LET LINE := SQLCODE || '': '' || SQLERRM;


INSERT INTO DBMGT.DBADMIN.XXX_BKP_DBLOGS (LOG_MESSAGE, action, status)
    VALUES (''Error: creating backup '' || :v_clone_db_name || :LINE , ''Backup'',''Failed'');

    
     RETURN ''Backup unsuccessful'';
     
             
END;
';

我最不确定如何声明游标和变量,以及如何循环游标(从“打开 c1”到“关闭 c2”)

非常感谢任何帮助我找到正确方向的帮助:)

我已经尝试了上述方法,使用雪花文档作为定义游标并循环遍历它们以执行删除屏蔽策略和行策略的指南。

在尝试删除屏蔽策略和行策略之前,代码的所有其他部分都正常工作(即,我只在与游标 c1 和 c2 相关的代码部分中出现错误)

snowflake-cloud-data-platform sql-scripts
1个回答
0
投票

您只需要在执行 SQL 语句(如代码末尾的 INSERT 语句)时使用绑定变量语法(变量名称前面的冒号)。它们位于字符串中,就像在游标定义中一样,您只需使用变量名称,没有冒号

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.