I'm interested in finding a method where a system wide variable can be written onto the Snowflake Account, and used in a view so that users can see the underlying DDL, but not know the value used in a particular function.
At the moment this is done by making these a "Secure" View, but that limits almost everyone from seeing the underlying DDL (which would be helpful to our users and admins).
I'm wondering if there is a way to set a System Wide Variable, and use that in the DDL.
Example:
SET SYSTEM VARIABLE variable_name = 'some_value';
CREATE VIEW catalog.schema.tablename AS
SELECT TRANSLATE(COLUMN_NAME, '0123456789', variable_name) AS NEW_COLUMN_NAME
FROM <FULL SOURCE TABLE NAME>
WHERE <WHATEVER CONDITIONS APPLY>;
I have found setting variables on a session, and I know I can see / change Account Parameters. But can I create something like Account Variables?
Function has two privileges on it - OWNERSHIP and USAGE. If you don't give either of these function privileges to the viewer of the view, but you give the viewer SELECT privileges on the view, they will be able to see the DDL of the view, but won't be able to see the details of the UDF. Then you can store values in your UDF that you don't want other people seeing. I'll post code for this in just a second.
--Something like this to test it out from scratch. You must have accountadmin for this to work:
--use role accountadmin:
--create a database called demo_db;
--create a role called owner_demo_db and grant it usage, monitor, and create schema; also give it usage on a warehouse;
--create a user called demo_db_user. give them ownership on demo_db;
--create a role called reader_demo_db;
--assign the "reader" and the "owner" role to demo_db_user;
--as the owner_demo_db role, create the following:
use role owner_demo_db;
--The role owner_demo_db will own this function
create function pi_udf()
returns float
as '3.141592654::FLOAT'
;
--The role owner_demo_db will own this view
create view MyView as
select 'some_value' AS someval
, pi_udf() pi_val;
--Because owner_demo_db owns the view, they can grant select to the reader role to the view
grant select on view demo_db.demo_schema.MyView to reader_demo_db;
--Show functions and views and you'll be able to see both.
show functions;
show views;
--Show functions and views as reader_demo_db, and you'll only be able to see DDL for the view b/c you don't have a privilege on the function
use role reader_demo_db;
show functions;
show views;
Background:
I have two accounts for the same database one "master" account and another (sub) account which I use for my website to use to connect to the server so I can manage what the user can and cannot do. A lot of the permissions on this account were already on there before I got access to it so I don't know what exactly all the permissions are, except the ones I have managed.
There is a user defined table type that some one else created, dont ask me why they did,
CREATE TYPE [dbo].[AffectedServiceList] AS TABLE(
[AffSerName] [nvarchar](200) NULL
)
GO
This type is used in a stored procedure like so
ALTER PROCEDURE [dbo].[Contractsetup] #OtherParams, --Easier than typing them all
#list dbo.AFFECTEDSERVICELIST READONLY
The master account can execute and modify this procedure perfectly but the sub account cannot run or modify this stored procedure while the affectedservicelist type is used as it gets the error
Cannot find the type 'AffectedServiceList', because it does not exist
or you do not have permission.
I have tried doing this grant execute on type::dbo.AFFECTEDSERVICELIST to subaccount
But it still returns the same error that about the permissions. I have eliminated it to the the permissions as when I try and modify on the master account I just get
Command(s) completed successfully.
To use User Defined Table Type you need EXECUTE or CONTROL permission on it.
Your code
grant execute on type::dbo.AFFECTEDSERVICELIST to subaccount
is correct.
What is missing here is REFERENCES permission:
grant references on type::dbo.AFFECTEDSERVICELIST to subaccount
this is need to be able to reference this type in the code.
To only be able o create a proc using UDT, you only need REFERENCES permission. EXECUTE or CONTROL is needed to be able to execute the code(proc)
After doing a bit more digging the permission I needed to add was not execute it was control.
So instead of doing this;
grant execute on type::dbo.AFFECTEDSERVICELIST to subaccount
I actually needed to do this;
grant control on type::dbo.AFFECTEDSERVICELIST to subaccount
I am new to databases. Here I have logged in the user account:System
I then create a new user raj using the following command
create user raj identified by raj
Then I connected to the user raj using following command
grant connect to raj
Here I am granting privileges on the table client_master to raj
grant all on client_master to raj
Now I want to select the contents of table client_master
select * from raj.client_master
but it is giving an error that such table does not exist.
A quick search on google and you would find out that the select right is as simple as select.
grant select on client_master to raj;
However, it is not the real problem as when executing this command grant all on client_master to raj the select privilege is already included.
So here are the possibilities why you get this error :
The table does not exist (you need to create it).
It is in another schema, and you did not specify it.
You made a typo when writing client_master.
My guess is that you created the table in sys schema (which is really a bad idea btw) so the problem is the option 2 in the one I listed.
Try
select * from sys.client_master;
Note that if you don't want to always specify the prefix, you can create a synonym.
create synonym raj.client_master for sys.client_master;
Then
select * from client_master;
Would work.
Try running below command -
GRANT EXECUTE ON Find_Value TO smith;
This may help you to resolve your issue.
How can I restrict some users in DB2, not to see the table structure. I set the user privilege and restrict user from table access. so that user can not select data or change table but still can see the table structure or describe it.
This problem refers to row access in tables which is added in db2 version 10.
I had this problem too.
you can use this version - if applicable- and restrict user access from specific table structures.
You need to remove the select grant on catalog tables. For example, the following query should return 0 rows when executing with q restricted user.
db2 "select tabschema, tabname from syscat.tables"
All tables and views in the following schemas should not have select on public, nor in any group the restrictive user is in.
sysibm
syscat
db2 revoke select on SYSIBM.SYSTABLES from username
I have a database and have a Sql script to add some fields to a table called "Products" in the database.
But when i am executing this script, I am getting the following error:
Cannot find the object "Products" because it does not exist or you do not have permissions
Why is the error occurring and what should I do to resolve it?
I found a reason why this would happen. The user had the appropriate permissions, but the stored procedure included a TRUNCATE statement:
TRUNCATE TableName
Since TRUNCATE deletes items without logging, you (apparently) need elevated permissions to execute a stored procedure that contains it. We changed the statement to:
DELETE FROM TableName
...and the error went away!
Are you sure that you are executing the script against the correct database? In SQL Server Management studio you can change the database you are running the query against in a drop-down box on one of the toolbars, or you can start your query with this:
USE SomeDatabase
It can also happen due to a typo in referencing a table such as [dbo.Product] instead of [dbo].[Product].
Does the user you're executing this script under even see that table??
select top 1 * from products
Do you get any output for this??
If yes: does this user have the permission to modify the table, i.e. execute DDL scripts like ALTER TABLE etc.? Typically, regular users don't have this elevated permissions.
Look for any DDL operation in the script.
Maybe the user does not have access rights to run changes.
In my case it was SET IDENTITY_INSERT tblTableName ON
You can either add db_ddladmin for the whole database or for just the table to solve this issue (or change the script)
-- give the non-ddladmin user INSERT/SELECT as well as ALTER:
GRANT ALTER, INSERT, SELECT ON dbo.tblTableName TO user_name;
It could also be possible that you have created the "Products" in your login schema and you were trying to execute the same in a different schema (probably dbo)
Steps to resolve this issue
1)open the management studio
2) Locate the object in the explorer and identify the schema under which your object is? ( it is the text before your object name ). In the image below its the "dbo" and my object name is action status
if you see it like "yourcompanydoamin\yourloginid" then you should
you can modify the permission on that specific schema and not any other schema.
you may refer to "Ownership and User-Schema Separation in SQL Server"
I've been trying to copy a table from PROD to DEV but get an error:
"Cannot find the object X because it does not exist or you do not have permissions."
However, the table did exist, and I was running as sa so I did have permissions.
The problem was actually with CONTRAINTS. I'd renamed the table on DEV to be old_XXX months ago. But when I tried to copy the original one over from PROD, the Defaut Constraint names clashed.
The error message was misleading
You can right click the procedure, choose properties and see which permissions are granted to your login ID. You can then manually check off the "Execute" and alter permission for the proc.
Or to script this it would be:
GRANT EXECUTE ON OBJECT::dbo.[PROCNAME]
TO [ServerInstance\user];
GRANT ALTER ON OBJECT::dbo.[PROCNAME]
TO [ServerInstance\user];
This could be a permission issue. The user needs at least ALTER permission to truncate a table.
Another option is to call DELETE FROM instead of TRUNCATE TABLE, but this operation is slower because it writes to the Log file, whereas TRUNCATE does not write to the log file.
The minimum permission required is ALTER on table_name. TRUNCATE TABLE
permissions default to the table owner, members of the sysadmin fixed
server role, and the db_owner and db_ddladmin fixed database roles,
and are not transferable. However, you can incorporate the TRUNCATE
TABLE statement within a module, such as a stored procedure, and grant
appropriate permissions to the module using the EXECUTE AS clause.
Sharing my case, hope that will help.
In my situation inside MY_PROJ.Database->MY_PROJ.Database.sqlproj I had to put this:
<Build Include="dbo\Tables\MyTableGeneratingScript.sql" />
In my case I was running under a different user than the one I was expecting.
My code passed 'DRIVER={SQL Server};SERVER=...;DATABASE=...;Trusted_Connection=false;User Id=XXX;Password=YYY' as the connection string to pypyodbc.connect(), but it ended up connecting with the credentials of the Windows user that ran the script instead of the User Id= from the connection string.
(I verified this using the SQL Server Profiler and by putting an invalid uid/password combination in the connection string - which didn't result in an expected error).
I decided not to dig into this further, since switching to this better way of connecting fixed the issue:
conn = pypyodbc.connect(driver='{SQL Server}', server='servername',
database='dbname', uid='userName', pwd='Password')
In my case the sql server version on my localhost is higher than that on the production server and hence some new variables were added to the generated script from the localhost. This caused errors in creating the table in the first place.
Since the creation of the table failed, subsequent query on the "NON EXISITING" table also failed.
Luckily, in among the long list of the sql errors, I found this "OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF" to be the new varialbe in the script causing my issue. I did a search and replace and the error went away.
Hope it helps someone.
The TRUNCATE statement was my first problem, glad to find the solution here. But I was using SSIS and trying to load data from another database, and it failed with the same error on any table that used IDENTITY to create an auto-incrementing ID. If I was scripting it myself I'd first need to use the command SET IDENTITY_INSERT tablename ON, and then SET IDENTITY_INSERT tablename OFF when the table update was done. But this requires ALTER permissions on the table, which I do not have. Hence the error message in SSIS on the table load (even though the previous step had just deleted all the data out of the table.)
You receive this error, when you use an ORM like GORM (https://gorm.io/) in Go for example.
When you try to create a struct and accidentally pass the ID (primary key) although it's inserted automatically.
Rich features IDE like Visual Studio Code make this mistake happen easily:
if tx := db.Create(&myStruct{
Ts: Time.Now(),
ID: 42,
}); tx.Error != nil {
t.Fatal(tx.Error)
}
You can still use auto-filling by Visual Studio Code, but delete your entry for your model's primary keys:
if tx := db.Create(&myStruct{
Ts: Time.Now(),
}); tx.Error != nil {
t.Fatal(tx.Error)
}