使用 Snowflake Scripting 的 Snowflake 存储过程 - 遍历结果并使用结果更改用户
Snowflake stored procedure using Snowflake Scripting - Iterate through result and ALTER USER with result
我正在尝试创建一个 stored procedure with Snowflake Scripting 专门用于查询用户 table,然后遍历结果并更改这些用户。
这是我目前的情况:
create or replace procedure TEST_PROCEDURE()
returns varchar
language sql
as
$$
declare
c1 CURSOR for SELECT 'USERNAME@EMAIL.COM' AS NAME;
user_name varchar;
begin
for record in c1 do
user_name := record.name;
ALTER USER user_name SET DEFAULT_ROLE = 'REPORTER', DEFAULT_WAREHOUSE = 'REPORTING_WH_L';
end for;
return user_name;
end;
$$
;
当我 运行 存储过程时,出现以下错误:
Uncaught exception of type 'STATEMENT_ERROR' on line 8 at position 9: SQL compilation error: User 'USER_NAME' does not exist or not authorized.
我更改了 USERNAME@EMAIL.COM
只是为了这个问题它正在查询 table 并返回有效的 Snowflake 用户名。
查询历史显示,在 ALTER USER
命令中,它没有用游标的结果替换 user_name。
关于如何解决这个问题有什么想法吗?
查看帮助的 using variables 部分,在使用循环变量的示例中,变量名称在 SQL
中大写
insert into names (v) values (:PV_NAME);
虽然“脚本”部分是小写,但它的前缀也是 :
create procedure duplicate_name(pv_name varchar)
returns varchar
language sql
as
$$
begin
declare
pv_name varchar;
begin
pv_name := 'middle block variable';
declare
pv_name varchar;
begin
pv_name := 'innermost block variable';
insert into names (v) values (:PV_NAME);
end;
-- Because the innermost and middle blocks have separate variables
-- named "pv_name", the INSERT below inserts the value
-- 'middle block variable'.
insert into names (v) values (:PV_NAME);
end;
-- This inserts the value of the input parameter.
insert into names (v) values (:PV_NAME);
return 'Completed.';
end;
$$
;
使用EXECUTE IMMEDIATE
:
create or replace procedure TEST_PROCEDURE()
returns varchar
language sql
as
$$
declare
c1 CURSOR for SELECT '"USERNAME@EMAIL.COM"' AS NAME;
SQL STRING;
begin
for record in c1 do
SQL := 'ALTER USER '|| record.name || ' SET DEFAULT_ROLE = ''REPORTER'', DEFAULT_WAREHOUSE = ''REPORTING_WH_L''';
EXECUTE IMMEDIATE :SQL;
end for;
return :SQL;
end;
$$;
CALL TEST_PROCEDURE();
-- ALTER USER "USERNAME@EMAIL.COM" SET DEFAULT_ROLE = 'REPORTER', DEFAULT_WAREHOUSE = 'REPORTING_WH_L'
您需要使用 IDENTIFIER 并在 user_name 变量前添加冒号。
所以从
ALTER USER user_name
SET DEFAULT_ROLE = 'REPORTER',
DEFAULT_WAREHOUSE = 'REPORTING_WH_L';
至
ALTER USER IDENTIFIER(:user_name)
SET DEFAULT_ROLE = 'REPORTER',
DEFAULT_WAREHOUSE = 'REPORTING_WH_L';
我已经测试过了,它对我有用。
我正在尝试创建一个 stored procedure with Snowflake Scripting 专门用于查询用户 table,然后遍历结果并更改这些用户。
这是我目前的情况:
create or replace procedure TEST_PROCEDURE()
returns varchar
language sql
as
$$
declare
c1 CURSOR for SELECT 'USERNAME@EMAIL.COM' AS NAME;
user_name varchar;
begin
for record in c1 do
user_name := record.name;
ALTER USER user_name SET DEFAULT_ROLE = 'REPORTER', DEFAULT_WAREHOUSE = 'REPORTING_WH_L';
end for;
return user_name;
end;
$$
;
当我 运行 存储过程时,出现以下错误:
Uncaught exception of type 'STATEMENT_ERROR' on line 8 at position 9: SQL compilation error: User 'USER_NAME' does not exist or not authorized.
我更改了 USERNAME@EMAIL.COM
只是为了这个问题它正在查询 table 并返回有效的 Snowflake 用户名。
查询历史显示,在 ALTER USER
命令中,它没有用游标的结果替换 user_name。
关于如何解决这个问题有什么想法吗?
查看帮助的 using variables 部分,在使用循环变量的示例中,变量名称在 SQL
中大写insert into names (v) values (:PV_NAME);
虽然“脚本”部分是小写,但它的前缀也是 :
create procedure duplicate_name(pv_name varchar)
returns varchar
language sql
as
$$
begin
declare
pv_name varchar;
begin
pv_name := 'middle block variable';
declare
pv_name varchar;
begin
pv_name := 'innermost block variable';
insert into names (v) values (:PV_NAME);
end;
-- Because the innermost and middle blocks have separate variables
-- named "pv_name", the INSERT below inserts the value
-- 'middle block variable'.
insert into names (v) values (:PV_NAME);
end;
-- This inserts the value of the input parameter.
insert into names (v) values (:PV_NAME);
return 'Completed.';
end;
$$
;
使用EXECUTE IMMEDIATE
:
create or replace procedure TEST_PROCEDURE()
returns varchar
language sql
as
$$
declare
c1 CURSOR for SELECT '"USERNAME@EMAIL.COM"' AS NAME;
SQL STRING;
begin
for record in c1 do
SQL := 'ALTER USER '|| record.name || ' SET DEFAULT_ROLE = ''REPORTER'', DEFAULT_WAREHOUSE = ''REPORTING_WH_L''';
EXECUTE IMMEDIATE :SQL;
end for;
return :SQL;
end;
$$;
CALL TEST_PROCEDURE();
-- ALTER USER "USERNAME@EMAIL.COM" SET DEFAULT_ROLE = 'REPORTER', DEFAULT_WAREHOUSE = 'REPORTING_WH_L'
您需要使用 IDENTIFIER 并在 user_name 变量前添加冒号。
所以从
ALTER USER user_name
SET DEFAULT_ROLE = 'REPORTER',
DEFAULT_WAREHOUSE = 'REPORTING_WH_L';
至
ALTER USER IDENTIFIER(:user_name)
SET DEFAULT_ROLE = 'REPORTER',
DEFAULT_WAREHOUSE = 'REPORTING_WH_L';
我已经测试过了,它对我有用。