Double Dot table qualifier - sql

I am looking at a new database schema developed by an external vendor. There are two databases:
Database1
Database2
They have sent me an SQL statement that joins tables between the two databases. There are places where they have used a double dot notation. I have never seen this before. Please see the SQL statement below (this is not the statement they sent me):
select * from database2..Person
The statement above is run from database1. Why does it have two dots? If I remove one of the dots then the query does not run.
I have done some Googling and came across this: http://www.sqlservercentral.com/Forums/Topic585446-338-1.aspx. This suggests it is referring to the schema. However:
The schema is empty in the sql statement i.e. there is no text in between the two dots.
The Person table is part of the dbo schema in database2.

Thanks to this dot, the default schema (dbo) is choosen for your query.
When you have two databases it is required to give the full path to the table.
If we have:
Database1 schema: dbo, guest table dbo.A, guest: A
Database2 schema: dbo, guest table dbo.B, guest: B
if we create select statement like:
select * from Database2..B
We are selecting data from dbo.B table
IF we would like to specify schema we need to refer as
select * from Database2.schemaname.tablename
EDIT:
As colleagues pointed out, the default schema can be changed in database, however in this particular example it seems to be dbo :)

This is a database schema. Full three-part name of a table is:
databasename.schemaname.tablename
For a default schema of the user, you can also omit the schema name:
databasename..tablename
You can also specify a linked server name:
servername.databasename.schemaname.tablename
You can read more about using identifiers as table names on MSDN

Related

If not exist clause SQL statement

so I found this sql query in a project I am succeeding. This is the first time I encountering this clause/statement. I understand that this is to look if the table exist before creating one and that Object_ID is the table name that is to be created.
My questions are:
Does sysobject mean the database?
What is the Object property?
I know that it is not the columns inside the table to be created.
The columns are : dtb_color_id and description.
can someone explain this to me. please?
IF NOT EXISTS(SELECT * FROM SYSOBJECTS WHERE ID = OBJECT_ID('DTB_COLOR') AND OBJECTPROPERTY(ID,'ISUserTable') = 1)
BEGIN
.......some query I understand
END
sysobjects, OBJECTPROPERTY and OBJECT_ID are used in Microsoft SQL Server. They are part of the SQL Server DMVs and system functions/procedures used to query and manipulate the metadata.
sys.sysobjects is simply the list of all objects (tables, views, SPs, functions, etc) on the server in the active database. Please note, that sys.sysobjects is deprecated and is only available for backward compatibility. Use sys.objects instead
https://learn.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/system-dynamic-management-views?view=sql-server-ver16
It has (as far as I know) no meaning in MySQL, unless somebody specifically created them.
You can also use INFORMATION_SCHEMA which is available in MySQL too (however slightly different in different RDBMS).
MSSQL INFORMATION_SCHEMA: https://learn.microsoft.com/en-us/sql/relational-databases/system-information-schema-views/system-information-schema-views-transact-sql?view=sql-server-ver16
MySQL INFORMATION_SCHEMA: https://dev.mysql.com/doc/refman/8.0/en/information-schema.html
SQL Server has no CREATE TABLE IF NOT EXISTS construct, a variation of the mentioned condition is commonly used to imitate that.
This is a way in SQL Server to check if a table exists in the active database and to perform actions according to the result, like creating the table.
OBJECTPROPERTY simply checks (in this case) if the table is a user created one.
https://learn.microsoft.com/en-us/sql/t-sql/functions/objectproperty-transact-sql?view=sql-server-ver16
I would remove the OBJECTPROPERTY condition in case the part you understand is a CREATE TABLE statement. You don't want to create a table which has a similar name to any system table/view, also you don't want to execute the CREATE TABLE if there is a VIEW with the same name (table creation will fail)
Yes sysobject means database.
The OBJECTPROPERTY() function returns information about schema-
scoped objects in the current database. Use this to check if an
object is a table, view, stored procedure, etc. You can also use
it to check if a table has a primary key, foreign key, foreign
key reference, etc.
For more details : https://learn.microsoft.com/en-us/sql/t-sql/functions/objectpropertyex-transact-sql?view=sql-server-ver16
In this scenario it is used to check whether it is user table or
not. The result of the ISUserTable property is 1 when it is user
table otherwise returns 0.
Here the following steps are followed:
First, it executes the select statement inside the IF Exists
If the select statement returns a value that condition is TRUE for IF Exists
It starts the code inside a begin statement
DTB_COLOR - May be a stored procedure

What does double dots .. mean in SQL Server?

I am using SQL Server. I found the following way to backup a database table:
-- Taking a backup
SELECT * INTO MY_BACKUP_DATABASE..CustomersTemporaryTable FROM Customers
I am trying to understand the .. in the syntax. From what I understand, the sentence means that Customers is the table that is going to be backed-up by placing it all of its content into the database called MY_BACKUP_DATABASE using CustomersTemporaryTable as the destination table. I assume when executing the sentence, CustomersTemporaryTable must already exist. Is my understanding of the sentence to take a backup correct?
Each MS SQL Table identifiers can have a name compound of three parts separates with a dot :
the database name
the SQL schema name (by default dbo)
the table, view or Table UDF name
Syntax :
db_name.schema_name.table_name
But it is not always necessary to specify the three parts.
Inside the current database, no need to specify the db_name. It's implicit...
By default every SQL user is associate with a specific default schema (frequently dbo too...).
So you can specify a table name with :
schema_name.table_name
...SQL Server will try to find the table into the current DB
db_name..table_name
...SQL Server will try to find the table into the specified DB and the default user schema
table_name
...SQL Server will try to find the table into the current DB and the
default user schema
To know with SQL schema is associated with your SQL user, use :
SELECT SCHEMA_NAME() AS DEFAULT_CURRENT_USER_SCHEMA
To know all the associations between SQL users and SQL schemas, do :
SELECT name AS USER_NAME, default_schema_name
FROM sys.database_principals
WHERE type_desc LIKE '%?_USER' ESCAPE '?'
First of all, understand that what you are doing is not "taking a backup", it is inserting data into a table from another table. If you have not created the destination table the syntax is like this:
Select *
INTO Destination_Table
FROM Source_Table
The destination table will be created automatically. This doesn't necessarily work so well if you will be inserting additional data that might be different lengths or data types, but for a one of select should work fine.

SQL Server Table Schema Name

I have some questions about the schema in a table.
Sometime when you create a table the default schema is dbo.TableName. Is the dbo the default schema name? I believe you can change or specify the schema when creating a table right, because there are tables that have different schema like: Sales.Tablename or Users.Roles, etc. I believe the purpose of a schema is to make a difference between tables or something like that? Something like a namespace within a C# class. Is it possible to have two tables with same name but a different schema, like: Sales.Users, Marketing.Users ?
dbo is the default schema. You can change the default schema for each sql-login.
If you accidentally create a table in the wrong schema, you can move it:
-- Moving Peter table from Sales schema to Orders schema
ALTER SCHEMA Orders TRANSFER Sales.peter
You can specify which schema to create the table in by specifying it before the table name:
CREATE TABLE Sales.Users(id int);
One of the purposes of schemas is to create logical groups of tables, just like namespaces in C#. They are also useful for controlling permissions and more.
Yes, table names only need to be unique within each schema..
Sometime when you create a table the default schema is dbo.TableName. Is the dbo
the default schema name?
Why do you ask? It is quite obvious that dbo is the default schame name if you get it as default, or? On top it is the only usable schema a new database has.
I believe you can change or specify the schema when creating a table right,
What sense would multiple schemata have if you could not use them? And as the create table syntax clearly states you can specify a schema.
I believe the purpose of a schema is to make a difference between tables or
something like that? Something like a namespace within a C# class.
That pretty much sums it up.
Is it possible to have two tables with same name but a different schema,
What about you spend 10 seconds to try it out? Are you challenged by he concept of trying something totally simplistic out? And the answer is yes. object names have to be unique - within their schema.

Using name of a database inside a sql script for a full table name

I struggled for a while with a bug, and then found out the reason for it in a database stored procedure code, which contained the old name of a database in a table name, whereas the current database name was already different. So, I'd like to ask:
Is there a situation in which using a database name as a part of a full table name (database name + schema name + table name) can be justified (provided we don't touch tables in other databases) or is it always a bad practice? How to correctly use a database name in sql scripts to keep code neutral to a specific database?
Code just for an illustration:
CREATE PROCEDURE [dbo].[MyProc]
AS
BEGIN
DELETE FROM [MyDatabase].[dbo].[MyTable]
END
No, you shouldn't use database names in a stored procedure unless you need to address two databases.
It causes exactly the kinds of bugs you're seeing. When the database name changes, all your SP code breaks, or continues working, but on the old database.
It does make sense if you are sending a SQL query to the database, but only if the application dynamically picks the database name to insert into the query.
My suggestion is that you do a full export of your database schema, and search for database names that are hardcoded and remove them.
It really depends on how your scripts are implemented.
Even if you don't refer to a table as
[MyDatabase].[dbo].[MyTable]
you will still need to refer to the database by:
USE [MyDatabase]
earlier in the script.
It is possible to mix trusted database tables in a single query. When someone do this,it is justified and mandatory to include database on table 'path'.
I don't found a reason out of this scenario if stored procedure and table is on the same database.
You can search all database name occurencies through database catalog in order to fix your development. For SQL Server 2005:
SELECT Name
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%databasename%'
GO
For SQL Server 2000:
SELECT DISTINCT so.name
FROM syscomments sc
INNER JOIN sysobjects so ON sc.id=so.id
WHERE sc.TEXT LIKE '%databasename%'
GO

Copy tables from one database to another in SQL Server

I have a database called foo and a database called bar. I have a table in foo called tblFoobar that I want to move (data and all) to database bar from database foo. What is the SQL statement to do this?
SQL Server Management Studio's "Import Data" task (right-click on the DB name, then tasks) will do most of this for you. Run it from the database you want to copy the data into.
If the tables don't exist it will create them for you, but you'll probably have to recreate any indexes and such. If the tables do exist, it will append the new data by default but you can adjust that (edit mappings) so it will delete all existing data.
I use this all the time and it works fairly well.
On SQL Server? and on the same database server? Use three part naming.
INSERT INTO bar..tblFoobar( *fieldlist* )
SELECT *fieldlist* FROM foo..tblFoobar
This just moves the data. If you want to move the table definition (and other attributes such as permissions and indexes), you'll have to do something else.
This should work:
SELECT *
INTO DestinationDB..MyDestinationTable
FROM SourceDB..MySourceTable
It will not copy constraints, defaults or indexes. The table created will not have a clustered index.
Alternatively you could:
INSERT INTO DestinationDB..MyDestinationTable
SELECT * FROM SourceDB..MySourceTable
If your destination table exists and is empty.
If it’s one table only then all you need to do is
Script table definition
Create new table in another database
Update rules, indexes, permissions and such
Import data (several insert into examples are already shown above)
One thing you’ll have to consider is other updates such as migrating other objects in the future. Note that your source and destination tables do not have the same name. This means that you’ll also have to make changes if you dependent objects such as views, stored procedures and other.
Whit one or several objects you can go manually w/o any issues. However, when there are more than just a few updates 3rd party comparison tools come in very handy. Right now I’m using ApexSQL Diff for schema migrations but you can’t go wrong with any other tool out there.
Script the create table in management studio, run that script in bar to create the table. (Right click table in object explorer, script table as, create to...)
INSERT bar.[schema].table SELECT * FROM foo.[schema].table
You can also use the Generate SQL Server Scripts Wizard to help guide the creation of SQL script's that can do the following:
copy the table schema
any constraints (identity, default values, etc)
data within the table
and many other options if needed
Good example workflow for SQL Server 2008 with screen shots shown here.
You may go with this way: ( a general example )
insert into QualityAssuranceDB.dbo.Customers (columnA, ColumnB)
Select columnA, columnB from DeveloperDB.dbo.Customers
Also if you need to generate the column names as well to put in insert clause, use:
select (name + ',') as TableColumns from sys.columns
where object_id = object_id('YourTableName')
Copy the result and paste into query window to represent your table column names and even this will exclude the identity column as well:
select (name + ',') as TableColumns from sys.columns
where object_id = object_id('YourTableName') and is_identity = 0
Remember the script to copy rows will work if the databases belongs to the same location.
You can Try This.
select * into <Destination_table> from <Servername>.<DatabaseName>.dbo.<sourceTable>
Server name is optional if both DB is in same server.
I give you three options:
If they are two databases on the same instance do:
SELECT * INTO My_New_Table FROM [HumanResources].[Department];
If they are two databases on different servers and you have linked servers do:
SELECT * INTO My_New_Table FROM [ServerName].[AdventureWorks2012].[HumanResources].[Department];
If they are two databases on different servers and you don't have linked servers do:
SELECT * INTO My_New_Table
FROM OPENROWSET('SQLNCLI', 'Server=My_Remote_Server;Trusted_Connection=yes;',
'SELECT * FROM AdventureWorks2012.HumanResources.Department');