I had a schema in one oracle DB as ui_prod. I asked my DBA team guys to create exactly same schema like ui_prod but as read only and name it ui_prod_readonly. Usually I will use Oracle SQL developer to connect a DB and query directly with table name like below.
--Connect to ui_prod
select * from table
but why I requested to put owner name infront when query for readonly schema they created for me, as without putting it, I get error table not exist.
--Connect to ui_prod_readonly
select * from ui_prod.table
I have project files which hardcode the sql query with only table names and adding owner name in front will cause many changes and effort. Can anyone explain me on this? or provide me any document/link to read. Thanks
You should look into synonyms, apparently the user you are connecting to the database as is not the owner of the objects. So to view the object you have to prepend the names with the schema name (the owner of the object themselves).
http://www.techonthenet.com/oracle/synonyms.php
CREATE OR REPLACE SYNONYM ui_prod_readonly.synonym_name
FOR ui_prod.object_name
It seems to me that your dbas have not created another set of tables but just granted the existing tables to the user ui_prod_readonly.
When you log in to Oracle, the current schema is the name of the user you used to log in. So if you log in with ui_prod_readonly Oracle checks that schema for the table if you do not qualify it with the owner (=schema).
If you want to change the current schema so that you don't need to fully qualify the tables, you can do that with ALTER SESSION
alter session set current_schema = ui_prod;
Once you have done that, you don't need to fully qualify the table with the owner (=schema).
if you need a user to read the data only
its simple to create new user and grant it only select privilege
you can create user and grant select privilege using
CREATE USER [user] IDENTIFIED BY [your_password];
grant select on table to [user]
Related
Using SYSTEM user I create a new user. After that I try to give this user access to specific columns only in 1 table, but get the error that this table does not exist. Meaning that SYSTEM user does not have access to this table. Unfortunately, the user that has access to the normal production tables cannot manage user privileges and access. What are my options?
CREATE USER test1 IDENTIFIED BY 123456;
GRANT UPDATE (extinvno, invoiceno) ON invoice TO test1;
Edit: Solution
Created 3 views that I needed. GRANT-ed the new user SELECT and UPDATE on 2 of the views and SELET on the 3rd. For the new user I had to use the chema to refer to the views: chema.view
If SYSTEM doesn't own the table then you need to specify who does; for example if the table was in the HR schema you would do:
GRANT UPDATE (extinvno, invoiceno) ON HR.invoice TO test1;
... using the real owning schema name, of course.
It isn't that SYSTEM doesn't have access to the table; it's that by default it's looking for SYSTEM.invoice, which doesn't exist.
The table owner could also grant the update privilege to test1.
I was using node.js to work on snowflake datawarehouse as a destination for users. I wanted to check if a user has the required permission level on the schema to create a table and write into it before adding the user to the database otherwise it should give an error saying that the user does not have the appropriate permission level. How can I achieve that programatically?
Thanks,
one way you could do is check if the role has SEELCT privilege on the table by looking into the view TABLE_PRIVILEGES in information_schema schema.
select * from information_schema.TABLE_PRIVILEGES where table_name = 'SALES_RAW'
Due to how permissions can be inherited through the role hierarchy, this isn't easy to do. Permissions aren't assigned to users in Snowflake, they are assigned to roles. You could use the table_privileges in the information schema (as Himanshu said). You'll need to ask your admin for privileges to the information_schema schema in the databsae:
You could probably use some combination of these too:
show grants to user [username]
with
show grants on schema [schema name]
The easiest way would be to have your app / script / service assume the same role as the user and see if you can select from a table in the schema or try to create a temporary table in the schema. If you receive an error code, the user doesn't have permissions!
I have created a new view named CONS_INTERRUPTED_DATA for the main user hfdora and the view has been created successfully. But when I am trying to create the same view for another user (cis) of the same database after giving all the privileges to the user (cis) I am getting the below error,
*oms_consumer
ERROR at line 13:
ORA-00942: table or view does not exist
Both the user hfdora and cis are the part of same database and this oms_consumer table is present at the database
I have granted the following privileges for the user cis before creating the view
grant select on energization_info to cis;
grant select on trigger_info to cis;
grant select on oms_source to cis;
grant select on oms_consumer to cis;
grant connect,resource,dba to cis;
My sql query to create the view,
>CREATE OR REPLACE VIEW CONS_INTERRUPTED_DATA AS
SELECT
trigger_info_A.b1 AS FDR_RMU_OFF_B1, trigger_info_A.b2 AS FDR_RMU_OFF_B2,
trigger_info_A.B3TEXT AS FDR_RMU_OFF_B3TEXT, trigger_info_A.elem AS FDR_RMU_OFF_ELEM,
trigger_info_B.b1 AS FDR_RMU_RESTORE_B1, trigger_info_B.b2 AS FDR_RMU_RESTORE_B2,
trigger_info_B.B3TEXT AS FDR_RMU_RESTORE_B3TEXT,
trigger_info_B.elem AS FDR_RMU_RESTORE_ELEM,
oms_consumer.consumer_code, energization_info.b1 AS AFFECTED_B1,
energization_info.b2 AS AFFECTED_B2, energization_info.b3text AS AFFECTED_B3TEXT,
to_char(energization_info.deenergized_date, 'DD-MM-YYYY Hh24:MI:SS') AS DEENERGIZED_DATE,
to_char(energization_info.energized_date, 'DD-MM-YYYY Hh24:MI:SS') AS ENERGIZED_DATE,
trigger_info_A.comments AS KEY
FROM
energization_info,
trigger_info trigger_info_A,
trigger_info trigger_info_B,
oms_consumer
WHERE
(energization_info.trigger_number = trigger_info_A.trigger_number)
AND (energization_info.ENERGIZED_TRIGGER_NUMBER = trigger_info_B.trigger_number)
AND (energization_info.b1 = oms_consumer.B1NAME
AND energization_info.b2 = oms_consumer.B2NAME
AND energization_info.b3 = oms_consumer.B3NAME)
WITH READ ONLY;
The first step in diagnosing a problem when creating a view is to try the select part on its own. In this case you would still get the ORA-00942 error, but the problem is now just a query and access issue and not to do with the view specifically.
When you get ORA-00942: table or view does not exist, it's because either:
The table or view name that you typed really doesn't exist.
Check the spelling - maybe there is a typo.
Are you connected to a database where it exists? Perhaps you are on a test system that doesn't have it.
Query dba_objects to see whether the table exists in another schema. (If you don't have privileges to query dba_objects, all_objects lists everything you have permission to view, which may be some help.)
It really does exist, but it's in another schema.
In that case, there are two possible issues:
You don't have permission to query it. The table's owner needs to grant read on xyz (substitute the actual table name for xyz) to either
you
public (if you want everyone to be able to see the data, not always advisable)
a role that you have (but roles aren't used by stored PL/SQL or views, though, so it's possible that you can query a table in another schema thanks to a role that you have, but still not be able to create a view or a procedure that uses it.)
You need to specify the schema. Say you want to query the REGIONS table in HR but you are connected as SCOTT. If you just select * from regions it will look for SCOTT.REGIONS, which doesn't exist. To fix that, do one of the following:
use hr.regions explicitly in your query.
in your schema, create or replace synonym regions for hr.regions;
Now whenever you refer to regions, the database will automatically redirect to hr.regions.
in any schema with permission to create public synonyms:
create or replace public synonym regions for hr.regions;
Now everyone connecting to the database will have any references to regions redirected to hr.regions, which isn't always a good idea, but it's one option anyway.
alter session set current_schema = hr;
Now the default schema for resolving names of objects is HR and not the one you logged into. For applications that always log in as a different user than the one that owns the tables, you can create an after logon trigger so this is always set. Then they can just refer to regions etc without needing to specify any schema and without any synonyms.
My issue has been resolved. :-)
I have made the following changes,
FROM
hfdora.energization_info,
hfdora.trigger_info trigger_info_A,
hfdora.trigger_info trigger_info_B,
hfdora.oms_consumer
Now the same view is created for the user cis.
Question: when I create a table (T_TableName) using SQL Server Management-Studio, it always creates the table as
Domain\UserName.T_TableName
instead of
dbo.T_TableName
What's wrong ?
If you don't specify a schema explicitly on your table name to be created, it will be created in the user's current default schema.
I bet the user you're using has its own personal schema set as its default schema - that's why your tables get created in his own personal schema.
You can check what database users you have and what their default schema is by inspecting sys.database_principals (SQL Server 2005 and up):
SELECT name, type_desc, default_schema_name
FROM sys.database_principals
To solve this:
specify the schema you want to use explicitly (best practice anyway!)
CREATE TABLE dbo.T_TableName
change the user's default schema to dbo
ALTER USER [Domain\YourUser] WITH DEFAULT_SCHEMA = dbo
But as a general rule of thumb, I recommend always using the "dbo." prefix explicitly, if you want to have all your database objects in the dbo schema. Helps with performance, too (ever so slightly) since SQL Server won't have to go hunting in different schemas, if you explicitly tell it where your db objects live.
You need to either create your table as "dbo.Whatever", OR you need to change your default schema (or have your SA do it for you) by issuing a command like:
ALTER USER [DOMAINNAME\UserName] WITH DEFAULT_SCHEMA = dbo;
Call it dbo.T_TableName in SSMS. If you have the correct permissions, it will work.
Are you assigned as db_owner for the database you created the table in? If not, this could be the issue. Try adding your user mapping permissions to the database as such.
USE [yourDatabase]
GO
EXEC sp_addrolemember N'db_owner', N'DOMAIN\UserOrGroup'
GO
It is my understanding that the default behavior when creating a table in SQL 2005 is that it will be created with dbo as the owner of the table. Is there a way to change this default behavior so that all tables get created as the user instead of as dbo?
I am working on moving an application from SQL 2000 to SQL 2005 and much of the logic within the application makes the assumption that the default behavior is to create a table with the user as the owner.
You can first create the schema (that you, or the target user, own), then create the table(s) under the schema, ala:
CREATE TABLE [yourSchema].[sales](...)
The schema / owner situation are different in sql2005.
Whats nice is that the schema name doesn't have to the same as the owner name. And if the current schema owner ever leaves you can reassign the schema ownership to someone else.