Unable to delete zip files from DB server location using xp_cmdshell - sql

I have a Zip file created and I am unable to delete it using the below command.
xp_cmdshell 'rm "F:\EXIS\Reports\Individual.zip"'
It gives an error saying File not found, when I can actually see the file.
I tried using xp_cmdshell 'del "F:\EXIS\Reports\Individual.zip"'
But, this asks for a confirmation, which I actually cannot input.
Please suggest if anything,
Thanks.

The message is more generic in the sense the file is not found with the current credentials of SQL Server process while accessing the indicated location.
I suspect it is a problem of rights, so please assure the SQL Server proecess has rights to delete file in that location. An alternative suggestion is to perform a "dir" on that location.

Try executing delin silent mode like:
xp_cmdshell 'del /Q "F:\EXIS\Reports\Individual.zip"'
And also: if SQL Server is running on a different machine the path must of course be valid for that machine.

--change server configuration like :
--Script to enable the XP_CMDSHELL
-- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1 GO
-- To update the currently configured value for advanced options.
RECONFIGURE GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1 GO
-- To update the currently configured value for this feature.
RECONFIGURE GO;
DECLARE #BackUpPath varchar(255) ,#sqlQuery varchar(255)
Set #BackUpPath='D:\All DB BackUp\TestDB.bak'
IF dbo.fn_FileExists(#BackUpPath)=1
BEGIN
SET #sqlQuery='DEL /Q "' + #BackUpPath + '"';
PRINT #sqlQuery
EXEC master..xp_cmdshell #sqlQuery
IF dbo.fn_FileExists(#BackUpPath)=0
BEGIN
PRINT 'File Deleted'
END
ELSE
BEGIN
PRINT 'File not Deleted'
END
END
IF #BackUpPath contains space , you must type your path like "your
path"

Related

Move text file from one folder to another folder using sql script

I have been using the following sql script to move file from one location to another .
EXEC
master.dbo.sp_configure 'show advanced options', 1
RECONFIGURE
EXEC
master.dbo.sp_configure 'xp_cmdshell', 1
RECONFIGURE
DECLARE #cmd nvarchar(500), #folderName varchar(100),#move varchar(100),#destinationpath varchar(50)
SET #folderName = 'Newfolder_' + REPLACE(CONVERT(varchar(10), GETDATE(), 101), '/', '')
SET #cmd = 'mkdir C:\FileDestination\' + #folderName
EXEC master..xp_cmdshell #cmd --- this will create folder(newfolder_mmddyyy)
set #destinationpath='C:\FileDestination\'+#folderName
set #move ='move c:\filesource\* '+ #destinationpath
exec master.dbo.xp_cmdshell #move ---this will move files to newly created folder
But it's showing the error as follows
The system cannot find the file specified.
Can any one let me know the solution for this. Thanks Alot for your help !
If "filesource" and "FileDestination" are example folder locations, then it could be that the variable for the move command is too small. Try making it the same as #cmd, i.e. #move nvarchar(500)
It seems to be the access issue on the filesource folder, try giving full access to everyone on the folder.
I tried the exact code on my system and it works fine for me (moved test file).

how to break text in field when copy to notepad in sql server

I use char(13) and char(10) for break text in sql server.
I want when copy text filed content top the notepad , text in break.
I use below code to break line :
declare #result varchar(30)='this is some'+ char(13)+char(10)+'text'
but when I copy text to notepad all text show in a line .
how can I do this ?
I searched in google , but cant find any similar answer.
it have to work:
just try this one, (using only one of char(13) or char(10) also gives same output)
declare #result varchar(30)='this is some'+char(13)+char(10)+'text'
print #result
Output:(copied exact output from my window)
this is some
text
but for getting the result to notepad(windows) don't copy/past from the displayed grid within management studio use xp_cmdshell as below:
master..xp_cmdshell 'bcp "SELECT ''this is some''+char(13)+char(10)+''text''" queryout C:\myText.txt -t, -c -Slocalhost -T'
exact content:
this is some
text
Note: you may need to enable xp_cmdshell:
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO

Exec master..xp_cmdshell 'Del...' is not working

I'm trying to delete a excel file using xp_cmdshell, but is not working... I check the other questions of here but I can't solve my issue, I activated the advanced options of SQL SERVER to allow this sintax, but it show's me a error message like this:
No se encuentra C:\xampp\htdocs\Web_Seguimiento\Body\Upload\Files\Carga
No se encuentra C:\WINDOWS\system32\Masiva
NULL
My code:
---- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured value for this feature.
RECONFIGURE
GO
declare #sqlquery varchar(255)
declare #name varchar(255)
set #name = 'Carga Masiva Usuarios General.xlsx'
set #sqlquery= 'Del C:\xampp\htdocs\Web_Seguimiento\Body\Upload\Files\'+#name +''
exec master..xp_cmdshell #sqlquery
Can anybody tell me what I do wrong, or how can I solve this issue...???
Try putting quotes around the file name, like this:
set #sqlquery= 'Del "C:\xampp\htdocs\Web_Seguimiento\Body\Upload\Files\'+#name +'"'

SQL Server Management Studio -- Script that executes other scripts?

So I have been looking around for a way to develop a script that will execute other scripts from within my project folder using SQL Server Management Studio and so far none of the other solutions have worked. I tried writing a script that had the sqlcommandline stuff in it:
sqlcmd -S.\SQLExpress -imyScript.sql;
and that didn't work and from my understanding using #\path\to\script.sql won't work either so any other ideas? Or should I start looking into writing a procedure? In which case, could anybody point me in the right direction?
Thank you in advance for any assistance.
Personally, I'd look into writing stored procedures. The MSDN documentation is good and there are lots of resources on line if you do a quick search.
Alternatively you could do something like this to MAKE it happen (you'll need to have permission to execute command shell, etc):
CREATE TABLE ##SQLFiles ( SQLFileName VARCHAR(2000))
GO
INSERT INTO ##SQLFiles
EXECUTE master.dbo.xp_cmdshell 'dir /b "C:\SQL Scripts\*.sql"'
GO
DECLARE cFiles CURSOR LOCAL FOR
SELECT DISTINCT [SQLFileName]
FROM ##SQLFiles
WHERE [SQLFileName] IS NOT NULL AND
[SQLFileName] != 'NULL'
ORDER BY [SQLFileName]
DECLARE #vFileName VARCHAR(200)
DECLARE #vSQLStmt VARCHAR(4000)
OPEN cFiles
FETCH NEXT FROM cFiles INTO #vFileName
WHILE ##FETCH_STATUS = 0
BEGIN
-- The following SET command must be on a single line or else an error will be generated.
-- It is split in this script for readability purposes.
SET #vSQLStmt = 'master.dbo.xp_cmdshell ''osql -S Server Name -U User Name -P Password
-d Database Name -i "C:\SQL Scripts\' + #vFileName + '"'''
EXECUTE (#vSQLStmt)
FETCH NEXT FROM cFiles INTO #vFileName
END
CLOSE cFiles
DEALLOCATE cFiles
GO
DROP TABLE ##SQLFiles
GO

How do I find the data directory for a SQL Server instance?

We have a few huge databases (20GB+) which mostly contain static lookup data. Because our application executes joins against tables in these databases, they have to be part of each developers local SQL Server (i.e. they can't be hosted on a central, shared database server).
We plan on copying a canonical set of the actual SQL Server database files (*.mdf and *.ldf) and attach them to each developer's local database.
What's the best way to find out the local SQL Server instance's data directory so we can copy the files to the right place? This will be done via an automated process, so I have to be able to find and use it from a build script.
It depends on whether default path is set for data and log files or not.
If the path is set explicitly at Properties => Database Settings => Database default locations then SQL server stores it at Software\Microsoft\MSSQLServer\MSSQLServer in DefaultData and DefaultLog values.
However, if these parameters aren't set explicitly, SQL server uses Data and Log paths of master database.
Bellow is the script that covers both cases. This is simplified version of the query that SQL Management Studio runs.
Also, note that I use xp_instance_regread instead of xp_regread, so this script will work for any instance, default or named.
declare #DefaultData nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultData', #DefaultData output
declare #DefaultLog nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultLog', #DefaultLog output
declare #DefaultBackup nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'BackupDirectory', #DefaultBackup output
declare #MasterData nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer\Parameters', N'SqlArg0', #MasterData output
select #MasterData=substring(#MasterData, 3, 255)
select #MasterData=substring(#MasterData, 1, len(#MasterData) - charindex('\', reverse(#MasterData)))
declare #MasterLog nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer\Parameters', N'SqlArg2', #MasterLog output
select #MasterLog=substring(#MasterLog, 3, 255)
select #MasterLog=substring(#MasterLog, 1, len(#MasterLog) - charindex('\', reverse(#MasterLog)))
select
isnull(#DefaultData, #MasterData) DefaultData,
isnull(#DefaultLog, #MasterLog) DefaultLog,
isnull(#DefaultBackup, #MasterLog) DefaultBackup
You can achieve the same result by using SMO. Bellow is C# sample, but you can use any other .NET language or PowerShell.
using (var connection = new SqlConnection("Data Source=.;Integrated Security=SSPI"))
{
var serverConnection = new ServerConnection(connection);
var server = new Server(serverConnection);
var defaultDataPath = string.IsNullOrEmpty(server.Settings.DefaultFile) ? server.MasterDBPath : server.Settings.DefaultFile;
var defaultLogPath = string.IsNullOrEmpty(server.Settings.DefaultLog) ? server.MasterDBLogPath : server.Settings.DefaultLog;
}
It is so much simpler in SQL Server 2012 and above, assuming you have default paths set (which is probably always a right thing to do):
select
InstanceDefaultDataPath = serverproperty('InstanceDefaultDataPath'),
InstanceDefaultLogPath = serverproperty('InstanceDefaultLogPath')
Even though this is a very old thread, I feel like I need to contribute a simple solution.
Any time that you know where in Management Studio a parameter is located that you want to access for any sort of automated script, the easiest way is to run a quick profiler trace on a standalone test system and capture what Management Studio is doing on the backend.
In this instance, assuming you are interested in finding the default data and log locations you can do the following:
SELECT
SERVERPROPERTY('instancedefaultdatapath') AS [DefaultFile],
SERVERPROPERTY('instancedefaultlogpath') AS [DefaultLog]
I stumbled across this solution in the documentation for the Create Database statement in the help for SQL Server:
SELECT SUBSTRING(physical_name, 1, CHARINDEX(N'master.mdf', LOWER(physical_name)) - 1)
FROM master.sys.master_files
WHERE database_id = 1 AND file_id = 1
For the current database you can just use:
select physical_name fromsys.database_files;
to specify another database e.g. 'Model', use sys.master_files
select physical_name from sys.master_files where database_id = DB_ID(N'Model');
As of Sql Server 2012, you can use the following query:
SELECT SERVERPROPERTY('INSTANCEDEFAULTDATAPATH') as [Default_data_path], SERVERPROPERTY('INSTANCEDEFAULTLOGPATH') as [Default_log_path];
(This was taken from a comment at http://technet.microsoft.com/en-us/library/ms174396.aspx, and tested.)
Various components of SQL Server (Data, Logs, SSAS, SSIS, etc) have a default directory. The setting for this can be found in the registry. Read more here:
http://technet.microsoft.com/en-us/library/ms143547%28SQL.90%29.aspx
So if you created a database using just CREATE DATABASE MyDatabaseName it would be created at the path specified in one of the settings above.
Now, if the admin / installer changed the default path, then the default path for the instance is stored in the registry at
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\[INSTANCENAME]\Setup
If you know the name of the instance then you can query the registry. This example is SQL 2008 specific - let me know if you need the SQL2005 path as well.
DECLARE #regvalue varchar(100)
EXEC master.dbo.xp_regread #rootkey='HKEY_LOCAL_MACHINE',
#key='SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.MSSQLServer\Setup',
#value_name='SQLDataRoot',
#value=#regvalue OUTPUT,
#output = 'no_output'
SELECT #regvalue as DataAndLogFilePath
Each database can be created overriding the server setting in a it's own location when you issue the CREATE DATABASE DBName statement with the appropriate parameters. You can find that out by executing sp_helpdb
exec sp_helpdb 'DBName'
Keeping it simple:
use master
select DB.name, F.physical_name from sys.databases DB join sys.master_files F on DB.database_id=F.database_id
this will return all databases with associated files
From the GUI: open your server properties, go to Database Settings, and see Database default locations.
Note that you can drop your database files wherever you like, though it seems cleaner to keep them in the default directory.
Small nitpick: there is no data folder, only a default data folder.
Anyway, to find it, assuming you want to install for the first default instance:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\Setup\SQLDataRoot
If there's a named instance, MSSQL.1 becomes something like MSSQL10.INSTANCENAME.
You can find default Data and Log locations for the current SQL Server instance by using the following T-SQL:
DECLARE #defaultDataLocation nvarchar(4000)
DECLARE #defaultLogLocation nvarchar(4000)
EXEC master.dbo.xp_instance_regread
N'HKEY_LOCAL_MACHINE',
N'Software\Microsoft\MSSQLServer\MSSQLServer',
N'DefaultData',
#defaultDataLocation OUTPUT
EXEC master.dbo.xp_instance_regread
N'HKEY_LOCAL_MACHINE',
N'Software\Microsoft\MSSQLServer\MSSQLServer',
N'DefaultLog',
#defaultLogLocation OUTPUT
SELECT #defaultDataLocation AS 'Default Data Location',
#defaultLogLocation AS 'Default Log Location'
Expanding on "splattered bits" answer, here is a complete script that does it:
#ECHO off
SETLOCAL ENABLEDELAYEDEXPANSION
SET _baseDirQuery=SELECT SUBSTRING(physical_name, 1, CHARINDEX(N'master.mdf', LOWER(physical_name)) - 1) ^
FROM master.sys.master_files WHERE database_id = 1 AND file_id = 1;
ECHO.
SQLCMD.EXE -b -E -S localhost -d master -Q "%_baseDirQuery%" -W >data_dir.tmp
IF ERRORLEVEL 1 ECHO Error with automatically determining SQL data directory by querying your server&ECHO using Windows authentication.
CALL :getBaseDir data_dir.tmp _baseDir
IF "%_baseDir:~-1%"=="\" SET "_baseDir=%_baseDir:~0,-1%"
DEL /Q data_dir.tmp
echo DataDir: %_baseDir%
GOTO :END
::---------------------------------------------
:: Functions
::---------------------------------------------
:simplePrompt 1-question 2-Return-var 3-default-Val
SET input=%~3
IF "%~3" NEQ "" (
:askAgain
SET /p "input=%~1 [%~3]:"
IF "!input!" EQU "" (
GOTO :askAgain
)
) else (
SET /p "input=%~1 [null]: "
)
SET "%~2=%input%"
EXIT /B 0
:getBaseDir fileName var
FOR /F "tokens=*" %%i IN (%~1) DO (
SET "_line=%%i"
IF "!_line:~0,2!" == "c:" (
SET "_baseDir=!_line!"
EXIT /B 0
)
)
EXIT /B 1
:END
PAUSE
i would have done a backup restore simply becuase its easier and support versioning. Reference data especially needs to be versioned in order to know when it started taking effect. A dettach attach wont give you that ability. Also with backups you can continue to provide updated copies without having to shut down the database.
Alex's answer is the right one, but for posterity here's another option: create a new empty database. If you use CREATE DATABASE without specifying a target dir you get... the default data / log directories. Easy.
Personally however I'd probably either:
RESTORE the database to the developer's PC, rather than copy/attach (backups can be compressed, exposed on a UNC), or
Use a linked server to avoid doing this in the first place (depends how much data goes over the join)
ps: 20gb is not huge, even in 2015. But it's all relative.
SELECT DISTINCT dbo.GetDirectoryPath(filename) AS InstanceDataPaths
FROM sys.sysaltfiles WHERE filename like '%.mdf' and filename not like '%\MSSQL\Binn\%'
SELECT DISTINCT dbo.GetDirectoryPath(filename) AS InstanceLogPaths
FROM sys.sysaltfiles WHERE filename like '%.ldf' and filename not like '%\MSSQL\Binn\%'
You can download detail SQL script from how to find the data directory for a SQL Server instance
You will get default location if user database by this query:
declare #DataFileName nVarchar(500)
declare #LogFileName nVarchar(500)
set #DataFileName = (select top 1 RTRIM(LTRIM(name)) FROM master.sys.master_files where database_id >4 AND file_id = 1)+'.mdf'
set #LogFileName = (select top 1 RTRIM(LTRIM(name)) FROM master.sys.master_files where database_id >4 AND file_id = 2)+'.ldf'
select
( SELECT top 1 SUBSTRING(physical_name, 1, CHARINDEX(#DataFileName, LOWER(physical_name)) - 1)
FROM master.sys.master_files
WHERE database_id >4 AND file_id = 1) as 'Data File'
,
(SELECT top 1 SUBSTRING(physical_name, 1, CHARINDEX(#LogFileName, LOWER(physical_name)) - 1)
FROM master.sys.master_files
WHERE database_id >4 AND file_id = 2) as 'Log File'