Can we Use Snowflake Tables functions in the procedure? - snowflake-cloud-data-platform

Experts,
I am trying to use tables function inside the snowflake procedure. However it throws me an error.
CREATE PROCEDURE
.....
....
extcnt ="select count(*) from table(information_schema.external_table_files(table_name=>''MYTABLE''))";
snowflake.execute({sqlText: extcnt});
.....
I get below error message. Is there any restriction in using table function inside the procedure? Please Help.
"JavaScript execution error: Uncaught 100183-Stored procedure execution error: Requested information on the current user is not accessible in stored procedure"
Regards,
Gopi

Check the "Caller’s Rights and Owner’s Rights Stored Procedures" - this is probably the source of that error message:
https://docs.snowflake.com/en/sql-reference/stored-procedures-rights.html
When defining a stored procedure you can ask it to EXECUTE AS CALLER, which changes the access it has to different resources.
Create a stored procedure as an owner’s rights stored procedure if all of the following are true: You want to delegate a task(s) to another user(s) who will run with the owner’s privileges, not the caller’s own privileges [...]
Create a stored procedure as a caller’s rights stored procedure if the following are true: The stored procedure operates only on objects that the caller owns or has the required privileges on [...]
CREATE PROCEDURE sv_proc1()
RETURNS VARCHAR
LANGUAGE JAVASCRIPT
EXECUTE AS CALLER
AS
$$
...

Related

Is there a way in which I can grant only read access of a procedure in snowflake?

I have created a Procedure in snowflake
I want to give read-privileges of that stored procedure in snowflake to some other user/role.
GRANT USAGE ON PROCEDURE
get_column_scale(float)
TO ROLE other_role_name_here;
I believe the above command would also give the write access, which I don't want. Is there a way in which only read access can be granted
The only privilege to assign to a procedure is usage, so if you want a role to be able to read the definition for the procedure but not run it, then you can use a stored procedure defined to execute with owner's rights:
create or replace procedure read_procedure(PROCEDURE_PATH string)
returns string
language javascript
execute as owner
as
$$
let rs = snowflake.execute({sqlText: `select get_ddl('procedure', ?) as DDL`, binds:[PROCEDURE_PATH]});
rs.next();
return rs.getColumnValue('DDL');
$$;
create or replace procedure FOO(S string)
returns string
language javascript
as
$$
return S;
$$;
grant usage on procedure READ_PROCEDURE(string) to role MY_ROLE;
call read_procedure('FOO(string)');
In this setup, make sure that MY_ROLE has usage on procedure read_procedure(string) but does not have usage on procedure foo(string). That way the role will be able to see the definition of foo(string) without the privilege required to execute it (usage).
Note that since the read_procedure(string) procedure runs with owner's rights, anyone calling it will be able to read any procedure that the owner's role can read.
Edit: You can also read the SP in parts in the INFORMATION_SCHEMA.PROCEDURES view. You can grant select on that view without granting USAGE on the procedure.

Force a stored procedure to fail when a column not exits?

Sometimes it happens that I have some errors in stored procedure body, e.g.
select invalidColumn from validTable
When I try to create/alter stored procedure, it works and I can see the error only when I try to execute the stored procedure.
Is it possible to force schema check when I create or alter?

How to get name of executing stored procedure in Snowflake?

Does snowflake have function which returns name of the current stored procedure like the following in SQL Server.
SELECT OBJECT_NAME(##PROCID)
I am just trying to build a logging table to log all statements that are executed inside a stored procedure this is for monitoring purpose i.e. which statement within stored procedure failed and how long queries are taking to run. If Snowflake has something out-of-box OR a recommended way of doing it please share.
Try this from within your stored procedure:
const procName = Object.keys(this)[0];
Also see this related post.

execute('tsql_string') inside stored procedure - what permissions/user is used for execute()?

I have a stored procedure where I'd like to save the execution of an update statement for further down in the procedure, which I'm doing by putting the sql into a varchar variable.
My problem is that the EXECUTE() seems to use the original caller's permissions and then gives an error, as the caller does not (and should not) have UPDATE permissions for table1.
Why doesn't it use the permissions of the stored procedure's owner?
And more importantly: how can I make it use those permissions?
The stored procedure looks basically like this: (except #tsql_string is set dynamically)
create procedure dbo.woopwoop() as
BEGIN
DECLARE #tsql_string varchar(max)
SET #tsql_string = 'UPDATE table1 set c1 = 1'
EXECUTE(#tsql_string)
END
I'm on SQL Server 2008, and the owner (me) of the stored procedure is a Windows Authentication user with domain\user.
Anyone?
That's what the EXECUTE AS clause exists for - to allow you to control this:
By specifying the context in which the module is executed, you can control which user account the Database Engine uses to validate permissions on objects that are referenced by the module.
CALLER
Specifies the statements inside the module are executed in the context of the caller of the module. The user executing the module must have appropriate permissions not only on the module itself, but also on any database objects that are referenced by the module.
CALLER is the default for all modules except queues
You would be wanting to specify that the stored procedure executes as OWNER (or possibly SELF, read the above page and decide which makes most sense for you) instead.
create procedure dbo.woopwoop()
with execute as owner
as
....
From MSDN (This example grants EXECUTE permission on the stored procedure HumanResources.uspUpdateEmployeeHireInfo to an application role named Recruiting11):
USE AdventureWorks2012;
GRANT EXECUTE ON OBJECT::HumanResources.uspUpdateEmployeeHireInfo
TO Recruiting11;
GO
Source
Of course you should have permission to grant the permission.

Stored Procedure and Permissions - Is EXECUTE enough?

I have a SQL Server 2008 database where all access to the underlying tables is done through stored procedures. Some stored procedures simply SELECT records from the tables while others UPDATE, INSERT, and DELETE.
If a stored procedure UPDATES a table does the user executing the stored procedure also need UPDATE permissions to the affected tables or is the fact that they have EXECUTE permissions to the stored procedure enough?
Basically I am wondering if giving the user EXECUTE permissions to the stored procedures is enough or do I need to give them SELECT, UPDATE, DELETE, and INSERT permissions to the tables in order for the stored procedures to work. Thank you.
[EDIT] In most of my stored procedures it does indeed appear that EXECUTE is enough. However, I did find that in stored procedures where "Execute sp_Executesql" was used that EXECUTE was not enough. The tables involved needed to have permissions for the actions being performed within "sp_Executesql".
Permissions on tables are not checked (including DENY) if tables and proc have the same owner. They can be in different schemas too as long as the schemas have the same owner.
See Ownership chaining on MSDN
Edit, from a comment from a deleted answer.
The context is always the current login unless EXECUTE AS as been used: only referenced object DML permissions are not checked. Try OBJECT_ID(referencedtable) in a stored proc where no rights are assigned to referencedtable. It gives NULL. If executed by the owner of the stored proc then it would give a value because owener has rights on referencedtable
Execute permissions on the stored procedure is sufficient.
CREATE TABLE dbo.Temp(n int)
GO
DENY INSERT ON dbo.Temp TO <your role>
GO
CREATE PROCEDURE dbo.SPTemp(#Int int)
AS
INSERT dbo.Temp
SELECT #Int
GO
GRANT EXEC ON dbo.SPTemp TO <your role>
GO
Then the (non-db_owner) user will have the following rights:
EXEC dbo.SPTemp 10
GO
INSERT dbo.Temp --INSERT permission was denied on the object 'Temp'
SELECT 10
However, if there is dynamic SQL inside dbo.SPTemp that attempts to insert into dbo.Temp then that will fail. In this case direct permission on the table will need to be granted.
Maybe you can use
"with execute as owner"
when you create the stored procedure, such as below:
create procedure XXX
with execute as owner
as
begin
...
end
go
Then you only need to grant the user the EXECUTE permission for the stored procedure XXX.
Execute permission on a stored procedure that does an insert, update, or delete is sufficient. You do not need to grant those permissions at the table level. In fact, I would discourage that approach. Using a stored procedure gives you more control over how the change occurs. For instance, you may wish to do some checking prior to allowing the update. Using a stored procedure can also help prevent major accidents--like deleting all the rows in the table because someone forgot the WHERE clause!
THANK YOU SO MUCH! I had a similar problem. This lead me to the answer.
I was attempting to trunctate a table in a stored procedure that called other stored procedures that were nested in IF statements.
My error was
The server principal "domain\my_id" is not able to access the database "2nd_DB" under the current security context.
I had given the calling stored procedure rights to do the truncate (EXECUTE AS SELF), which then caused a problem because SELF didn't have rights to the 2nd DB. Our solution was to move the truncate to another SP, include the EXECUTE AS SELF. We now call the truncate SP, execute our data processing, make logic determination, and call the appropriate 3rd SP.

Resources