SQL server schema and default schema - sql-server

I have a schema define in my database. Except now everytime I do a sql statement I have to provide the schema ...
SELECT * FROM [myschema].table
I set the default schema for my user using management studio and also ran the
ALTER USER myUser WITH DEFAULT_SCHEMA [myschema]
and I still get the invalid object 'table' when writing a query without the schema (SELECT * FROM table)
Is there a way to write SELECT * FROM table without having to specify the schema name all the time?
It's on SQL 2005 using SQL Management Studio.

Is the user an SA, if so it will not work, according to the documentation SA users are always defaulted to the dbo schema.
The value of DEFAULT_SCHEMA is ignored
if the user is a member of the
sysadmin fixed server role. All
members of the sysadmin fixed server
role have a default schema of dbo.

Couple of options:
Is your user listed under Security > Users (in SSMS)? Check the Properties (right click the name), and see if the Default schema is set in the context of the database, rather than the instance (which is what ALTER USER is setting).
Create a synonym for the table you want to reference:
CREATE SYNONYM table_name
FOR [your_db].[your_schema].table_name
...which will affect everyone who doesn't use at least two name notation, in the context of that database. Read more about it here. But it is associated ultimately to a schema.
Check that the database selected in the "Available Databases" drop down (upper left, to the left of the Execute button) is correct.
Use three name notation when specifying table (and view) references:
SELECT *
FROM [your_db].[your_schema].table_name

If you do not want to use "full qualified" SQl names, then you need to avoid creating your tables using any account or role that's not using the "dbo" default schema assigned. Why do you need to change the default schema on the user if you don't plan on using it?

Related

Objects being created as DBO for all users in SQL Server application

We have Windows Authentication on our SQL Server Databases.
Every object gets created as dbo which I don't mind. But we are unable to track who created what? Can someone help on how it can be managed so we can at least track who is doing what? The login names from the trace is also generic
login name - ABC\gMSA_SQL$
If I login to the server with my windows authentication and run the below command select SUSER_NAME(), I can see my username and not a generic one. So now if I create a table where can I get this username from?
The default schema of the user are set to dbo. It could be due to many reasons, as mentioned in the below msdn reference
The default schema will be the first schema that will be searched by
the server when it resolves the names of objects for this database
user. Unless otherwise specified, the default schema will be the owner
of objects created by this database user.
If the user has a default schema, that default schema will used. If
the user does not have a default schema, but the user is a member of a
group that has a default schema, the default schema of the group will
be used. If the user does not have a default schema, and is a member
of more than one group, the default schema for the user will be that
of the Windows group with the lowest principal_id and an explicitly
set default schema. (It is not possible to explicitly select one of
the available default schemas as the preferred schema.) If no default
schema can be determined for a user, the dbo schema will be used.
DEFAULT_SCHEMA can be set before the schema that it points to is
created.
DEFAULT_SCHEMA cannot be specified when you are creating a user mapped
to a certificate, or an asymmetric key.
The value of DEFAULT_SCHEMA is ignored if the user is a member of the
sysadmin fixed server role. All members of the sysadmin fixed server
role have a default schema of dbo.
You can find out the default schema of the users by running the below query. Refer to sys.database_principals
SELECT default_schema_name FROM sys.database_principals
If you want to restrict the users to only create objects on their schema, you have to do below things:
CREATE SCHEMA [userPrincipalSchema];
GO
CREATE USER [userPrincipal]
WITH PASSWORD='SUPERCOMPLEXPASSWORDHERE'
, DEFAULT_SCHEMA=[userPrincipalSchema]
GO
DENY ALTER ON SCHEMA::[dbo] to [userPrincipal]
GO
ALTER AUTHORIZATION ON SCHEMA::[userPrincipalSchema] to [userPrincipal];
GO
GRANT CREATE TABLE, CREATE VIEW, CREATE PROCEDURE TO [userPrincipal];
GO
This way, you can ensure that the [userPrincpal] is able to create objects only on their schema and you can track, the objects created by them.

How to create a local schema in Oracle database 11g?

I have installed Oracle Database 11g Release 2 (11.2.0.1.0) for Microsoft Windows (x64). How do I create a new schema or local schema?
A schema is the collection of objects owned by a user.
So connect as a power user like SYSTEM and run a create user command. Find out more.
Once you have a user you can connect to it and create tables and other objects.
Have you tried looking in the docs? https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_6014.htm#SQLRF01313
In oracle a 'schema' is nothing more than the collection of objects belonging to a given user. Many people will even argue that a "user" is a "schema". I believe that it was with 11g (now out of support) that oracle introduced the CREATE SCHEMA command. That command simply combines creating a user and creating some tables belonging to that user into a single SQL statement. You can always do it the "old fashioned" way by simply issuing a CREATE USER, then issuing whatever CREATE . statements you need:
create user fubar identified by fubar;
create table fubar.mytable (dob date);
create view fubar.myview as (select * from fubar.mytable);
etc. etc.

recreate user with schema

Following code recreates a user:
-- Remove link to order schema
ALTER AUTHORIZATION ON SCHEMA::order TO dbo
-- Recreate order user without login
DROP USER order
CREATE USER order WITH DEFAULT_SCHEMA = order
-- Restore link to order schema
ALTER AUTHORIZATION ON SCHEMA::order TO order
My question is, why do we need to remove link to schema before dropping a user, and restore it back after user created?
The behavior of Schemas changed in SQL Server 2005. Schemas are no longer equivalent to database users; each schema is now a distinct namespace that exists independently of the database user who created it. In other words, a schema is simply a container of objects. A schema can be owned by any user, and its ownership is transferable.
https://msdn.microsoft.com/en-us/library/ms190387.aspx
http://basitaalishan.com/2014/05/29/the-database-principal-owns-a-schema-in-the-database-and-cannot-be-dropped/
Ok, just found why we need to temporary move the schema link to another owner before deleting a user.
It will return error if not doing so:
The database principal owns a schema in the database, and cannot be dropped.

SQL Server 2008 - give user access to certain tables and views only

I need to allow certain user access to only specific views and tables. I have tried following so far
Created a user ex_user
Created a role rviewonly
deny view definition to rviewonly;
Then I executed this sql
GRANT SELECT ON vwBI_PEOPLE TO rviewonly
It seems to work, and this ex_user can do a select command on it however I do not see this vwBI_PEOPLE in list of views in Management Studio. There are about 50 views that I have to give this user access to along with about 40 different tables - I want the user to be able to see the available views and tables in Management Studio's Object Explorer
Because you have denied view definition at the database level (no object specified) to the role/user, this trumps any grant view definition on ... that you may make on an individual object. Grant select on ... will also allow view definition on that object without having to specify grant view definition.
I recommend revoking view definition at the database level:
revoke view definition to rviewonly;
And simply let your grant select on statements do the work for you. You shouldn't have to rerun them again after running the above revoke. view definiton by itself would be good for giving a user/role access to metadata, but not data.
Note that any deny will always trump a grant including the cases where you deny a role access but grant the user access or vice-versa.
I just verified this on a SQL Server 2008 R2 dev box. I'm not sure if any settings exist that might alter this behavior for your instance.
I had the same question before. I, instead of using a role, just granted select on the user itself. This is something handy for multiple table permission granting:
SELECT 'GRANT SELECT ON '+name+' TO ex_user;'
from sysobjects
where name in (
'[Enter table]',
'[names here]',
'[in a list]',
'[to grant permissions]'
)
Then copy all the results, throw it in a query, and run it. Especially handy if all the tables you want to grant access to are prefixed with the same grouping of letters.
Example: You can just change the above query's where clause to be where name like 'TST_%', if all the tables/views you're granting start with "TST_".
You need to add ex_user to rviewonly role sp_addrolemember:
EXEC sp_addrolemember rviewonly, [ex_user];
Then use revoke instead of deny view definition to the role:
revoke view definition to rviewonly;

When to qualify table or view name with dbo in a query?

I have a view in SQL Server, lets say MY_VIEW.
When I execute the command SELECT * FROM MY_VIEW it works fine. However, when I execute it as
SELECT * FROM dbo.MY_VIEW I get *Invalid object name 'MyDB.dbo.MY_VIEW'*
I am connected to SQL server using sa.
What is wrong with this? And when should we use dbo.MY_VIEW and when not?
Update: The schema name on the view is dbo and when I created the view then too I had connected with sa.
Update2 I found the problem was case sensitive collation. The problem was not because of the dbo. prefix. It was because the database collation was case sensitive and table names in queries were in wrong case.
Did you create your objects under a different schema name than dbo? It would depend on the default schema name for your user account if you didn't qualify it when you created the view. In SQL 2k5 and 2k8 I believe the default behavior is to create a new schema for each user vs. assigning them to the 'dbo' schema.
You are in the master database. You created the view in the master database. Your actual query was SELECT * FROM MyDB.dbo.MY_VIEW. Try creating the view in the MyDB database instead.
I found the problem was case sensitive collation. The problem was not because of the dbo. prefix. It was because the database collation was case sensitive and table names in queries were in wrong case.

Resources