Procedimentos armazenados com direitos do chamador e direitos do proprietário¶
Um procedimento armazenado é executado com os direitos do chamador ou com os direitos do proprietário. Ele não consegue ser executado com ambos ao mesmo tempo. Este tópico descreve as diferenças entre um procedimento armazenado de direitos do chamador e um procedimento armazenado de direitos do proprietário.
Neste tópico:
Introdução¶
O procedimento armazenado de direitos do chamador é executado com os privilégios do chamador. A principal vantagem do procedimento armazenado de direitos do chamador é que ele pode acessar informações sobre o chamador ou sobre a sessão atual do chamador. Por exemplo, um procedimento armazenado de direitos do chamador pode ler as variáveis da sessão do chamador e utilizá-las em uma consulta.
Um procedimento armazenado de direitos do proprietário é executado principalmente com os privilégios do proprietário do procedimento armazenado. A principal vantagem do procedimento armazenado de direitos do proprietário é que o proprietário pode delegar tarefas administrativas específicas, como a limpeza de dados antigos, a outra função sem conceder a essa função privilégios mais gerais, como privilégios para excluir todos os dados de uma tabela específica.
No momento em que o procedimento armazenado é criado, o criador especifica se o procedimento é executado com os direitos do proprietário ou com os direitos do chamador. A configuração padrão é direitos do proprietário.
O proprietário pode mudar o procedimento de um procedimento armazenado de direitos do proprietário para um procedimento armazenado de direitos do chamador (ou vice-versa), executando um comando ALTER PROCEDURE.
Privilégios em relação a objetos de banco de dados¶
Um procedimento armazenado de direitos do chamador é executado com os privilégios do banco de dados da função que chamou o procedimento armazenado. Qualquer instrução que o chamador não poderia executar fora do procedimento armazenado também não pode ser executada dentro do procedimento armazenado. Por exemplo, se a função denominada “Nurse” não tiver privilégios para excluir linhas da tabela medical_records
, isso significa que se um usuário com a função “Nurse” chamar um procedimento armazenado de direitos do chamador que tenta excluir linhas dessa tabela, o procedimento armazenado falhará.
Um procedimento de direitos do proprietário funciona com os direitos do proprietário do procedimento. Isso significa que se o proprietário tem privilégios para realizar uma tarefa, então o procedimento armazenado pode realizar essa tarefa mesmo quando chamado por uma função que não tem privilégios para realizar essa tarefa diretamente. Por exemplo, se a função denominada “Doctor” tem os privilégios do banco de dados para excluir linhas da tabela medical_records
, e a função “Doctor” cria um procedimento armazenado que exclui linhas anteriores a 7 anos daquela tabela, isso significa que se a função “Doctor” concede à função “Nurse” privilégios apropriados no procedimento armazenado, então a função “Nurse” pode executar o procedimento armazenado (e excluir linhas antigas da tabela usando aquele procedimento armazenado), mesmo que a função “Nurse” não tenha privilégios de exclusão na tabela.
Dica
Se você precisar de um procedimento armazenado de direitos de proprietário para executar ações em uma tabela, exibição ou função que o chamador tenha privilégios para acessar, você pode fazer com que o chamador transmita uma referência a essa tabela, exibição ou função.
Para obter mais detalhes, consulte Como passar referências de tabelas, exibições, funções e consultas para procedimentos armazenados.
Acesso e configuração do estado da sessão¶
Da mesma forma que acontece com outras instruções SQL, uma instrução CALL
é executada dentro de uma sessão e herda o contexto dessa sessão, como variáveis em nível de sessão, banco de dados atual etc. O contexto exato que o procedimento herda depende de se o procedimento armazenado é um procedimento armazenado de direitos do chamador ou um procedimento armazenado de direitos do proprietário.
Se um procedimento armazenado de direitos do chamador fizer alterações na sessão, essas alterações podem persistir após o final da CALL
. Os procedimentos armazenados de direitos do proprietário não podem alterar o estado da sessão.
Procedimentos armazenados de direitos do chamador¶
Os procedimentos armazenados de direitos do chamador obedecem às seguintes regras dentro de uma sessão:
São executados com os privilégios do chamador, não com os privilégios do proprietário.
Herdam o warehouse atual do chamador.
Utilizam o banco de dados e o esquema que o chamador está usando atualmente.
Podem ver, definir e remover definição das variáveis de sessão do chamador.
Podem ver, definir e remover definição dos parâmetros de sessão do chamador.
A seção abaixo fornece mais detalhes sobre como os procedimentos armazenados de direitos do chamador podem ler e escrever as variáveis em nível de sessão do chamador.
Variáveis de sessão para procedimentos de direitos do chamador¶
Suponha que o procedimento armazenado chamado MyProcedure
executa instruções SQL que leem e definem variáveis em nível de sessão. Neste exemplo, os detalhes dos comandos de ler e definir não são importantes, portanto, as instruções são representadas como pseudocódigo:
READ SESSION_VAR1
SET SESSION_VAR2
O procedimento armazenado fica semelhante ao seguinte pseudocódigo:
CREATE PROCEDURE MyProcedure()
...
$$
READ SESSION_VAR1;
SET SESSION_VAR2;
$$
;
Suponha que você execute a seguinte sequência de instruções na mesma sessão:
SET SESSION_VAR1 = 'some interesting value';
CALL MyProcedure();
SELECT *
FROM table1
WHERE column1 = $SESSION_VAR2;
Isto é equivalente a executar a seguinte sequência:
SET SESSION_VAR1 = 'some interesting value';
READ SESSION_VAR1;
SET SESSION_VAR2;
SELECT *
FROM table1
WHERE column1 = $SESSION_VAR2;
Em outras palavras:
O procedimento armazenado pode ver a variável que foi definida pelas instruções antes de o procedimento ser chamado.
As instruções após o procedimento armazenado podem ver a variável que foi definida dentro do procedimento.
Para um exemplo completo que não depende de pseudocódigo, consulte Como usar variáveis de sessão com procedimentos armazenados dos direitos do chamador e direitos do proprietário (neste tópico).
Em muitos procedimentos armazenados, você deve herdar informações de contexto, como o banco de dados atual e as variáveis atuais em nível de sessão.
Entretanto, em alguns casos, você pode querer que seu procedimento armazenado seja mais isolado. Por exemplo, se seu procedimento armazenado define uma variável em nível de sessão, você pode não querer que a variável em nível de sessão influencie futuras instruções fora do seu procedimento armazenado.
Para isolar melhor seu procedimento armazenado do resto de sua sessão:
Evite usar diretamente as variáveis em nível de sessão. Em vez disso, passe-as como parâmetros explícitos. Isso força o chamador a pensar exatamente em quais variáveis em nível de sessão o procedimento armazenado usará.
Limpe qualquer variável em nível de sessão que você definir dentro do procedimento armazenado (e use nomes que provavelmente não serão usados em outro lugar, para que você não limpe acidentalmente uma variável de sessão que existia antes da chamada de procedimento armazenado).
O seguinte procedimento armazenado utiliza o valor de uma variável de sessão ao recebê-la como parâmetro, não ao utilizar diretamente a variável de sessão:
SET Variable_1 = 49;
CREATE PROCEDURE sv_proc2(PARAMETER_1 FLOAT)
RETURNS VARCHAR
LANGUAGE JAVASCRIPT
AS
$$
var rs = snowflake.execute( {sqlText: "SELECT 2 * " + PARAMETER_1} );
rs.next();
var MyString = rs.getColumnValue(1);
return MyString;
$$
;
CALL sv_proc2($Variable_1);
O seguinte procedimento armazenado cria uma variável de sessão temporária com um nome incomum e limpa essa variável antes que o procedimento armazenado termine. Quando uma instrução após a chamada de procedimento tenta usar a variável de sessão que foi limpa, essa instrução falhará:
CREATE PROCEDURE sv_proc1()
RETURNS VARCHAR
LANGUAGE JAVASCRIPT
EXECUTE AS CALLER
AS
$$
var rs = snowflake.execute( {sqlText: "SET SESSION_VAR_ZYXW = 51"} );
var rs = snowflake.execute( {sqlText: "SELECT 2 * $SESSION_VAR_ZYXW"} );
rs.next();
var MyString = rs.getColumnValue(1);
rs = snowflake.execute( {sqlText: "UNSET SESSION_VAR_ZYXW"} );
return MyString;
$$
;
CALL sv_proc1();
-- This fails because SESSION_VAR_ZYXW is no longer defined.
SELECT $SESSION_VAR_ZYXW;
Nota
Se você programar na linguagem C (ou em linguagens similares como Java), observe que as variáveis de sessão que você define dentro de um procedimento armazenado não são como as variáveis locais em C que desaparecem quando uma função em C termina de executar. Isolar o procedimento armazenado do seu ambiente exige mais esforço em SQL do que em C.
Procedimentos armazenados de direitos do proprietário¶
Os procedimentos armazenados de direitos do proprietário obedecem às seguintes regras dentro de uma sessão:
São executados com os privilégios do proprietário, não com os privilégios do chamador.
Dica
Se você precisar de um procedimento armazenado de direitos de proprietário para executar ações em uma tabela, exibição ou função que o chamador tenha privilégios para acessar, você pode fazer com que o chamador transmita uma referência a essa tabela, exibição ou função.
Para obter mais detalhes, consulte Como passar referências de tabelas, exibições, funções e consultas para procedimentos armazenados.
Herdam o warehouse atual do chamador.
Utilizam o banco de dados e o esquema nos quais o procedimento armazenado está criado, não o banco de dados e o esquema que o chamador está usando atualmente.
Não conseguem acessar a maioria das informações específicas do chamador. Por exemplo:
Não podem ver, definir ou remover definição das variáveis de sessão do chamador.
Não é possível executar SHOW PARAMETERS para listar parâmetros.
Pode usar apenas um subconjunto de parâmetros de sessão definidos pelo chamador. Por exemplo, comandos SQL que retornam valores de data de saída podem usar o parâmetro DATE_OUTPUT_FORMAT que é definido para a sessão do chamador).
Para obter a lista desses parâmetros, consulte Efeitos dos parâmetros de sessão de um chamador sobre um procedimento de direitos do proprietário.
Não pode definir ou retirar a definição de qualquer um dos parâmetros de sessão do chamador.
Não podem consultar funções de tabela INFORMATION_SCHEMA (por exemplo, AUTOMATIC_CLUSTERING_HISTORY), que retornam resultados com base no usuário atual.
Não permitem que os não proprietários visualizem informações sobre o procedimento a partir da exibição PROCEDURES.
As restrições em relação às variáveis de sessão e parâmetros de sessão são descritas com mais detalhes abaixo.
Variáveis de sessão para procedimentos de direitos do proprietário¶
Um procedimento armazenado não tem acesso a Variáveis SQL criadas fora do procedimento armazenado. Essa restrição impede que um procedimento armazenado escrito ou de propriedade de um usuário leia variáveis SQL criadas por outro usuário (o chamador do procedimento armazenado).
Se seu procedimento armazenado precisa de valores que estão armazenados nas variáveis SQL da sessão atual, então os valores nessas variáveis devem ser passados como argumentos explícitos para o procedimento armazenado. Por exemplo:
SET PROVINCE = 'Manitoba';
CALL MyProcedure($PROVINCE);
Efeitos dos parâmetros de sessão de um chamador sobre um procedimento de direitos do proprietário¶
Nota
Esta seção não se aplica ao comando SHOW PARAMETERS. O comando SHOW PARAMETERS não é permitido em procedimentos armazenados de direitos do proprietário.
O valor de um parâmetro de sessão pode afetar o comportamento de comandos e funções. Por exemplo, comandos que retornam valores de data usam o formato especificado pelo parâmetro de sessão DATE_OUTPUT_FORMAT.
Em uma sessão de um chamador, o chamador pode definir ou anular um parâmetro de sessão. Em um procedimento armazenado de direitos de um chamador, os parâmetros de sessão podem afetar a execução de quaisquer consultas e expressões executadas dentro do procedimento. Por exemplo, o parâmetro TIMESTAMP_OUTPUT_FORMAT afeta o formato de saída de uma consulta filho como select current_timestamp::string
.
Entretanto, para um procedimento armazenado de direitos do proprietário, os valores da sessão do chamador são usados somente para os seguintes parâmetros:
AUTOCOMMIT
BINARY_INPUT_FORMAT
BINARY_OUTPUT_FORMAT
DATE_INPUT_FORMAT
DATE_OUTPUT_FORMAT
ENABLE_UNLOAD_PHYSICAL_TYPE_OPTIMIZATION
ERROR_ON_NONDETERMINISTIC_MERGE
ERROR_ON_NONDETERMINISTIC_UPDATE
JDBC_TREAT_DECIMAL_AS_INT
JSON_INDENT
LOCK_TIMEOUT
MAX_CONCURRENCY_LEVEL
ODBC_USE_CUSTOM_SQL_DATA_TYPES
PERIODIC_DATA_REKEYING
QUERY_TAG
QUERY_WAREHOUSE_NAME
ROWS_PER_RESULTSET
STATEMENT_QUEUED_TIMEOUT_IN_SECONDS
STATEMENT_TIMEOUT_IN_SECONDS
STRICT_JSON_OUTPUT
TIMESTAMP_DAY_IS_ALWAYS_24H
TIMESTAMP_INPUT_FORMAT
TIMESTAMP_LTZ_OUTPUT_FORMAT
TIMESTAMP_NTZ_OUTPUT_FORMAT
TIMESTAMP_OUTPUT_FORMAT
TIMESTAMP_TYPE_MAPPING
TIMESTAMP_TZ_OUTPUT_FORMAT
TIMEZONE
TIME_INPUT_FORMAT
TIME_OUTPUT_FORMAT
TRANSACTION_ABORT_ON_ERROR
TRANSACTION_DEFAULT_ISOLATION_LEVEL
TWO_DIGIT_CENTURY_START
UNSUPPORTED_DDL_ACTION
USE_CACHED_RESULT
WEEK_OF_YEAR_POLICY
WEEK_START
Nota
Essa lista pode mudar com o tempo.
Para outros parâmetros (não listados acima):
Usa-se o valor do parâmetro de nível de conta do proprietário.
Se o parâmetro no nível da conta não for definido para a conta do proprietário, será usado o valor padrão para o parâmetro da conta.
Essa restrição é usada para evitar possíveis problemas que poderiam ocorrer se um procedimento armazenado de direitos do proprietário usasse os parâmetros de sessão do chamador. Por exemplo:
Se o autor (proprietário) de um procedimento armazenado tiver definido um parâmetro de sessão específico, mas os chamadores do procedimento armazenado não tiverem definido esse parâmetro, o procedimento armazenado pode falhar ou comportar-se de forma diferente quando chamado por outros usuários que não o autor.
Se um procedimento armazenado tivesse permissão para usar o valor de qualquer parâmetro de sessão definido pelo chamador, o proprietário de um procedimento armazenado poderia conseguir determinar esses valores sem que o chamador soubesse.
Restrições adicionais aos procedimentos armazenados de direitos do proprietário¶
Os procedimentos armazenados de direitos do proprietário têm várias restrições adicionais, além das restrições relacionadas às variáveis e parâmetros de sessão. Essas restrições afetam o seguinte:
As funções internas que podem ser chamadas de dentro de um procedimento armazenado.
Capacidade de executar instruções ALTER USER.
Monitoramento dos procedimentos armazenados no tempo de execução.
Comandos SHOW e DESCRIBE.
Os tipos de instruções SQL que podem ser chamadas de dentro de um procedimento armazenado.
As seções seguintes explicam essas restrições com mais detalhes.
Nota
A maioria das restrições ao procedimento armazenado de direitos do proprietário se aplica a todos os chamadores, incluindo o proprietário.
Restrições às funções internas¶
Se um procedimento armazenado for criado como um procedimento armazenado de direitos do proprietário, então os chamadores (que não o proprietário) não podem chamar as seguintes funções internas:
GET_DDL()
Isso impede que outros usuários que não o proprietário do procedimento armazenado visualizem o código-fonte do procedimento armazenado.
SYSTEM$ENABLE_BEHAVIOR_CHANGE_BUNDLE()
SYSTEM$DISABLE_BEHAVIOR_CHANGE_BUNDLE()
ALTER USER¶
As restrições a seguir se aplicam às instruções ALTER USER em um procedimento armazenado de direitos do proprietário:
Os procedimentos armazenados de direitos do proprietário não podem executar instruções ALTER USER que implicitamente utilizam o usuário atual para a sessão. (Entretanto, os procedimentos armazenados de direitos do proprietário podem executar instruções ALTER USER que explicitamente identificam o usuário, desde que o usuário não seja o usuário atual).
Monitoramento dos procedimentos armazenados no tempo de execução¶
Nem o proprietário nem o chamador de um procedimento armazenado de direitos do proprietário tem necessariamente privilégios para monitorar a execução do procedimento armazenado.
Um usuário com o privilégio WAREHOUSE MONITOR pode monitorar a execução das instruções SQL individuais relacionadas ao warehouse dentro desse procedimento armazenado. A maioria das consultas e instruções DML são instruções relacionadas ao warehouse. Instruções DDL, como CREATE, ALTER etc., não utilizam o warehouse e não podem ser monitoradas como parte do monitoramento dos procedimentos armazenados.
Comandos SHOW e DESCRIBE¶
Um procedimento armazenado de direitos do proprietário não tem privilégios suficientes para ler informações sobre outros usuários que não o chamador. Por exemplo, executar SHOW USERS LIKE <current_user>
mostrará informações sobre o usuário atual, mas o SHOW USERS
mais geral não funciona, a menos que o usuário atual seja o único usuário.
Os seguintes comandos SHOW são permitidos:
SHOW DATABASES.
SHOW SCHEMAS.
SHOW WAREHOUSES.
Restrições às instruções SQL¶
Embora os procedimentos armazenados de direitos do chamador possam executar qualquer instrução SQL que o chamador tenha privilégios suficientes para executar fora de um procedimento armazenado, os procedimentos armazenados de direitos do proprietário podem chamar apenas um subconjunto de instruções SQL.
As seguintes instruções SQL podem ser chamadas de dentro de um procedimento armazenado de direitos do proprietário:
SELECT.
DML.
DDL. (Consulte acima as restrições à instrução ALTER USER).
GRANT/REVOKE.
Atribuição de variável.
DESCRIBE e SHOW. (Consulte as limitações documentadas acima).
Outras instruções SQL não podem ser chamadas de dentro de um procedimento armazenado de direitos do proprietário.
Procedimentos armazenados aninhados com direitos diferentes¶
Se um procedimento armazenado de direitos do proprietário é chamado pelo procedimento armazenado de direitos do chamador, ou vice-versa, as seguintes regras se aplicam:
Um procedimento armazenado comporta-se como um procedimento armazenado de direitos do chamador se, e somente se, o procedimento e toda a hierarquia de chamada acima dele forem procedimentos armazenados de direitos do chamador.
Um procedimento armazenado de direitos do proprietário sempre se comporta como um procedimento armazenado de direitos do proprietário, não importa de onde ele é chamado.
Qualquer procedimento armazenado chamado direta ou indiretamente a partir de um procedimento armazenado de direitos do proprietário comporta-se como um procedimento armazenado de direitos do proprietário.
Como escolher entre direitos do proprietário e direitos do chamador¶
Crie um procedimento armazenado como um procedimento armazenado de direitos do proprietário se todos os elementos seguintes forem verdadeiros:
Você quer delegar uma tarefa a outro usuário que a executará com os privilégios do proprietário, não com os próprios privilégios do chamador.
Por exemplo, se você quiser que um usuário sem privilégio DELETE para uma tabela possa chamar um procedimento armazenado que exclua dados antigos, mas não dados atuais, então você provavelmente deve usar um procedimento armazenado de direitos de proprietário. Esse procedimento conterá uma instrução DELETE que inclui um filtro (uma cláusula WHERE) para controlar quais dados podem ser excluídos usando o filtro.
Dica
Se você precisar de um procedimento armazenado de direitos de proprietário para executar ações em uma tabela, exibição ou função que o chamador tenha privilégios para acessar, você pode fazer com que o chamador transmita uma referência a essa tabela, exibição ou função.
Para obter mais detalhes, consulte Como passar referências de tabelas, exibições, funções e consultas para procedimentos armazenados.
As restrições aos procedimentos armazenados de direitos do proprietário não impedirão que o procedimento armazenado funcione corretamente.
Crie um procedimento armazenado como um procedimento armazenado de direitos do chamador se as condições seguintes forem verdadeiras:
O procedimento armazenado opera somente em objetos de propriedade do chamador ou para os quais o chamador tem os privilégios necessários.
As restrições aos procedimentos armazenados de direitos do proprietário impediriam o procedimento armazenado de funcionar. Por exemplo, use o procedimento de direitos do chamador se o chamador do procedimento armazenado precisar usar o ambiente desse chamador (por exemplo, variáveis de sessão ou parâmetros de conta).
Se um determinado procedimento puder funcionar corretamente com os direitos do chamador ou do proprietário, então a seguinte regra pode ajudar você a escolher quais direitos usar:
Se um procedimento for um procedimento de direitos do proprietário, o chamador não tem o privilégio de ver o código no procedimento armazenado (a menos que o chamador também seja o proprietário). Se você quiser impedir que os chamadores vejam o código-fonte do procedimento, então crie o procedimento como um procedimento de direitos do proprietário. Por outro lado, se você quiser que os chamadores possam ler o código-fonte, então crie o procedimento como um procedimento de direitos do chamador.