"Create Database"-SQL with name from variable fails - sql-server

I used an existing database to generate a "CREATE"-Script via the MS SQL Server Management Tool. Then i replaced the string literals for the DB Name with variables. However, when i execute the script, it keeps saying "wrong syntax near #DBFullName" (the first use in 'NAME = #DBFullName ...'). I have no idea what the issue is, other than the possibility, that the use of variables is forbidden here.
DECLARE #DBNAME nvarchar(MAX);
SET #DBNAME = 'MyDataBase'
DECLARE #DBFullName text;
SET #DBFullName = 'MySuperDataBase';
DECLARE #DBFileName text;
SET #DBFileName = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.DEVELOPMENT\MSSQL\DATA\\' + #DBName + '.mdf';
DECLARE #DBLogName text;
SET #DBLogName = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.DEVELOPMENT\MSSQL\DATA\\' + #DBName + '.ldf';
CREATE DATABASE [#DBNAME] ON PRIMARY
( NAME = #DBFullName + '_Data', FILENAME = #DBFileName , SIZE = 30720KB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%)
LOG ON
( NAME = #DBFullName + '_Log', FILENAME = #DBLogName , SIZE = 2048KB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%)
GO

You have to use dynamic SQL. Also, you need to replace text with nvarchar(max) otherwise text concatenation won't work.
Here is full script for you:
DECLARE #DBNAME sysname;
SET #DBNAME = 'MyDataBase'
DECLARE #DBFullName sysname;
SET #DBFullName = 'MySuperDataBase';
DECLARE #DBFileName nvarchar(max);
SET #DBFileName = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.DEVELOPMENT\MSSQL\DATA\' + #DBName + '.mdf';
DECLARE #DBLogName nvarchar(max);
SET #DBLogName = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.DEVELOPMENT\MSSQL\DATA\' + #DBName + '.ldf';
DECLARE #SQL nvarchar(max);
SET #SQL = N'
CREATE DATABASE ' + QUOTENAME(#DBNAME) + ' ON PRIMARY
(NAME = ' + QUOTENAME(#DBFullName + '_Data') + ',
FILENAME = ' + QUOTENAME(#DBFileName, '''') + ',
SIZE = 30720KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 10%)
LOG ON (
NAME = ' + QUOTENAME(#DBFullName + '_Log') + ',
FILENAME = ' + QUOTENAME(#DBLogName, '''') + ',
SIZE = 2048KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 10%)'
PRINT #SQL
EXEC (#SQL)
GO
Works on my machine! :)

Related

Passing a file path as a variable in SQL Server

I'm trying to add a file to a file group in order to create a partition in SQL Server. When I pass in a hardcoded file path to the the filename, the code works. But when I use a variable for the file path, I get an error
Incorrect syntax near #FilePath or Unexpected symbol #FilePath
This is my code:
USE StudentRepository
BEGIN
SET NOCOUNT ON;
DECLARE #FilePath NVARCHAR(MAX) = "C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLEXPRESS\MSSQL\DATA\",
#FileName NVARCHAR(MAX) = "FirstTerm2020",
#FileExt NVARCHAR(MAX) = ".NDF";
DECLARE #count INT = 0;
ALTER DATABASE StudentRepository
ADD FILE
(
NAME = 'FirstTerm2020',
FILENAME = #FilePath + #FileName + #FileExt, --Error here!
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP FirstTerm2020
END
When I pass a hardcoded file path to the filename, it works and creates the required partitions. as below
--Code omitted for brevity
FILENAME = "C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLEXPRESS\MSSQL\DATA\FirstTerm2020.NDF" --No error!
Please I need some help. How do I pass a file path as a variable?
This is how I solved the problem. I create a dynamic sql and passed the filepath variable like this.
USE StudentRepository
BEGIN
SET NOCOUNT ON;
DECLARE #FilePath NVARCHAR(MAX) = 'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLEXPRESS\MSSQL\DATA\',
#FileName NVARCHAR(MAX) = 'SecondTerm2022',
#FileExt NVARCHAR(MAX) = '.NDF';
DECLARE #count INT = 0;
DECLARE #sql NVARCHAR(MAX) = '
ALTER DATABASE StudentRepository ADD FILEGROUP ' + #FileName + ';
ALTER DATABASE StudentRepository
ADD FILE
(
NAME = '+ #FileName + ',
FILENAME = ''' + #FilePath + #FileName + #FileExt + ''',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP '+ #FileName
END
EXEC sp_executesql #sql
My major problem was that I was ommitting the three single quotes near #FilePath

Is there a function to compress 'bak' file in sql script?

In SQL Server, I want to clear personal info and backup it
Backup original DB
Restore as another DB name
Clear personal info in another DB
Backup another DB
Delete rest files
Zip Backup DB
I finished 1~5. but couldn't find a way to do 6.
I Want to compress bak file to zip here.
For instance, below code can be used in Powershell script. Is there a way to use this .Net function in SQL script?
[System.IO.Compression.ZipFile]::CreateFromDirectory($CurrentPath, $DeployHistoryFilePath)
Below is my full script.
DECLARE #DBName NVARCHAR(MAX) = N'TestDB'
DECLARE #BackupPath NVARCHAR(MAX) = N'D:\Database\Backup'
EXEC ('master.dbo.xp_create_subdir N'''+ #BackupPath +'''')
DECLARE #BackupName NVARCHAR(MAX) = N'OnCube_' + REPLACE(REPLACE(REPLACE(CONVERT(NVARCHAR(MAX), GETDATE(), 120), N'-', N''), N':', N''), N' ', N'_')
DECLARE #DiskFile NVARCHAR(MAX) = #BackupPath + N'\' + #BackupName + N'.bak'
BACKUP DATABASE #DBName TO DISK = #DiskFile
DECLARE #SQL NVARCHAR(MAX) = 'SELECT TOP (1) #OriginalMdf = name FROM ' + #DBName + '.sys.database_files WHERE file_id = 1'
DECLARE #OriginalMdf NVARCHAR(MAX)
EXEC sp_executesql #SQL, N'#OriginalMdf NVARCHAR(MAX) OUT', #OriginalMdf out
SET #SQL = 'SELECT TOP (1) #OriginalLdf = name FROM ' + #DBName + '.sys.database_files WHERE file_id = 2'
DECLARE #OriginalLdf NVARCHAR(MAX)
EXEC sp_executesql #SQL, N'#OriginalLdf NVARCHAR(MAX) OUT', #OriginalLdf out
DECLARE #PartialMdf NVARCHAR(MAX) = #BackupPath + N'\' + #BackupName + N'.mdf'
DECLARE #PartialLdf NVARCHAR(MAX) = #BackupPath + N'\' + #BackupName + N'_0.ldf'
RESTORE FILELISTONLY FROM DISK = #DiskFile
RESTORE DATABASE #BackupName
FROM DISK = #DiskFile
WITH MOVE #OriginalMdf TO #PartialMdf,
MOVE #OriginalLdf TO #PartialLdf
EXEC (N'
USE [' + #BackupName + ']
UPDATE Person
SET
PatientNo = NULL
, PatientName = N''Cleared'' + CONVERT(NVARCHAR(MAX), RawID)
, RoomNo = NULL
, BedNo = NULL
, Birthday = NULL
, Sex = NULL
, Address = NULL
, AdmitDate = NULL
, AdmitNo = NULL
, Description = NULL
, DischargedDate = NULL
')
DECLARE #ClearedDiskFile NVARCHAR(MAX) = #BackupPath + N'\' + #BackupName + N'_PatientInfoCleared.bak'
BACKUP DATABASE #BackupName TO DISK = #ClearedDiskFile
EXEC('DROP DATABASE [' + #BackupName + ']')
EXEC ('xp_cmdshell ''del "' + #DiskFile + '"''')
-- I Want to compress bak file to zip here
-- For instance, below code can be used in Powershell script. Is there a way to use this .Net function in SQL script?
-- [System.IO.Compression.ZipFile]::CreateFromDirectory($CurrentPath, $DeployHistoryFilePath)
PRINT N'Success to make ' + #ClearedDiskFile + '. Patient informations are all cleared'
Is there a way to use this .Net function in SQL script?
Yes, you can use SQL CLR with C#
see samples Using 7-zip and SharpZipLib here:
also , you can create zip file from SQL without Powershell script:
Create zip file from SQL Server

T-SQL Restore Databases with script and variables

There is something going wrong, but can't find the mistake...
I want to restore a database in a procedure, but can't do this with variables...
DECLARE #sql as NVARCHAR(1000)
DECLARE #targetDBname as NVARCHAR(20) = 'BO_9999'
DECLARE #backupFileNamePath as NVARCHAR(100) = '\\SRV015\C$\temp\BO_1767_Schulung_2016-07-13_22-36-28.bak'
DECLARE #masterDBname as NVARCHAR(20) = 'BO_1767_Schulung'
DECLARE #targetMDFfilePath as NVARCHAR(100) = 'Y:\CADTOOLS\DB\BO_9999.mdf'
DECLARE #masterLogname as NVARCHAR(30)= 'BO_1767_Schulung_log'
DECLARE #targetLogFilePath as NVARCHAR(100) = 'Y:\CADTOOLS\LOG\BO_9999_log.LDF'
SET #sql = '''RESTORE DATABASE ' + #targetDBname
SET #sql = #sql + ' FROM DISK = ''''' + #backupFileNamePath + ''''''
SET #sql = #sql + ' WITH FILE = 1'
SET #sql = #sql + ', MOVE ''''' + #masterDBname + ''''''
SET #sql = #sql + ' TO ''''' + #targetMDFfilePath + ''''''
SET #sql = #sql + ', MOVE ''''' + #masterLogname + ''''''
SET #sql = #sql + ' TO ''''' + #targetLogFilePath + ''''''
SET #sql = #sql + ', NOUNLOAD, REPLACE, STATS = 10'''
PRINT #sql
EXEC (#sql)
--THIS COMMAND RUNS BUT I CANT GET THE COMMAND IN AN EXEC WITH VARIABLES
--RESTORE DATABASE BO_9999 FROM DISK = '\\SRV015\C$\temp\BO_1767_Schulung_2016-07-13_22-36-28.bak' WITH FILE = 1, MOVE 'BO_1767_Schulung' TO 'Y:\CADTOOLS\DB\BO_9999.mdf', MOVE 'BO_1767_Schulung_log' TO 'Y:\CADTOOLS\LOG\BO_9999_log.LDF', NOUNLOAD, REPLACE, STATS = 10
Can anybody help me... was still looking lot's of pages in the net... but couldn't get this run?!
THANKS #all
it runns this way:
RESTORE DATABASE BO_9999 FROM DISK = '\SRV015\C$\temp\BO_1767_Schulung_2016-07-13_22-36-28.bak' WITH FILE = 1, MOVE 'BO_1767_Schulung' TO 'Y:\CADTOOLS\DB\BO_9999.mdf', MOVE 'BO_1767_Schulung_log' TO 'Y:\CADTOOLS\LOG\BO_9999_log.LDF', NOUNLOAD, REPLACE, STATS = 10
and this way:
RESTORE DATABASE #targetDBname FROM DISK = #backupFileNamePath WITH FILE = 1, MOVE #masterDBname TO #targetMDFfilePath, MOVE #masterLogname TO #targetLogFilePath, NOUNLOAD, REPLACE, STATS = 10
but in the end i need it like this to run it on another linked server
EXEC (#sql) at [server\instance]
???

How to create 20 databases at a time in sqlserver?

I have written the following procedure to create a series of 20 databases.
But it is not creating them. The database is not created even when I go to my H: drive and didnot find the ldf and mdf named bharath1 bharath2 like...
What did I do wrong with this?
USE master
GO
DECLARE #command varchar(1000), #i int
while #i < 5
SET #command = 'CREATE DATABASE Bharath' + CAST(#i AS varchar) + '
ON ( NAME = ''Bharath_dat'',
FILENAME = ''H:\MSSQL10.MSSQLSERVER\MSSQL10.MSSQLSERVER\MSSQL\DATA\Bharath' +
CAST(#i AS varchar) + '.mdf'', SIZE = 10, MAXSIZE = 50, FILEGROWTH = 5 )
LOG ON ( NAME = ''Bharath_log'',
FILENAME = ''H:\MSSQL10.MSSQLSERVER\MSSQL10.MSSQLSERVER\MSSQL\DATA\Bharath' +
CAST(#i AS varchar) + '.ldf'', SIZE = 5MB, MAXSIZE = 25MB, FILEGROWTH = 5MB )'
EXEC (#command)
SET #i = #i + 1
GO
I don't have any idea in SQL Server stored procedure as of my knowledge and with somebody support i did like this. But i am not finding any databases.
Any help greatly appreciated.
OK, I don't see the BEGIN and END block right after the WHILE loop which may cause SQL to do an endless loop to run a SET #command statement only.
You need to enclose the WHILE with BEGIN and END...
DECLARE #command as varchar(1000), #i int
SET #i = 0
WHILE #i < 5
BEGIN
SET #command = 'CREATE DATABASE Example' + CAST(#i AS varchar)
EXEC(#command)
SET #i = #i + 1
END
This works for me. (SET #i = 0 is a must)
YOu need to initialise #i, add this after your declare:
SET #i = 1
There's a few things you've missed - you first of all need to put your several SQL command that you want to execute over and over again into a BEGIN......END block.
Second, you need to initialize your #i counter! Otherwise, it'll never get into that WHILE loop in the first place.
And thirdly, your CREATE DATABASE call was wrong - you need to specify a filegroup where to create the database (CREATE DATABASE (name) ON (filegroup) .......).
Here's my code:
USE master
GO
DECLARE #command varchar(1000), #instanceName VARCHAR(100), #i int
SET #i = 1
WHILE #i <= 5
BEGIN
SET #instanceName = 'Bharath' + CAST(#i AS VARCHAR(10))
SET #command = 'CREATE DATABASE ' + #instanceName +
' ON PRIMARY ( NAME = N''' + #instanceName + ''', ' +
'FILENAME = ''H:\MSSQL10.MSSQLSERVER\MSSQL10.MSSQLSERVER\MSSQL\DATA\' +
#instanceName + '.mdf'', SIZE = 10, MAXSIZE = 50, FILEGROWTH = 5 ) ' +
'LOG ON ( NAME = N''' + #instanceName + '_LOG'', ' +
'FILENAME = ''H:\MSSQL10.MSSQLSERVER\MSSQL10.MSSQLSERVER\MSSQL\DATA\' +
#instanceName + '.ldf'', SIZE = 5MB, MAXSIZE = 25MB, FILEGROWTH = 5MB )'
EXEC (#command)
SET #i = #i + 1
END
GO

Create a database using T SQL on a specified location

How to create a database using T SQL script on a specified location? Let's say, I want to create a SQL server database on D:\temp\dbFolder. How to do this?
When you create the new database you specify the location. For example:
USE [master]
GO
CREATE DATABASE [AdventureWorks] ON PRIMARY
( NAME = N'AdventureWorks_Data', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorks_Data.mdf' , SIZE = 167872KB , MAXSIZE = UNLIMITED, FILEGROWTH = 16384KB )
LOG ON
( NAME = N'AdventureWorks_Log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorks_Log.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 16384KB )
GO
From the SQL Server Books an example where database filenames are explicitely defined:
USE master
GO
CREATE DATABASE Sales
ON
( NAME = Sales_dat,
FILENAME = 'c:\program files\microsoft sql server\mssql\data\saledat.mdf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 )
LOG ON
( NAME = 'Sales_log',
FILENAME = 'c:\program files\microsoft sql server\mssql\data\salelog.ldf',
SIZE = 5MB,
MAXSIZE = 25MB,
FILEGROWTH = 5MB )
GO
Create folder on your file system: D:\temp\dbFolder\
Run the script:
USE master;
GO
CREATE DATABASE TestDB1
ON ( NAME = Sales_dat, FILENAME = 'D:\temp\dbFolder\TestDB1.mdf')
LOG ON ( NAME = Sales_log, FILENAME = 'D:\temp\dbFolder\TestDB1.ldf');
GO
Using variables in Studio Manager expanding on the previous examples.
Create folders and subfolders.
Example: root folder E:\MSSQL\DATA
subfolders E:\MSSQL\DATA\DB and E:\MSSQL\DATA\Logs.
MKDIR "E:\MSSQL\DATA\DB"
MKDIR "E:\MSSQL\DATA\Logs"
Change Database name #DBNAME variable #Test_DB' to your 'DesiredName_DB'
Change Root folder path #DataPath 'E:\MSSQL\DATA' to your as per above created folders.
Run the below in Studio Manager
DECLARE #DBNAME VARCHAR(MAX)
DECLARE #DataPath AS NVARCHAR(MAX)
DECLARE #sql VARCHAR(MAX)
SET #DBNAME = N'Test_DB'
SET #DataPath = N'E:\MSSQL\DATA'
SELECT #sql = 'USE MASTER'
EXEC (#sql)
SELECT #sql = 'CREATE DATABASE '+ quotename(#DBNAME) + '
ON
PRIMARY
(
NAME = ''' + #DBNAME + '_DB'',
FILENAME = ''' + #DataPath + '\DB\' + #DBNAME + '.mdf'',
SIZE = 3136 KB , MAXSIZE = UNLIMITED,
FILEGROWTH = 1024 KB
)
LOG ON
(
NAME = '''+ #DBNAME + '_Log'',
FILENAME = '''+ #DataPath + '\Logs\' + #DBNAME + '_log.ldf'',
SIZE = 832KB , MAXSIZE = 2048 GB , FILEGROWTH = 10 %
)'
EXEC (#sql)
Or another variation on the above theme.
DECLARE #DBNAME VARCHAR(MAX)
DECLARE #DataFilePath AS NVARCHAR(MAX)
DECLARE #LogFilePath AS NVARCHAR(MAX)
DECLARE #sql VARCHAR(MAX)
SET #DBNAME = N'Test_DB'
SET #DataFilePath = N'E:\MSSQL\DATA\DB\'
SET #LogFilePath = N'E:\MSSQL\DATA\Logs\'
SELECT #sql = 'USE MASTER'
EXEC (#sql)
SELECT #sql = 'CREATE DATABASE '+ quotename(#DBNAME) + '
ON
PRIMARY
(
NAME = ''' + #DBNAME + '_DB'',
FILENAME = ''' + #DataFilePath + #DBNAME + '.mdf'',
SIZE = 3136 KB , MAXSIZE = UNLIMITED,
FILEGROWTH = 1024 KB
)
LOG ON
(
NAME = '''+ #DBNAME + '_Log'',
FILENAME = '''+ #LogFilePath+ #DBNAME + '_log.ldf'',
SIZE = 832KB , MAXSIZE = 2048 GB , FILEGROWTH = 10 %
)'
EXEC (#sql)
See this link : CREATE DATABASE (Transact-SQL)
CREATE DATABASE [ADestinyDb] CONTAINMENT = NONE ON PRIMARY
( NAME = N'ADestinyDb',
FILENAME = N'D:\temp\dbFolder\ADestinyDb.mdf' ,
SIZE = 3136 KB , MAXSIZE = UNLIMITED,
FILEGROWTH = 1024 KB )
LOG ON
( NAME = N'ADestinyDb_log',
FILENAME = N'D:\temp\dbFolder\_log.ldf' ,
SIZE = 832KB , MAXSIZE = 2048 GB , FILEGROWTH = 10 %)
Create folder on your file system: D:\temp\dbFolder\ and run the below script
(try 'sa' login)
USE master
CREATE DATABASE [faltu] ON PRIMARY
( NAME = N'faltu', FILENAME = N'D:\temp\dbFolder\faltu.mdf' , SIZE = 2048KB , FILEGROWTH = 1024KB )
LOG ON
( NAME = N'faltu_log', FILENAME = N'D:\temp\dbFolder\faltu_log.ldf' , SIZE = 1024KB , FILEGROWTH = 10%)

Resources