Default schema for DROP and SELECT INTO in stored procedures - sql-server

I am a bit confused as to how the default database schema is determined in MS SQL server.
I have the following stored procedure as a minimal working example:
CREATE PROCEDURE [dbo].[SampleSP]
AS
SELECT 'HI' as [SampleColumn]
INTO [SampleTable]
DROP TABLE [SampleTable]
All tests are executed using a user User on MS SQL server using Windows Auth with a default database schema of the same name.
When I execute this SP on MS SQL Server 2005 installation (running in compatibility mode 80, i.e. Server 2000) the table is created as [User].[SampleTable] and DROP TABLE fails with Invalid object name 'SampleTable' (I assume because it looks for [dbo].[SampleTable])
When I DROP TABLE [SampleTable] in a separate query it does work
When I execute the SP on MS SQL Server 2008 R2 (also running in compat. 80) the table is created as [dbo].[SampleTable] and dropped without error
I have found this answer describing the lookup in stored procedures, but it doesn't mention the user default in that context, even though it is used on 2005. Maybe someone knows how this changed and whether new versions can be configured to behave the same way.

It sounds like you just need to set the default schema for the user to dbo:
ALTER USER YourUser WITH DEFAULT_SCHEMA = dbo;
That way it's set at the user level and you won't need to alter any code.

Related

SqlServer Oracle linked server cannot see tables in the default schema

In Sql Management Studio (2012) I have set up a linked Oracle server which works fine. However, I cannot see or access any tables that are in the default schema (i.e., which do not have a schema name).
In other words I can do this:
SELECT * FROM (LinkName)..(SchemaName).(TableName)
but I can't do this:
SELECT * FROM (LinkName)...(TableName)
These tables also do not show up under the Linked Server tables folder, and doing a select returns the error "The table either does not exist or the current user does not have permissions on that table."
I know the tables are there and I have the appropriate rights because I can see and access these tables when working with SSIS on the same machine, and with the same credentials.
Any ideas?

How do I log what user deleted a record in MS Access?

It's a MS Access app with linked tables to SQL Server. I need to log this on the SQL Server as I cannot modify the MS Access app.
The app connects to the SQL Server through a default SQL username.
You will need a trigger for this, and a table to store the results. Very quick prototype:
CREATE TRIGGER dbo.trigger_name
ON dbo.table_name
FOR DELETE
AS
INSERT INTO dbo.LogTable(RowID, UserName)
SELECT PK_Column, SUSER_SNAME()
FROM deleted;
GO
Note that unless each Access user authenticates to SQL Server as themselves, you may need to use host name or some other property to identify them (if they all connect as the same SQL user, there is little SQL Server can do to determine who they really are).

security context problem when accessing through synonyms

There is a user and two databases on server (db1 and db2).
User can connect to server having default database db1 where he can exec sp.
In sp syntax we use synonyms for db2 tables under dbo scheme.
All that is done in order to allow user just connect and exec one stored procedure. It worked noraml but now The server principal "user" is not able to access the database "db2" under the current security context.
User gets output from sp when code does not touch synonyms to db2.
What should be updated? I cant grant select to user for db2 objects.
I know the question is old, but still relevant
the procedure has to have permission on the synonym object
the procedure has to have permission on the object the synonym is targeting
you have to correctly setup trustworthy database property
By default, the procedure executes under the caller account, but it can be changed with execute as clause.

SQL server schema and default schema

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?

Cannot Find Stored Procedure Error

I recently did an import of database from a sql server 2000 database to a sql server 2005 database. I've gone through and setup what I thought were the same login credentials and owner permissions that I had previously setup in my old database.
All of the code base I'm working has stored procedures listed simply by stored procedure name.
In order to make sure I have the proper logins created, I am logging into the SQL Server Management studio with the connection information my application is using (i.e. using the username "licensemgr" and it's associated password). I can see all the tables, stored procedures, etc... in my database when I log in with combination. When I try to run a stored procedure, Sql Server Management Studio uses the following syntax to execute it:
EXEC: #return_value = [licensemgr].[Stored_Procedure_Name]
and it executes without error.
If I try to remove the [licensemgr]. from before the [Stored_Procedure_Name], however I get the error "Cannot find stored procedure: Stored_Procedure_Name". This is the same error I get when running my application off this database. I changed one stored procedure call in my application to have "licensemgr." in front of the stored procedure name and that seemed to correct the problem, however, I don't want to do that for each and every stored procedure call in my application. I am therefore wondering what type of setup / permissions type issue I might be missing in my SQL Server instance so that even when I'm logged into the database as licensemgr, I cannot see the stored procedure which is in the schema "licensemgr".
In SQL server 2000 the [licensemgr] referred to the owner of the table. So when you are logged in as [licensemgr] you do not need the prefix.
In SQL Server 2005 this has been changed to the schema, therefore it must be specified. See:
http://msdn.microsoft.com/en-us/library/ms190387.aspx
EDIT
There are two things that you need to watch out for:
If the user is in the sysadmin role, he will always default to the dbo schema, therefore you need to prefix
If your user needs to run code that is in different schemas you will need to prefix
If none of the two above it should work by setting the default schema for the user
When you created your user, did you specify DEFAULT_SCHEMA?
CREATE USER ... WITH DEFAULT_SCHEMA = "licensemgr"
If not, you may need to use ALTER USER to fix this for your user in the new system.

Resources