I'm getting an error deleting a database I created about a year ago. in the error, when I run these codes, it says:
USE MASTER;
GO
DROP DATABASE StoreDatabase;
GO
Cannot drop the database 'StoreDatabase', because it does not exist or you do not have permission.
when I try to manually delete it manually
Right-click => Delete => Delete Backup and restore history information for database and Close Existing connections
in the error message it says:
The object of type "Database" named "StoreDatabase" does not exist on the server (SqlManagerUI)
how can I solve this error. thank you for your help.
The Sql Database is not deleted
You do not delete a database but DROP it
Cannot drop the database 'StoreDatabase', because it does not exist or you do not have permission.
Error includes two parts: (1) database does not exist or (2) you do not have permission. Please connect the server using SSMS or Azure Data Studio
(1) Use SSMS and execute the following query in order to confirm that the database exists
select DatabaseName = [name] FROM sys.databases
where [name] = 'StoreDatabase'
GO
(2) In order to DROP a database you need to have CONTROL permission on the database, or ALTER ANY DATABASE permission on the server, or to be membership in the db_owner fixed database role. Execute the following query to check that you have the permissions
USE StoreDatabase;
SELECT * FROM fn_my_permissions (NULL, 'DATABASE')
where permission_name = 'CONTROL'
GO
SELECT * FROM fn_my_permissions(NULL, 'SERVER')
where permission_name = 'ALTER ANY DATABASE'
GO
USE master;
select DatabaseName = [name], DatabaseOwner = suser_sname(owner_sid)
FROM sys.databases
where [name] = 'StoreDatabase'
GO
Try to DROP the database when you are connected as sysadmin (for example the USER sa)
Related
How to "clone" a database from a remote server to LocalDB database by a C# application? No relationships back to the remote database are needed.
Background
Application is written in C# using .NET 4.5.2 and supports two modes - online which connects to a remote MS SQL Server database, and offline which connects to a LocalDB database. The application primarily targets newer versions of the servers (if it matters, supporting only version 2014 is ok).
Before the user goes offline it should ask the application to clone the remote database to the LocalDB database (the local database is completely overwritten). The local database should be independent on the remote database, i.e. no slave nor replication.
Both the online and offline connection string contains name of the respective database. The application itself has no direct knowledge of the database name nor of the table names as this is managed by the connection strings and by the Entity Framework.
Question
How to "clone" the remote database to a LocalDB database (the remote database name and the LocalDB database name might be different)?
I prefer a solution which does not require to launch an external program, but this is not a hard requirement.
Issues
Copying through Entity Framework no tracking entities is unacceptable slow.
I am aware of the BACKUP DATABASE and RESTORE DATABASE commands, but I have found the following difficulties:
They require me to specify the name of the database. Is there a way how to default them to the initial database specified as part of the connection string?
The RESTORE DATABASE command contains names and paths of the respective data files on the disc (MOVE parts). Is there a way how to process it with specifying just the database name without providing the data files path? Or how to get the data files paths via SQL commands (to get the file names, I will just create a blank database, got the file names, optionally drop the database and use the retrieved file names)?
Is there a better way doing this?
I use a stored procedure i created, but first you need to create a linked server:
IF EXISTS(SELECT name FROM sys.servers WHERE name = 'SERVER')
BEGIN--
EXEC sp_dropserver 'SERVER', 'droplogins'
END
/****** Object: LinkedServer [SERVER] create LinkedServer ******/
EXEC master.dbo.sp_addlinkedserver
#server = N'SERVER',
#srvproduct=N'SQLNCLI',
#provider=N'SQLNCLI',
#datasrc=N'192.168.1.1' -- IP address of a server
/* Add login data*/
EXEC sp_addlinkedsrvlogin
#useself='FALSE',
#rmtsrvname='SERVER',
#rmtuser='User',
#rmtpassword='Pass'
Then you can create stored procedure on local server or execute the query directly from application, also for safety I am using a transaction in this example:
USE [DB]
GO
/****** Object: StoredProcedure [dbo].[backupdatabase] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[backupdatabase]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION
TRUNCATE TABLE [dbo].[table_1]
INSERT INTO [dbo].[table_1]
SELECT * FROM [SERVER].[DB].[dbo].[table_1]
TRUNCATE TABLE [dbo].[table_2]
INSERT INTO [dbo].[table_2]
SELECT * FROM [SERVER].[DB].[dbo].[table_2]
TRUNCATE TABLE [dbo].[table_3]
INSERT INTO [dbo].[table_3]
SELECT * FROM [SERVER].[DB].[dbo].[table_3]
COMMIT
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION
DECLARE #ErrMsg nvarchar(4000), #ErrSeverity int
SELECT #ErrMsg = ERROR_MESSAGE(),
#ErrSeverity = ERROR_SEVERITY()
RAISERROR(#ErrMsg, #ErrSeverity, 1)
END
END CATCH
END
In Vsual Studio => Server Explorer I created a new SQL Server database (dbo) and I right clicked on the option "publish to provider".
It generated a file with sql extension which includes sql commands (SELECT, UPDATE).
I want to know what does this file contain.
Is it the whole database?
Can I import this file to SQL Server Management Studio later?
And does it store everything in database (relations, default values, rules)?
I have written some of the text from the file
/****** Object: ForeignKey [FK__aspnet_Me__Appli__21B6055D] Script Date: 06/30/2013 12:01:32 ******/
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo]. [FK__aspnet_Me__Appli__21B6055D]') AND parent_object_id = OBJECT_ID(N'[dbo]. [aspnet_Membership]'))
ALTER TABLE [dbo].[aspnet_Membership] DROP CONSTRAINT [FK__aspnet_Me__Appli__21B6055D]
GO
/****** Object: ForeignKey [FK__aspnet_Me__UserI__22AA2996] Script Date: 06/30/2013 12:01:32 ******/
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo]. [FK__aspnet_Me__UserI__22AA2996]') AND parent_object_id = OBJECT_ID(N'[dbo]. [aspnet_Membership]'))
ALTER TABLE [dbo].[aspnet_Membership] DROP CONSTRAINT [FK__aspnet_Me__UserI__22AA2996]
GO
/***
i clicked [...] can i import this file to sql server management studio later?
Then look at the manual for what you clicked on:
The Database Publishing Wizard in Visual Studio enables you to deploy a SQL Server database (both schema and data) to a hosting environment. You can run the wizard by right-clicking a database in Server Explorer and then clicking Publish to provider.
The tool supports the following ways to deploy a database:
It can generate a single SQL script file that you can manually run on the target server to re-create the database schema and the database contents.
So, yes.
This file contains a list of SQL statements that will transform the DB you selected during the process.
This file will work only for a DB in the same state as the one you selected.
If you will run this process twice, the script that will be generated will be different, since the first script changed your db, and some operations will not be performed.
This file does not contain all the data in the DB.
What's the difference between connecting to a server as opposed to connecting to a database?
The context of the question is that I'm in charge of developing a proof of concept where a user can select one of our servers, a database within that server, a table within that database, and a column within that table. I am using Visual C# and ASP.NET. I believe I can get the servers from the connection strings in the web.config, but I'm not quite sure how.
If it helps at all (I do like examples), you can assume SQL servers.
(Answer to original question)
There is a hierarchy:
Server: A piece of physical (or virtual) hardware that runs an OS and applications. You will address it via IP address or DNS name, in can host multiple Database Servers
Database Server (aka Instance): A piece of software that runs that can host multiple Databases. when you use a connection string it is in the format "ServerName\InstanceName"
Database: A data structure that can host multiple Data Tables
Data Table: A data structure that can host multiple Columns and Rows
Column: The smallest division of information seperation, holds information about a specific topic
Row: Holds a single set of columns.
(Answer to updated question)
It is different per SQL provider, but using Microsleft SQL server you just connect to the server (don't provide a default instance in the connection string) and do the following:
select * from sys.databases
Once you have your database, connect to that database and do the following to get the tables
select * from sys.tables where type = 'U'
to get the columns you do
select * from sys.Columns
however to get the name of the table the column is in you need to match Object_id to Object_id on sys.tables
select t.name as TableName, c.Name as ColumnName
from sys.tables t
inner join sys.columns c on t.object_id = c.object_id
where t.Type = 'U'
You can achieve your goal. Initially, you would connect to database master on the server and query the databases on that server.
SELECT * FROM sys.databases
Then, you would initiate a new connection to the selected database and query that database's information schema, to get a list of tables.
SELECT * FROM INFORMATION_SCHEMA.TABLES
Repeat for selecting a column.
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'foo'
If by server you mean database server, you would connect to the server to gain access to the database hosted on that server.
I want to check if a database is working as a "Publisher" to other databases.
To do this I was planing on checking if the database "distribution" exists on that instance.
after reading this I thought I could just do
new Sqlcommand("SELECT name FROM master.dbo.sysdatabases WHERE name = #name")
and solve my problem...but I dont have that table in my database...:s
is there another way to solve my problem?
If you want to know if a database is a publisher then looking for a distributor is the wrong check. A database can have a remote distributor, in which case you'll get a false negative. Or the distributor may exist but the database may not be a publisher, in which case you get a false positive. Not to mention that the distribution DB may have any name, so looking for a database named distribution is also wrong.
The proper way to do it is to sue the built in replication helper procedures:
exec sp_helppublication will return information about all publications in a database. IF the database is not a publisher, it won't return anything (yoru cue to action).
exec sp_helpdistributor will return information about the distributor of a publisher
exec sp_helpdistributiondb will return information about a distribution database
In addition, the simple facts whether the DB is a publisher, subscriber or distributor can be discovered in sys.databases:
is_published Database is a publication database in a
transactional or snapshot replication topology.
is_merge_published Database is a publication database in a merge replication topology.
is_subscribed Database is a subscription database in a
replication topology.
is_distributor Database is the distribution
database for a replication topology.
Assuming you have sufficient permissions to view database metadata you can use
SELECT CASE
WHEN DB_ID('distribution') IS NULL THEN 0
ELSE 1
END AS distributionExists
select *
from sys.databases
where name = #name
Very close. It looks like that is SQL Server 2000 catalog view. What you are looking for is querying sys.databases.
I created a login to connect to SQL SERVER.
create login bobLogin with password = 'bobpass' , default_database = bobDB
but when i am connecting sql server using this, it does not connects? because it needs a user.
so i created a user:
create user bobDB_USER for login bobLogin
then i connected to sql server using bobLogin & tried to create table:
create table bobDbTable(eid int)
which gives permission denied error;
so i granted permission:
GRANT CREATE TABLE TO bobDB_USER
then i again connected using bobLogin, & tried to create a table but it gave error:
The specified schema name "dbo" either does not exist or you do not have permission to use it.
why so? its creating the table in the dbo schema, thats why? so how do i grant him this permission ?
i dont want to create a new schema. is it necessary?
You would need to GRANT ALTER ON SCHEMA::dbo TO bobDB_USER to allow objects to be created in the dbo schema.
I would also use a Role too.
create role bobDB_ROLE
EXEC sp_addrolemember 'bobDB_ROLE', 'bobDB_USER'
GRANT ALTER ON SCHEMA::dbo TO bobDB_ROLE
However, you could addbobDB_USER into db_owner if it requires these rights
EXEC sp_addrolemember 'db_owner', 'bobDB_USER'
Note: end user permissions are quite different to admin type rights. If 'bobDB_USER' is an end user, then they should not be creating objects