I have a stored procedure in a database called DEV1
which exists in a Schema called BI
.
I am connecting with an ODBC connection that sets the default database of the session to a databased called DEV2
. I am unable to modify the ODBC connection of this service account due to how it is setup in key vaults/secrets managers for various environments.
When calling the stored procedure in the format of call DEV1.BI.StoredProcedureName()
from the service account which has it's session database set to DEV2, StoredProcedureName()
the query fails if the stored procedure attempts to read from Views which do not fully qualify the database name and exist in the DEV1 database, which are only referenced by a Schema.Table
reference instead of database.schema.table
. In my case this service account looks in DEV2 for these objects, which fails due to them not existing.
Is there functionality within Stored Procedures to overcome this issue?
It has been an architectural decision to leave database names out of our views and stored procedures, which enables us to CLONE COPY a higher environment (Prod) to a lower one (UAT) for testing. This process breaks if we hard code views with CI/CD variables swapped at deployment time.
It's understood that using a different service account can overcome this issue by setting the default database, but when this requires creating somewhat redundant artifacts in key vaults, it seems unnecessary if there exists syntax that can set the Stored Procedure to the right database before execution. I have tried adding a USE [database];
statement as a first-step in the stored proc, unsuccessfully.
Are we chasing dragons or is it possible to achieve what we're looking for without additional service accounts?
We've tried overcoming this by wrapping the uncallable SP in a wrapper Stored Procedure which first changes the database context similar to this:
CREATE OR REPLACE PROCEDURE DEV1.BI.AStoredProcedure()
RETURNS VARCHAR(16777216)
LANGUAGE SQL
EXECUTE AS CALLER
AS 'begin
use DATABASE DEV1;
call BI.AStoredProcedure()
end';
This executes successfully but does not return the data produced by the AStoredProcedure() execution. It feels like we're close but there's no documentation on such behaviour in the Snowflake documentation (that I've been able to find).
Thanks in advance for everyone's input!