default schema synonym - sql-server

I have a database FooDb with a schema BarSchema that contains a table Tbl (i.e. FooDb.BarSchema.Tbl)
I am also logged in as a user with BarSchema as default.
This query works fine
SELECT * FROM FooDb..Tbl
I also have a synonym for this table in another db
CREATE SYNONYM TblSynonym FOR FooDb..Tbl
But now I get an error "Invalid object name 'FooDb..Tbl'" when executing
SELECT * FROM TblSynonym
If i change the synonym to
CREATE SYNONYM TblSynonym FOR FooDb.BarSchema.Tbl
it works fine.
Why doesn't the default schema work in synonyms?
(The background is that I'm consoldating data from several databases which all got same table names but different schema names. It would be a lot easier if I could set the default schema for each database on the user and then ignore it everywhere in the script)

The documentation suggests the db..tbl syntax should work:
schema_name_2 Is the name of the
schema of the base object. If
schema_name is not specified the
default schema of the current user is
used.
This works for me in SQL Server 2008:
create synonym TestSynonym for TestDB..TestTable
One cause might be that the default schema is associated with the user, not the database. Check if your user has an unexpected default schema? In my SSMS, that setting is located under Database -> Security -> Users -> Properties.

Related

in SQL Server 2014 why SELECT * FROM System_User doesn't work but SELECT * FROM [ProjectManage].[dbo].[System_User] work

I am using SQL Server 2014 management studio, I found a strange situation.
in a SQL query dialog, I key in the below SQL:
SELECT * FROM System_User
I can see the table name in resource management dialog is: dbo.System_User
Then when I try to execute it, it said there is some grammar error.
If I change the SQL as:
SELECT * FROM [ProjectManage].[dbo].[System_User]
it works well.
But acutally in same SQL query dialog, I have another SQL:
SELECT * FROM FlowTemplateTransition
and its table name is dbo.FlowTemplateTransition in resource management dialog.
My question is:
what is the difference between dbo.FlowTemplateTransition and FlowTemplateTransition?
when do I need to add dbo and when it is unnecessary?
do I need to using square brackets always?
Thanks
dbo is the default schema in SQL Server. You can create your own schemas to allow you to better manage your object namespace.
In SQL Server Management Studio, you can create your own schema by browsing to Databases - Your Database - Security - Schemas. Or you can execute below query to create a schema.
CREATE SCHEMA [SchemaName] AUTHORIZATION [dbo]
You can use them to logically group your tables, for example by creating a schama for "vendors" information and another for "customers" data. Your tables would then display as:
vendors.BankAccounts
vendors.Transactions
customers.Address
Instead of using the default schema of dbo.
No need to use the square brackets[] always. But if your database or table name contains something like a dot(.) then you must use [].
As you have 3 questions. I have list it down separately.
Why SELECT * FROM System_User not working?
what is the difference between dbo.FlowTemplateTransition and FlowTemplateTransition
when do I need to add dbo and when it is unnecessary? do I need to using square brackets always?
Answer 1 : System_User is sql server built in function. Your table name conflict with this function that is why it gives an error.
Answer 2 : dbo is default database owner. If you don't write owner of table than Sql Server automatically consider dbo as an owner for that table.
Answer 3 : Generally dbo is not necessary to add.
The brackets are required if you use keywords or special chars in the table name.

Can I make sql server management studio not require [] around table names?

If I copy and paste a query into sql management studio to debug it, I have to change all the table names from tableName to [database].[dbo].[tableName], Can this be avoided?
It also matters which database you are using. When you open a default query window, it selects Master as your database. You can either manually change it to your database, which will just accept table names after that or you can specify in your query with a
Use Databasename;
Otherwise, you will need to specify the databasename.schema.table name with every reference. This is also how you can query across multiple databases in the same query window.
[] is called QuoteName and is required when you don't have a valid identifier for an object..
For Example
this fails
create table dbo.123
(
id int
)
this succeeds
create table dbo.[123]
(
id int
)
So in summary,[] isnot necessary,if you have a valid identifier and is required when you dont have one

Unable to carry out operations (create trigger, drop table) for a table I created

I am using a SQL Server database with SQL Server Management Studio where I have existing tables. I add a few tables to it and it works just fine. However, for subsequent operations such as
Drop table XXX --OR
Create Trigger YYY on XXX
I run into a error statement that reads:
i) Cannot drop table XXX as it does not exist or you do not have permissions
ii) The object 'XXX' does not exist or is invalid for this operation
I tried to carry out an Insert operation but that showed me a similar error (The object 'XXX' does not exist). I can see this maybe a permissions issue since I am using an existing database. However, in that case, I should have been unable to create a table as well?
Can anyone pinpoint how I can work myself around this and what the problem is?
What is your default schema?
SELECT name, default_schema_name
FROM sys.database_principals
WHERE type = 'S';
Try qualifying your references to the table as SchemaName.XXX and see if that helps.
Most of times when I had similar situations tables were created in system databases (master, tempdb..). Of course it was my mistake.
So maybe try to search for a tables in other databases?

Cannot find the object because it does not exist or you do not have permissions. Error in SQL Server

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)
}

Oracle database role - select from table across schemas without schema identifier

Which Oracle database role will allow a user to select from a table in another schema without specifying the schema identifier?
i.e., as user A- Grant select on A.table to user B;
B can then- "Select * from table" without specifying the 'A'.
One of our databases allows this, the other returns a 'table or view does not exist' error.
You can create a synonym for this. Create a synonym named "CoffeeTable" on object "A.CoffeeTable". You can create a public synonym so everyone sees it like this, or just a synonym under user B.
Just to double check that the schema you are using doesn't have a private synonym for the table (or a view as Leigh suggests) you could the following
SELECT * FROM all_objects WHERE object_name = 'mytablename'
and look at the owner and object_type information.
Maybe only the current_schema is different. Try:
alter session set current_schema=A
If there isn't a synonym, is there a view in schema B that selects from the table in schema A using the same name as the table? This would appear to be a locally referenced table in many ways.
Brett is right. Synonyms are used for this. In fact there are cases where you do not know what will be the schema name in production. Maybe you use A for some schema name and A is already taken in some Oracle instance.
#erno - probably the reason that TOAD didn't show you the public synonym is because it filters the information shown in the list - I don't have toad in front of me but I think if you right click on tab you will get to the filtering options (eg "only show objects owned by the schema", "show public objects", "show system objects" etc)

Resources