Memory Allocation while creating database in SQL Server - sql-server

For a bench-marking project I am currently working on, requires creating multiple databases on SQL Server. I am using Enterprise Edition instance on a VM, that has 8GB RAM and 4 core processor. I wanted to create dummy databases, with no data in it. I have the below script to generate the create database script.
create table createdb
(
dbname varchar(100),
createdbscript varchar(max)
)
DECLARE
#query as varchar(max), #NUM AS INT
SET #NUM = 1
CREATE TABLE #db_names(dbname varchar(250))
WHILE(#NUM <1001)
BEGIN
INSERT INTO #db_names values('NUM'+cast(#NUM as varchar))
SET #NUM = #NUM+1
END
SET #query = ''
insert into createdb
SELECT dbname, #query + 'CREATE DATABASE [' + dbname + ']
CONTAINMENT = NONE
ON PRIMARY
( NAME = N''' + dbname + ''',
FILENAME = N''c:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\' + dbname +'.mdf'' ,
SIZE = 10240KB ,
FILEGROWTH = 1024KB )
LOG ON
( NAME = N''' + dbname + '_log''' +',
FILENAME = N''c:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\' + dbname + '_log' +'.ldf'' ,
SIZE = 512KB ,
FILEGROWTH = 256KB )
' FROM #db_names
select * from createdb
drop table #db_names
I started to run create database commands in a batch of 100. It swamped my server's memory. After sometime, a batch of 2 create database commands was difficult.
I wanted to understand how the memory allocation happens for this kind of operations? What is the best way to create multiple databases? What hardware changes can impact this performance?

Related

Table already exists in a new SQL Server database

I'm writing a script to create a bunch of tables in SQL Server. As I write the script, I want to create and delete the database. The problem is that the I get an error saying that the object already exists.
Here is my example script
DECLARE #db_name varchar(20);
DECLARE #command varchar(100);
SET #db_name='testdb';
SET #command='DROP DATABASE ' + #db_name
IF EXISTS(SELECT * FROM sys.databases WHERE name=#db_name)
exec(#command)
SET #command='CREATE DATABASE ' + #db_name
EXEC(#command)
--listing databaes
SELECT name from master.dbo.sysdatabases
-- using our database
SET #command='USE ' + #db_name
EXEC(#command)
PRINT 'listing tables'
SET #command = 'SELECT table_name FROM ' + #db_name + '.INFORMATION_SCHEMA.TABLES WHERE table_type = "base TABLE"'
EXEC(#command)
CREATE TABLE stuff(
name VARCHAR(30) PRIMARY KEY NOT NULL,
weight INT,
quantity INT)
and the output I get is
name
------------
master
tempdb
model
msdb
testdb
SW
(6 rows affected)
listing tables
table_name
Error:
Msg 2714, Level 16, State 6, Server Orange, Line 22
There is already an object named 'stuff' in the database.
I run this on a Linux mint machine, a freshly installed SQL Server, and I use sqlcmd. I guess I can put a drop/delete command before the creating the table, but this shouldn't happen to begin with. What is going on here?
When you execute a USE statement from dynamic SQL, the database context reverts back to the original database context (master?) when the executed batch completes. You'll need to add a USE to the CREATE TABLE script and execute it using dynamic SQL too:
SET #command = N'USE' + QUOTENAME(#db_name) + N';
CREATE TABLE stuff(
name VARCHAR(30) PRIMARY KEY NOT NULL,
weight INT,
quantity INT);
';
bind the create table statement inside a object existence check. like this
IF OBJECT_ID('stuff') IS NULL
BEGIN
CREATE TABLE stuff(
name VARCHAR(30) PRIMARY KEY--NOT NULL is not needed as the primary key does not allow NULL,
weight INT,
quantity INT)
END

Find All Empty Tables Named MAP_ALERT In All Databases On Server

We perform studies at my job, and each study has its own database. All the study databases are on the same server, and eaxch has a table named MAP_ALERT.
I need to find all MAP_ALERT tables that contain no data, for all the study databases. I found this page that tells how to find empty tables in one database: Select all empty tables in SQL Server - how can I adapt this to find ALL empty tables named MAP_ALERT in ALL database on a given server?
You can use dynamic sql here to help you out. This is querying the system tables for each database. This will even properly handle databases that don't have that table.
declare #SQL nvarchar(MAX)
set #SQL = '';
create table #Results
(
DBName sysname
)
select #SQL = #SQL + 'if exists(select * from ' + name + '.sys.tables where name = ''MAP_ALERT'') insert #results (DBNAME) select ''' + name + ''' from ' + name + '.dbo.MAP_ALERT having count(*) > 0;'
from sys.databases
--select #SQL
--uncomment the following when you have evaluated the dynamic sql and understand what query is going to run on your system
exec sp_executesql #SQL
select * from #Results

How to backup all databases on SQL Server 2008

I have been working on SQL Server 2008 R2 for 4 years and it's time to format my laptop.
I just use the default instance, which I can access using the . as server name, and then my username and password for user authentication.
Now I want to format my laptop, and it is almost impossible to backup manually all the database.
I found in the following path
C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL
all the databases that I have, for each database I found:
databasename_log.ldf
databasename.mdf
I copied these files to an external hard drive.
My question:
Are those files enough to import the database after formatting? Will they work if I installed (after formatting) SQL Server 2012 not 2008 R2?
I found the SQL from this article useful in taking backups of all databases on a server.
DECLARE #name VARCHAR(50) -- database name
DECLARE #path VARCHAR(256) -- path for backup files
DECLARE #fileName VARCHAR(256) -- filename for backup
DECLARE #fileDate VARCHAR(20) -- used for file name
-- specify database backup directory
SET #path = 'C:\Backup\'
-- specify filename format
SELECT #fileDate = CONVERT(VARCHAR(20),GETDATE(),112)
DECLARE db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb') -- exclude these databases
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #fileName = #path + #name + '_' + #fileDate + '.BAK'
BACKUP DATABASE #name TO DISK = #fileName
FETCH NEXT FROM db_cursor INTO #name
END
CLOSE db_cursor
DEALLOCATE db_cursor
You can use SELECT Statement or CURSOR like this:
DECLARE #PathForBackUp VARCHAR(255)
SET #PathForBackUp = 'F:\Backup\User DB\'
SELECT 'BACKUP DATABASE [' + name + '] TO DISK = N''' + #PathForBackUp + '' + name + '.bak''
WITH NOFORMAT, NOINIT, NAME = N''' + name + '_FullBackUp'', SKIP, NOREWIND, NOUNLOAD, COMPRESSION, STATS = 5'
FROM sys.databases
WHERE database_id > 4
OR
DECLARE #DBName VARCHAR(255)
DECLARE #PathForBackUp VARCHAR(255)
DECLARE #FileName VARCHAR(255)
DECLARE #DateFile VARCHAR(255)
DECLARE #SQL NVARCHAR(2048)
SET #PathForBackUp = 'F:\Backup\User DB\'
SET #DateFile = REPLACE(REPLACE(CONVERT(VARCHAR(20),GETDATE(),120) ,' ','T'), ':','')
DECLARE BACKUPING CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases WHERE dbid > 4
OPEN BACKUPING
FETCH NEXT FROM BACKUPING INTO #DBName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #FileName = #PathForBackUp + #DBName + '_' + #DateFile + '.BAK'
SET #SQL = 'BACKUP DATABASE '+#DBName+ ' TO DISK = '''+#FileName+''' WITH COMPRESSION '
PRINT #SQL
EXECUTE sp_executesql #sql
FETCH NEXT FROM BACKUPING INTO #DBName
END
CLOSE BACKUPING
DEALLOCATE BACKUPING
If you want to more about these solution I wrote post about that here:
http://www.pigeonsql.com/single-post/2016/12/20/Backup-All-Users-databases-via-Select-and-Cursor
Are those files enough to import the database after formatting? Will they work if I installed (after formatting) SQL Server 2012 not 2008 R2?
You are taking file level backup of database mdf and ldf file this is bit different from T-SQL backup. As I can read you have already formatted your machine and you have not taken backup so in that case please copy the mdf and ldf file on the local drive and then attach those files to create the database.
Please note before attaching make sure you have installed Service pack(SP), if it was installed on SQL Server 2008 r2 before formatting. If not please install SP after attaching database.
To attach database you can use both TSQL and GUI. Below link would help you in attaching the data files. Before opening SSMS please right click on SSMS and select run as administrator to avoid any access denied message.
Attach a database using SSMS
Sample script for attach
CREATE DATABASE DatabaseName
ON (FILENAME = 'FilePath\FileName.mdf'), -- Main Data File .mdf
(FILENAME = 'FilePath\LogFileName.ldf'), -- Log file .ldf
(FILENAME = 'FilePath\SecondaryDataFile.ndf) -- Optional - any secondary data files
FOR ATTACH
GO

How can I clone an SQL Server database on the same server in SQL Server 2008 Express?

I have an MS SQL Server 2008 Express system which contains a database that I would like to 'copy and rename' (for testing purposes) but I am unaware of a simple way to achieve this.
I notice that in the R2 version of SQL Server there is a copy database wizard, but sadly I can't upgrade.
The database in question is around a gig.
I attempted to restore a backup of the database I want to copy into a new database, but with no luck.
Install Microsoft SQL Management Studio, which you can download for free from Microsoft's website:
Version 2008
Microsoft SQL Management Studio 2008 is part of SQL Server 2008 Express with Advanced Services
Version 2012
Click download button and check ENU\x64\SQLManagementStudio_x64_ENU.exe
Version 2014
Click download button and check MgmtStudio 64BIT\SQLManagementStudio_x64_ENU.exe
Open Microsoft SQL Management Studio.
Backup original database to .BAK file (db -> Task -> Backup).
Create empty database with new name (clone). Note comments below as this is optional.
Click to clone database and open restore dialog (see image)
Select Device and add the backup file from step 3.
Change destination to test database
Change location of database files, it must be different from the original. You can type directly into text box, just add postfix. (NOTE: Order is important. Select checkbox, then change the filenames.)
Check WITH REPLACE and WITH KEEP_REPLICATION
Right-click the database to clone, click Tasks, click Copy Database.... Follow the wizard and you're done.
You could try to detach the database, copy the files to new names at a command prompt, then attach both DBs.
In SQL:
USE master;
GO
EXEC sp_detach_db
#dbname = N'OriginalDB';
GO
At Command prompt (I've simplified the file paths for the sake of this example):
copy c:\OriginalDB.mdf c:\NewDB.mdf
copy c:\OriginalDB.ldf c:\NewDB.ldf
In SQL again:
USE master;
GO
CREATE DATABASE OriginalDB
ON (FILENAME = 'C:\OriginalDB.mdf'),
(FILENAME = 'C:\OriginalDB.ldf')
FOR ATTACH;
GO
CREATE DATABASE NewDB
ON (FILENAME = 'C:\NewDB.mdf'),
(FILENAME = 'C:\NewDB.ldf')
FOR ATTACH;
GO
It turns out that I had attempted to restore from a backup incorrectly.
Initially I created a new database and then attempted to restore the backup here.
What I should have done, and what worked in the end, was to bring up the restore dialog and type the name of the new database in the destination field.
So, in short, restoring from a backup did the trick.
Thanks for all the feedback and suggestions guys
This is the script I use. A bit tricky but it works. Tested on SQL Server 2012.
DECLARE #backupPath nvarchar(400);
DECLARE #sourceDb nvarchar(50);
DECLARE #sourceDb_log nvarchar(50);
DECLARE #destDb nvarchar(50);
DECLARE #destMdf nvarchar(100);
DECLARE #destLdf nvarchar(100);
DECLARE #sqlServerDbFolder nvarchar(100);
SET #sourceDb = 'db1'
SET #sourceDb_log = #sourceDb + '_log'
SET #backupPath = 'E:\DB SQL\MSSQL11.MSSQLSERVER\MSSQL\Backup\' + #sourceDb + '.bak' --ATTENTION: file must already exist and SQL Server must have access to it
SET #sqlServerDbFolder = 'E:\DB SQL\MSSQL11.MSSQLSERVER\MSSQL\DATA\'
SET #destDb = 'db2'
SET #destMdf = #sqlServerDbFolder + #destDb + '.mdf'
SET #destLdf = #sqlServerDbFolder + #destDb + '_log' + '.ldf'
BACKUP DATABASE #sourceDb TO DISK = #backupPath
RESTORE DATABASE #destDb FROM DISK = #backupPath
WITH REPLACE,
MOVE #sourceDb TO #destMdf,
MOVE #sourceDb_log TO #destLdf
None of the solutions mentioned here worked for me - I am using SQL Server Management Studio 2014.
Instead I had to uncheck the "Take tail-log backup before restore" checkbox in the "Options" screen: in my version it is checked by default and prevents the Restore operation to be completed.
After unchecking it, the Restore operation proceeded without issues.
From SSMS :
1 - Backup original database to .BAK file (your_source_db -> Task -> Backup).
2 - Right clicking the "Databases" and 'Restore Database'
3 - Device > ... (button) > Add > select the your_source_db.bak
4 - In 'General' tab, in 'Destination' section, rename in 'Database' your_source_db to new_name_db
5 - In 'Files' tab, tick 'Relocate all files to folder',
Rename in 'Restore As' column the two lignes to keep consistency with new_name_db (.mdf, _log.ldf)
6 - In 'Options' tab, in 'Restore options' section, tick two fist options ('Overwrite...', 'Preserve...') and for 'Recovery state' : 'RESTORE WITH RECOVERY'
Make also sure that in 'Tail-Log backup' section options are unticked to avoid keeping source db in 'restoring state' !
Using MS SQL Server 2012, you need to perform 3 basic steps:
First, generate .sql file containing only the structure of the source DB
right click on the source DB and then Tasks then Generate Scripts
follow the wizard and save the .sql file locally
Second, replace the source DB with the destination one in the .sql file
Right click on the destination file, select New Query and Ctrl-H or (Edit - Find and replace - Quick replace)
Finally, populate with data
Right click on the destination DB, then select Tasks and Import Data
Data source drop down set to ".net framework data provider for SQL server" + set the connection string text field under DATA ex: Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
do the same with the destination
check the table you want to transfer or check box besides "source: ..." to check all of them
You are done.
If the database is not very large, you might look at the 'Script Database' commands in SQL Server Management Studio Express, which are in a context menu off the database item itself in the explorer.
You can choose what all to script; you want the objects and the data, of course. You will then save the entire script to a single file. Then you can use that file to re-create the database; just make sure the USE command at the top is set to the proper database.
In SQL Server 2008 R2, back-up the database as a file into a folder.
Then chose the restore option that appears in the "Database" folder.
In the wizard enter the new name that you want in the target database.
And choose restore frrom file and use the file you just created.
I jsut did it and it was very fast (my DB was small, but still)
Pablo.
The solution, based on this comment: https://stackoverflow.com/a/22409447/2399045 .
Just set settings: DB name, temp folder, db files folder.
And after run you will have the copy of DB with Name in "sourceDBName_yyyy-mm-dd" format.
-- Settings --
-- New DB name will have name = sourceDB_yyyy-mm-dd
declare #sourceDbName nvarchar(50) = 'MyDbName';
declare #tmpFolder nvarchar(50) = 'C:\Temp\'
declare #sqlServerDbFolder nvarchar(100) = 'C:\Databases\'
-- Execution --
declare #sourceDbFile nvarchar(50);
declare #sourceDbFileLog nvarchar(50);
declare #destinationDbName nvarchar(50) = #sourceDbName + '_' + (select convert(varchar(10),getdate(), 121))
declare #backupPath nvarchar(400) = #tmpFolder + #destinationDbName + '.bak'
declare #destMdf nvarchar(100) = #sqlServerDbFolder + #destinationDbName + '.mdf'
declare #destLdf nvarchar(100) = #sqlServerDbFolder + #destinationDbName + '_log' + '.ldf'
SET #sourceDbFile = (SELECT top 1 files.name
FROM sys.databases dbs
INNER JOIN sys.master_files files
ON dbs.database_id = files.database_id
WHERE dbs.name = #sourceDbName
AND files.[type] = 0)
SET #sourceDbFileLog = (SELECT top 1 files.name
FROM sys.databases dbs
INNER JOIN sys.master_files files
ON dbs.database_id = files.database_id
WHERE dbs.name = #sourceDbName
AND files.[type] = 1)
BACKUP DATABASE #sourceDbName TO DISK = #backupPath
RESTORE DATABASE #destinationDbName FROM DISK = #backupPath
WITH REPLACE,
MOVE #sourceDbFile TO #destMdf,
MOVE #sourceDbFileLog TO #destLdf
Another way that does the trick by using import/export wizard, first create an empty database, then choose the source which is your server with the source database, and then in the destination choose the same server with the destination database (using the empty database you created at first), then hit finish
It will create all tables and transfer all the data into the new database,
Script based on Joe answer (detach, copy files, attach both).
Run Managment Studio as Administrator account.
It's not necessary, but maybe access denied error on executing.
Configure sql server for execute xp_cmdshel
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
Run script, but type your db names in #dbName and #copyDBName variables before.
USE master;
GO
DECLARE #dbName NVARCHAR(255) = 'Products'
DECLARE #copyDBName NVARCHAR(255) = 'Products_branch'
-- get DB files
CREATE TABLE ##DBFileNames([FileName] NVARCHAR(255))
EXEC('
INSERT INTO ##DBFileNames([FileName])
SELECT [filename] FROM ' + #dbName + '.sys.sysfiles')
-- drop connections
EXEC('ALTER DATABASE ' + #dbName + ' SET OFFLINE WITH ROLLBACK IMMEDIATE')
EXEC('ALTER DATABASE ' + #dbName + ' SET SINGLE_USER')
-- detach
EXEC('EXEC sp_detach_db #dbname = ''' + #dbName + '''')
-- copy files
DECLARE #filename NVARCHAR(255), #path NVARCHAR(255), #ext NVARCHAR(255), #copyFileName NVARCHAR(255), #command NVARCHAR(MAX) = ''
DECLARE
#oldAttachCommand NVARCHAR(MAX) =
'CREATE DATABASE ' + #dbName + ' ON ',
#newAttachCommand NVARCHAR(MAX) =
'CREATE DATABASE ' + #copyDBName + ' ON '
DECLARE curs CURSOR FOR
SELECT [filename] FROM ##DBFileNames
OPEN curs
FETCH NEXT FROM curs INTO #filename
WHILE ##FETCH_STATUS = 0
BEGIN
SET #path = REVERSE(RIGHT(REVERSE(#filename),(LEN(#filename)-CHARINDEX('\', REVERSE(#filename),1))+1))
SET #ext = RIGHT(#filename,4)
SET #copyFileName = #path + #copyDBName + #ext
SET #command = 'EXEC master..xp_cmdshell ''COPY "' + #filename + '" "' + #copyFileName + '"'''
PRINT #command
EXEC(#command);
SET #oldAttachCommand = #oldAttachCommand + '(FILENAME = "' + #filename + '"),'
SET #newAttachCommand = #newAttachCommand + '(FILENAME = "' + #copyFileName + '"),'
FETCH NEXT FROM curs INTO #filename
END
CLOSE curs
DEALLOCATE curs
-- attach
SET #oldAttachCommand = LEFT(#oldAttachCommand, LEN(#oldAttachCommand) - 1) + ' FOR ATTACH'
SET #newAttachCommand = LEFT(#newAttachCommand, LEN(#newAttachCommand) - 1) + ' FOR ATTACH'
-- attach old db
PRINT #oldAttachCommand
EXEC(#oldAttachCommand)
-- attach copy db
PRINT #newAttachCommand
EXEC(#newAttachCommand)
DROP TABLE ##DBFileNames
You could just create a new database and then go to tasks, import data, and import all the data from the database you want to duplicate to the database you just created.
This program copies a database to the same server under a different name. I relied on examples given on this site with some improvements.
-- Copies a database to the same server
-- Copying the database is based on backing up the original database and restoring with a different name
DECLARE #sourceDb nvarchar(50);
DECLARE #destDb nvarchar(50);
DECLARE #backupTempDir nvarchar(200)
SET #sourceDb = N'Northwind' -- The name of the source database
SET #destDb = N'Northwind_copy' -- The name of the target database
SET #backupTempDir = N'c:\temp' -- The name of the temporary directory in which the temporary backup file will be saved
-- --------- ---
DECLARE #sourceDb_ROWS nvarchar(50);
DECLARE #sourceDb_LOG nvarchar(50);
DECLARE #backupPath nvarchar(400);
DECLARE #destMdf nvarchar(100);
DECLARE #destLdf nvarchar(100);
DECLARE #sqlServerDbFolder nvarchar(100);
Declare #Ret as int = -1
Declare #RetDescription nvarchar(200) = ''
-- Temporary backup file name
SET #backupPath = #backupTempDir+ '\TempDb_' + #sourceDb + '.bak'
-- Finds the physical location of the files on the disk
set #sqlServerDbFolder = (SELECT top(1) physical_name as dir
FROM sys.master_files where DB_NAME(database_id) = #sourceDb );
-- Clears the file name and leaves the directory name
set #sqlServerDbFolder = REVERSE(SUBSTRING(REVERSE(#sqlServerDbFolder), CHARINDEX('\', REVERSE(#sqlServerDbFolder)) + 1, LEN(#sqlServerDbFolder))) + '\'
-- Finds the logical name for the .mdf file
set #sourceDb_ROWS = (SELECT f.name LogicalName FROM sys.master_files f INNER JOIN sys.databases d ON d.database_id = f.database_id
where d.name = #sourceDb and f.type_desc = 'ROWS' )
-- Finds the logical name for the .ldf file
set #sourceDb_LOG = (SELECT f.name LogicalName FROM sys.master_files f INNER JOIN sys.databases d ON d.database_id = f.database_id
where d.name = #sourceDb and f.type_desc = 'LOG' )
-- Composes the names of the physical files for the new database
SET #destMdf = #sqlServerDbFolder + #destDb + N'.mdf'
SET #destLdf = #sqlServerDbFolder + #destDb + N'_log' + N'.ldf'
-- If the source name is the same as the target name does not perform the operation
if #sourceDb <> #destDb
begin
-- Checks if the target database already exists
IF Not EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = #destDb)
begin
-- Checks if the source database exists
IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = #sourceDb) and (#sqlServerDbFolder is not null)
begin
-- Opens the permission to run xp_cmdshell
EXEC master.dbo.sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
EXEC master.dbo.sp_configure 'xp_cmdshell', 1
RECONFIGURE WITH OVERRIDE
-- If the temporary backup directory does not exist it creates it
declare #md as nvarchar(100) = N'if not exist ' + #backupTempDir + N' md ' +#backupTempDir
exec xp_cmdshell #md, no_output
-- Creates a backup to the source database to the temporary file
BACKUP DATABASE #sourceDb TO DISK = #backupPath
-- Restores the database with a new name
RESTORE DATABASE #destDb FROM DISK = #backupPath
WITH REPLACE,
MOVE #sourceDb_ROWS TO #destMdf,
MOVE #sourceDb_LOG TO #destLdf
-- Deletes the temporary backup file
declare #del as varchar(100) = 'if exist ' + #backupPath +' del ' +#backupPath
exec xp_cmdshell #del , no_output
-- Close the permission to run xp_cmdshell
EXEC master.dbo.sp_configure 'xp_cmdshell', 0
RECONFIGURE WITH OVERRIDE
EXEC master.dbo.sp_configure 'show advanced options', 0
RECONFIGURE WITH OVERRIDE
set #ret = 1
set #RetDescription = 'The ' +#sourceDb + ' database was successfully copied to ' + #destDb
end
else
begin
set #RetDescription = 'The source database '''+ #sourceDb + ''' is not exists.'
set #ret = -3
end
end
else
begin
set #RetDescription = 'The target database '''+ #destDb + ''' already exists.'
set #ret = -4
end
end
else
begin
set #RetDescription = 'The target database ''' +#destDb + ''' and the source database '''+ #sourceDb + ''' have the same name.'
set #ret = -5
end
select #ret as Ret, #RetDescription as RetDescription
<!doctype html>
<head>
<title>Copy Database</title>
</head>
<body>
<?php
$servername = "localhost:xxxx";
$user1 = "user1";
$pw1 = "pw1";
$db1 = "db1";
$conn1 = new mysqli($servername,$user1,$pw1,$db1);
if($conn1->connect_error) {
die("Conn1 failed: " . $conn1->connect_error);
}
$user2 = "user2";
$pw2 = "pw2";
$db2 = "db2";
$conn2 = new mysqli($servername,$user2,$pw2,$db2);
if($conn2->connect_error) {
die("Conn2 failed: " . $conn2->connect_error);
}
$sqlDB1 = "SELECT * FROM table1";
$resultDB1 = $conn1->query($sqlDB1);
if($resultDB1->num_rows > 0) {
while($row = $resultDB1->fetch_assoc()) {
$sqlDB2 = "INSERT INTO table2 (col1, col2) VALUES ('" . $row["tableRow1"] . "','" . $row["tableRow2"] . "')";
$resultDB2 = $conn2->query($sqlDB2);
}
}else{
echo "0 results";
}
$conn1->close();
$conn2->close();
?>
</body>
If you are MS SQL 2014 and newer;
DBCC CLONEDATABASE (CurrentDBName, NewDBName)
GO
Details;

What is a simple command line program or script to backup SQL server databases?

I've been too lax with performing DB backups on our internal servers.
Is there a simple command line program that I can use to backup certain databases in SQL Server 2005? Or is there a simple VBScript?
To backup a single database from the command line, use osql or sqlcmd.
"C:\Program Files\Microsoft SQL Server\90\Tools\Binn\osql.exe"
-E -Q "BACKUP DATABASE mydatabase TO DISK='C:\tmp\db.bak' WITH FORMAT"
You'll also want to read the documentation on BACKUP and RESTORE and general procedures.
I use ExpressMaint.
To backup all user databases I do for example:
C:\>ExpressMaint.exe -S (local)\sqlexpress -D ALL_USER -T DB -BU HOURS -BV 1 -B c:\backupdir\ -DS
Schedule the following to backup all Databases:
Use Master
Declare #ToExecute VarChar(8000)
Select #ToExecute = Coalesce(#ToExecute + 'Backup Database ' + [Name] + ' To Disk = ''D:\Backups\Databases\' + [Name] + '.bak'' With Format;' + char(13),'')
From
Master..Sysdatabases
Where
[Name] Not In ('tempdb')
and databasepropertyex ([Name],'Status') = 'online'
Execute(#ToExecute)
There are also more details on my blog: how to Automate SQL Server Express Backups.
I found this on a Microsoft Support page http://support.microsoft.com/kb/2019698.
It works great! And since it came from Microsoft, I feel like it's pretty legit.
Basically there are two steps.
Create a stored procedure in your master db. See msft link or if it's broken try here: http://pastebin.com/svRLkqnq
Schedule the backup from your task scheduler. You might want to put into a .bat or .cmd file first and then schedule that file.
sqlcmd -S YOUR_SERVER_NAME\SQLEXPRESS -E -Q "EXEC sp_BackupDatabases #backupLocation='C:\SQL_Backup\', #backupType='F'" 1>c:\SQL_Backup\backup.log
Obviously replace YOUR_SERVER_NAME with your computer name or optionally try .\SQLEXPRESS and make sure the backup folder exists. In this case it's trying to put it into c:\SQL_Backup
I'm using tsql on a Linux/UNIX infrastructure to access MSSQL databases. Here's a simple shell script to dump a table to a file:
#!/usr/bin/ksh
#
#.....
(
tsql -S {database} -U {user} -P {password} <<EOF
select * from {table}
go
quit
EOF
) >{output_file.dump}
You can use the backup application by ApexSQL. Although it’s a GUI application, it has all its features supported in CLI. It is possible to either perform one-time backup operations, or to create a job that would back up specified databases on the regular basis. You can check the switch rules and exampled in the articles:
ApexSQL Backup CLI support
ApexSQL Backup CLI examples
Eventual if you don't have a trusted connection as the –E switch declares
Use following command line
"[program dir]\[sql server version]\Tools\Binn\osql.exe" -Q "BACKUP DATABASE mydatabase TO DISK='C:\tmp\db.bak'" -S [server] –U [login id] -P [password]
Where
[program dir] is the directory where the osql.exe exists
On 32bit OS c:\Program Files\Microsoft SQL Server\
On 64bit OS c:\Program Files (x86)\Microsoft SQL Server\
[sql server version] your sql server version 110 or 100 or 90 or 80 begin with the largest number
[server] your servername or server ip
[login id] your ms-sql server user login name
[password] the required login password
Microsoft's answer to backing up all user databases on SQL Express is here:
The process is: copy, paste, and execute their code (see below. I've commented some oddly non-commented lines at the top) as a query on your database server. That means you should first install the SQL Server Management Studio (or otherwise connect to your database server with SSMS). This code execution will create a stored procedure on your database server.
Create a batch file to execute the stored procedure, then use Task Scheduler to schedule a periodic (e.g. nightly) run of this batch file. My code (that works) is a slightly modified version of their first example:
sqlcmd -S .\SQLEXPRESS -E -Q "EXEC sp_BackupDatabases #backupLocation='E:\SQLBackups\', #backupType='F'"
This worked for me, and I like it. Each time you run it, new backup files are created. You'll need to devise a method of deleting old backup files on a routine basis. I already have a routine that does that sort of thing, so I'll keep a couple of days' worth of backups on disk (long enough for them to get backed up by my normal backup routine), then I'll delete them. In other words, I'll always have a few days' worth of backups on hand without having to restore from my backup system.
I'll paste Microsoft's stored procedure creation script below:
--// Copyright © Microsoft Corporation. All Rights Reserved.
--// This code released under the terms of the
--// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
USE [master]
GO
/****** Object: StoredProcedure [dbo].[sp_BackupDatabases] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Microsoft
-- Create date: 2010-02-06
-- Description: Backup Databases for SQLExpress
-- Parameter1: databaseName
-- Parameter2: backupType F=full, D=differential, L=log
-- Parameter3: backup file location
-- =============================================
CREATE PROCEDURE [dbo].[sp_BackupDatabases]
#databaseName sysname = null,
#backupType CHAR(1),
#backupLocation nvarchar(200)
AS
SET NOCOUNT ON;
DECLARE #DBs TABLE
(
ID int IDENTITY PRIMARY KEY,
DBNAME nvarchar(500)
)
-- Pick out only databases which are online in case ALL databases are chosen to be backed up
-- If specific database is chosen to be backed up only pick that out from #DBs
INSERT INTO #DBs (DBNAME)
SELECT Name FROM master.sys.databases
where state=0
AND name=#DatabaseName
OR #DatabaseName IS NULL
ORDER BY Name
-- Filter out databases which do not need to backed up
IF #backupType='F'
BEGIN
DELETE #DBs where DBNAME IN ('tempdb','Northwind','pubs','AdventureWorks')
END
ELSE IF #backupType='D'
BEGIN
DELETE #DBs where DBNAME IN ('tempdb','Northwind','pubs','master','AdventureWorks')
END
ELSE IF #backupType='L'
BEGIN
DELETE #DBs where DBNAME IN ('tempdb','Northwind','pubs','master','AdventureWorks')
END
ELSE
BEGIN
RETURN
END
-- Declare variables
DECLARE #BackupName varchar(100)
DECLARE #BackupFile varchar(100)
DECLARE #DBNAME varchar(300)
DECLARE #sqlCommand NVARCHAR(1000)
DECLARE #dateTime NVARCHAR(20)
DECLARE #Loop int
-- Loop through the databases one by one
SELECT #Loop = min(ID) FROM #DBs
WHILE #Loop IS NOT NULL
BEGIN
-- Database Names have to be in [dbname] format since some have - or _ in their name
SET #DBNAME = '['+(SELECT DBNAME FROM #DBs WHERE ID = #Loop)+']'
-- Set the current date and time n yyyyhhmmss format
SET #dateTime = REPLACE(CONVERT(VARCHAR, GETDATE(),101),'/','') + '_' + REPLACE(CONVERT(VARCHAR, GETDATE(),108),':','')
-- Create backup filename in path\filename.extension format for full,diff and log backups
IF #backupType = 'F'
SET #BackupFile = #backupLocation+REPLACE(REPLACE(#DBNAME, '[',''),']','')+ '_FULL_'+ #dateTime+ '.BAK'
ELSE IF #backupType = 'D'
SET #BackupFile = #backupLocation+REPLACE(REPLACE(#DBNAME, '[',''),']','')+ '_DIFF_'+ #dateTime+ '.BAK'
ELSE IF #backupType = 'L'
SET #BackupFile = #backupLocation+REPLACE(REPLACE(#DBNAME, '[',''),']','')+ '_LOG_'+ #dateTime+ '.TRN'
-- Provide the backup a name for storing in the media
IF #backupType = 'F'
SET #BackupName = REPLACE(REPLACE(#DBNAME,'[',''),']','') +' full backup for '+ #dateTime
IF #backupType = 'D'
SET #BackupName = REPLACE(REPLACE(#DBNAME,'[',''),']','') +' differential backup for '+ #dateTime
IF #backupType = 'L'
SET #BackupName = REPLACE(REPLACE(#DBNAME,'[',''),']','') +' log backup for '+ #dateTime
-- Generate the dynamic SQL command to be executed
IF #backupType = 'F'
BEGIN
SET #sqlCommand = 'BACKUP DATABASE ' +#DBNAME+ ' TO DISK = '''+#BackupFile+ ''' WITH INIT, NAME= ''' +#BackupName+''', NOSKIP, NOFORMAT'
END
IF #backupType = 'D'
BEGIN
SET #sqlCommand = 'BACKUP DATABASE ' +#DBNAME+ ' TO DISK = '''+#BackupFile+ ''' WITH DIFFERENTIAL, INIT, NAME= ''' +#BackupName+''', NOSKIP, NOFORMAT'
END
IF #backupType = 'L'
BEGIN
SET #sqlCommand = 'BACKUP LOG ' +#DBNAME+ ' TO DISK = '''+#BackupFile+ ''' WITH INIT, NAME= ''' +#BackupName+''', NOSKIP, NOFORMAT'
END
-- Execute the generated SQL command
EXEC(#sqlCommand)
-- Goto the next database
SELECT #Loop = min(ID) FROM #DBs where ID>#Loop
END​
Here is an example one, it will take backup database, compress using 7zip and delete backup file so issue related to storage also solved. In this example I use 7zip, which is free
#echo off
CLS
echo Running dump ...
sqlcmd -S SERVER\SQLEXPRESS -U username -P password -Q "BACKUP DATABASE master TO DISK='D:\DailyDBBackup\DB_master_%date:~-10,2%%date:~-7,2%%date:~-4,4%.bak'"
echo Zipping ...
"C:\Program Files\7-Zip\7z.exe" a -tzip "D:\DailyDBBackup\DB_master_%date:~-10,2%%date:~-7,2%%date:~-4,4%_%time:~0,2%%time:~3,2%%time:~6,2%.bak.zip" "D:\DailyDBBackup\DB_master_%date:~-10,2%%date:~-7,2%%date:~-4,4%.bak"
echo Deleting the SQL file ...
del "D:\DailyDBBackup\DB_master_%date:~-10,2%%date:~-7,2%%date:~-4,4%.bak"
echo Done!
Save this as sqlbackup.bat and schedule it to be run everyday.
If you just want to take backup only then you can create script without zipping and deleting.
You could use a VB Script I wrote exactly for this purpose:
https://github.com/ezrarieben/mssql-backup-vbs/
Schedule a task in the "Task Scheduler" to execute the script as you like and it'll backup the entire DB to a BAK file and save it wherever you specify.
SET NOCOUNT ON;
declare #PATH VARCHAR(200)='D:\MyBackupFolder\'
-- path where you want to take backups
IF OBJECT_ID('TEMPDB..#back') IS NOT NULL
DROP TABLE #back
CREATE TABLE #back
(
RN INT IDENTITY (1,1),
DatabaseName NVARCHAR(200)
)
INSERT INTO #back
SELECT 'MyDatabase1'
UNION SELECT 'MyDatabase2'
UNION SELECT 'MyDatabase3'
UNION SELECT 'MyDatabase4'
-- your databases List
DECLARE #COUNT INT =0 , #RN INT =1, #SCRIPT NVARCHAR(MAX)='', #DBNAME VARCHAR(200)
PRINT '---------------------FULL BACKUP SCRIPT-------------------------'+CHAR(10)
SET #COUNT = (SELECT COUNT(*) FROM #back)
PRINT 'USE MASTER'+CHAR(10)
WHILE(#COUNT > = #RN)
BEGIN
SET #DBNAME =(SELECT DatabaseName FROM #back WHERE RN=#RN)
SET #SCRIPT ='BACKUP DATABASE ' +'['+#DBNAME+']'+CHAR(10)+'TO DISK =N'''+#PATH+#DBNAME+ N'_Backup_'
+ REPLACE ( REPLACE ( REPLACE ( REPLACE ( CAST ( CAST ( GETDATE () AS DATETIME2 ) AS VARCHAR ( 100 )), '-' , '_' ), ' ' , '_' ), '.' , '_' ), ':' , '' )+'.bak'''+CHAR(10)+'WITH COMPRESSION, STATS = 10'+CHAR(10)+'GO'+CHAR(10)
PRINT #SCRIPT
SET #RN=#RN+1
END
PRINT '---------------------DIFF BACKUP SCRIPT-------------------------'+CHAR(10)
SET #COUNT =0 SET #RN =1 SET #SCRIPT ='' SET #DBNAME =''
SET #COUNT = (SELECT COUNT(*) FROM #back)
PRINT 'USE MASTER'+CHAR(10)
WHILE(#COUNT > = #RN)
BEGIN
SET #DBNAME =(SELECT DatabaseName FROM #back WHERE RN=#RN)
SET #SCRIPT ='BACKUP DATABASE ' +'['+#DBNAME+']'+CHAR(10)+'TO DISK =N'''+#PATH+#DBNAME+ N'_Backup_'
+ REPLACE ( REPLACE ( REPLACE ( REPLACE ( CAST ( CAST ( GETDATE () AS DATETIME2 ) AS VARCHAR ( 100 )), '-' , '_' ), ' ' , '_' ), '.' , '_' ), ':' , '' )+'.diff'''+CHAR(10)+'WITH DIFFERENTIAL, COMPRESSION, STATS = 10'+CHAR(10)+'GO'+CHAR(10)
PRINT #SCRIPT
SET #RN=#RN+1
END
This can be helpful when you are dealing with dockerised mssql container in your day to day work and want to take a quick dump of the data from table. I have specially found it useful when you are re-building the db container quite frequently and don't want to loose the test data after the re-build.
Export data using bcp utility
/opt/mssql-tools/bin/bcp <Table_Name> out /tmp/MyData.bcp -d <database_name> -c -U <user_name> -P "<password>" -S <server_name>
Import data using bcp utility
/opt/mssql-tools/bin/bcp <Table_Name> IN /tmp/MyData.bcp -d <database_name> -c -U <user_name> -P "<password>" -S <server_name>
If you can find the DB files... "cp DBFiles backup/"
Almost for sure not advisable in most cases, but it's simple as all getup.

Resources