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
Related
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
How to implement a for each loop in SQL?
I am looking for a way to automate the backing up of databases for SQL Server 2019 to a given folder, with the following name syntax:
<Date><DB Name>
I am hoping to be able to a list of all databases in a temporary table:
DECLARE #DBList TABLE (DBName VARCHAR(40))
INSERT INTO #DBList
SELECT name
FROM master.dbo.sysdatabases
and then run each record agents function.
At the moment this is how I do it. It works is a vile violation of the write-once principle
-- Initialize variables
DECLARE #Date NVARCHAR(MAX) = CONVERT(VARCHAR, GETDATE(), 112);
DECLARE #DBName SYSNAME;
DECLARE #Path NVARCHAR(MAX);
USE [master];
-- BackUp Database
SET #DBName = 'DATABASE01';
SET #Path = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\' + #Date + #DBName +'.bak';
BACKUP DATABASE #DBName TO DISK = #Path;
SET #DBName = 'DATABASE02';
SET #Path = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\' + #Date + #DBName +'.bak';
BACKUP DATABASE #DBName TO DISK = #Path;
SET #DBName = 'DATABASE03';
SET #Path = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\' + #Date + #DBName +'.bak';
BACKUP DATABASE #DBName TO DISK = #Path;
SET #DBName = 'DATABASE04';
SET #Path = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\' + #Date + #DBName +'.bak';
BACKUP DATABASE #DBName TO DISK = #Path;
SET #DBName = 'DATABASE05';
SET #Path = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\' + #Date + #DBName +'.bak';
BACKUP DATABASE #DBName TO DISK = #Path;
You can make use of loop in this way.
You need to create some sort of ranking to go through each row, and then get the value based on current rank.
DECLARE #DBList TABLE (DBName varchar(40),rankvalue int)
insert into #DBList SELECT name, DENSE_RANK() over (order by name) rankval FROM master.dbo.sysdatabases
Declare #Date NVARCHAR(max) = convert(varchar, getdate(), 112);
DECLARE #DBName SYSNAME;
DECLARE #Path NVARCHAR(MAX);
Declare #current int = 1 , #maxvalue int =(select max(rankvalue) from #DBList)
while #current <= #maxvalue
begin
Set #DBName = (select DBName from #DBList where rankvalue = #current)
Set #Path = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\' + #Date + #DBName +'.bak';
BACKUP DATABASE #DBName TO DISK = #Path
set #current = #current + 1
end
I am trying to execute the below script to get the mdf and ldf file details from a .back file. It throws an error
Incorrect syntax at H.
Declare #backupPath NVARCHAR(300);
set #backupPath =N'H:\path\of\backupfile.bak';
declare #qry NVARCHAR(max) = N'RESTORE FILELISTONLY from disk = ';
set #qry = #qry + #backupPath ;
exec(#qry)
When I tried with the below line
set #qry = 'Restore filelistonly from #backuppath'
it would throw the error "declare scalar variable #qry.
Please help.
If you print #qry you will see that syntax is wrong, the quotes are missing.
Try this:
Declare #backupPath NVARCHAR(300);
set #backupPath =N'''H:\path\of\backupfile.bak''';
declare #qry NVARCHAR(max) = N'RESTORE FILELISTONLY from disk = ';
set #qry = #qry + #backupPath ;
exec(#qry)
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! :)
I have simple code
: CREATE DATABASE [asst]
: ON (NAME = 'asst_dat', FILENAME = 'C:\data' , SIZE = 62, FILEGROWTH = 10%)
: LOG ON (NAME = 'asst_log', FILENAME = 'C:\data' , SIZE = 146, FILEGROWTH = 10%)
How can I change the FILENAME parameter to create DB in the default installation path like C:\Program Files\Microsoft SQL Server\MSSQL10_50.ATASSIST\MSSQL. So why I need it: from version to version, from instance to instance of SQL Server this locations differs
First create the database and then alter file properties as needed.
CREATE DATABASE [DBName]
GO
ALTER DATABASE [DBName] MODIFY FILE
( NAME = N'DBName' , SIZE = 512MB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
GO
ALTER DATABASE [DBName] MODIFY FILE
( NAME = N'DBName_log' , SIZE = 256MB , MAXSIZE = UNLIMITED , FILEGROWTH = 10%)
GO
You can use the following variables, that respectively contain the root directory of your install and the data directory :
SELECT ##basedir, ##datadir;
Thanks, überjesus, I've simplified your code a little bit
DECLARE #rows varchar(MAX),
#script nvarchar(MAX);
SET #rows = (SELECT physical_name AS current_file_location
FROM sys.master_files
where name = 'master');
SET #rows = Replace(#rows, 'master.mdf', '')
SELECT #rows;
set #script = 'CREATE DATABASE [assist1]
ON (NAME = ''asst_dat'', FILENAME = ''' + #rows + 'assist1.mdf'' , SIZE = 62, FILEGROWTH = 10%)
LOG ON (NAME = ''asst_log'', FILENAME = ''' + #rows + 'assist1_log.ldf'' , SIZE = 146, FILEGROWTH = 10%);'
exec(#script);
Thanks for a great idea!
try this
You can create a database without specifying file details, like:
CREATE DATABASE DatabaseName;
Assuming you are using SQL Server 2005 or 2008 this should do it. Although it's probably a bit longer than you expected :-) You could put the main part of the code into a function and call that every time you need to create a database.
declare #instance_name nvarchar(200),
#system_instance_name nvarchar(200),
#registry_key nvarchar(512),
#path_data nvarchar(260),
#path_log nvarchar(260),
#value_name nvarchar(20),
#script nvarchar(4000);
set #instance_name = coalesce(convert(nvarchar(20), serverproperty('InstanceName')), 'MSSQLSERVER');
exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\Microsoft SQL Server\Instance Names\SQL', #instance_name, #system_instance_name output;
set #registry_key = N'Software\Microsoft\Microsoft SQL Server\' + #system_instance_name + '\MSSQLServer';
/* determine default location for data files */
exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', #registry_key, N'DefaultData', #path_data output;
if #path_data is null
begin
/* this is only executed if we are using the default instance */
set #registry_key = N'Software\Microsoft\Microsoft SQL Server\' + #system_instance_name + '\Setup';
exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', #registry_key, N'SQLDataRoot', #path_data output;
set #path_data = #path_data + '\Data';
end;
/* determine default location for log files */
exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', #registry_key, N'DefaultLog', #path_log output;
if #path_log is null
begin
/* this is only executed if we are using the default instance */
set #registry_key = N'Software\Microsoft\Microsoft SQL Server\' + #system_instance_name + '\Setup';
exec master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', #registry_key, N'SQLDataRoot', #path_log output;
set #path_log = #path_log + '\Data';
end;
set #script = 'CREATE DATABASE [asst]
ON (NAME = ''asst_dat'', FILENAME = ''' + #path_data + '\yourfile.mdf'' , SIZE = 62, FILEGROWTH = 10%)
LOG ON (NAME = ''asst_log'', FILENAME = ''' + #path_log + '\yourfile.ldf'' , SIZE = 146, FILEGROWTH = 10%);'
exec(#script);
You can not use variables in the CREATE DABASE statement. That's why you have to create a variable that holds the command and execute that as a script.