gpg encryption in xp_cmdshell - sql-server-2012

I am trying to encrypt a .csv file using gpg in xp_cmdshell command in sql server 2012.
When I use gpg through xp_cmdshell, it says gpg is not recognized as an internal or external command.
But this works perfectly on windows cmd.
How should I configure my sql server to accept this command. Please advice.
select #encrypt = 'gpg -e -r ' + #sEncryptionKey+ ' '+ #sPath + #tempdataFolder+'\'+ #sFileName
exec master..xp_cmdshell #encrypt

To remedy the error you are indicating above, simply add the full path to gpg.exe in your code.
select #encrypt = 'c:\gpg\gpg.exe -e -r ' + #sEncryptionKey+ ' '+ #sPath + #tempdataFolder+'\'+ #sFileName
exec master..xp_cmdshell #encrypt
For comparison, this is how I have done this in the past via SSIS; be sure you provide the exact full path to your executable... we are using gpg4win (gpg2.exe) in this example.
You may also want to wrap each parameter in " " to handle file names/paths with spaces better.
DECLARE #sKeyEmail VARCHAR(100), #sInFile VARCHAR(100), #sOutFile VARCHAR(100), #SQL VARCHAR(1000)
SET #sInFile = 'c:\temp\somefile.xls'
SET #sOutFile = 'c:\temp\somefile.xls.gpg'
SET #sKeyEmail = 'user#domain.com'
SET #SQL = 'EXEC master.dbo.xp_cmdshell ''C:\Progra~1\GNU\GnuPG\gpg2 -o ' +#sOutFile+ ' -e -r ' +#sKeyEmail + ' ' +#sInFile+ ''''
PRINT #SQL
-- EXEC sp_execute #SQL

Related

How to execute sql file using another sql file MSQL

Im creating database which need few sql scripts. Running them one by one is not effective , so I wanted to create main sql query which will load all files. I tried this :
Declare
#DBServerName Varchar(100),
#DBName Varchar(100),
#FilePathName Varchar(100),
#strSql varchar(1000)
Set #DBServerName='USER-PC'-- Server Name
Set #DBName='testo' -- DB Name
Set #FilePathName='some path here'
Set #strSql= 'sqlcmd -S ' + #DBServerName + ' -d ' + #DBName + ' -i ' + #FilePathName
EXEC xp_cmdshell #strSql
After executing this, It is showing that my query was executed succesfully but in my database nothing is appearing. Ive seen lot of websites but there is no working answear.
I don't think you want xp_cmdshell here. If you want to execute dynamic SQL you should be using the code below:
sp_executesql #strsql;

bcp field terminator empty

https://technet.microsoft.com/en-us/library/aa196735(v=sql.80).aspx
I'm trying to create a file from bcp, the file was successfully created, but I want to make the field terminator -t empty. The closest way was with the null terminator, but it makes a space between fields.
This is my code.
select #cmd = 'bcp '+ #SP + ' queryout '+ #ruta+' -w -t\0 -S '+#Servidor+ ' -U'+#user +' -P'+ #password
exec master..xp_cmdshell #cmd
I've also tried to leave it without any symbol after t, but it puts more spaces.
select #cmd = 'bcp '+ #SP + ' queryout '+ #ruta+' -w -t -S '+#Servidor+ ' -U'+#user +' -P'+ #password
exec master..xp_cmdshell #cmd
use -t"" This basically gives you a fixed width export file especially when used to source fields defined as char()
for example:
bcp "select * from TEST.dbo.tExportTst" queryout FixedWidth.txt -c -t"" -T -S Svr\instance

Using bcp utility to export SQL queries to a text file

I debug a stored procedure (SQL Server 2005) and I need to find out some values in a datatable.
The procedure is run by an event of the application and I watch just the debugging output.
I do the following my stored procedure (SQL Server 2005), I took a system table (master.dbo.spt_values) as example:
set #logtext = 'select name, type from master.dbo.spt_values where number=6'
--set #logtext = 'master.dbo.spt_values'
SET #cmd = 'bcp ' + #logtext + ' out "c:\spt_values.dat" -U uId -P uPass -c'
EXEC master..XP_CMDSHELL #cmd
So, when I uncomment the second like everything works, a file apprears on the C:\ drive... but if I coment it back leaving only the first line, any output is generated.
How to fix this problem?
bcp out exports tables.
To export a query use queryout instead - you'll need to wrap your query in "double quotes"
set #logtext = '"select name, type from master.dbo.spt_values where number=6"'
--set #logtext = 'master.dbo.spt_values'
SET #cmd = 'bcp ' + #logtext + ' queryout "c:\spt_values.dat" -U uId -P uPass -c'
EXEC master..XP_CMDSHELL #cmd
http://msdn.microsoft.com/en-us/library/ms162802.aspx

Writing file to network drive in stored proc

I have a stored proc that can write a file to a network drive using BCP, by creating a temporary drive on the database server that maps to the shared drive on another server. It is working correctly, however, I am returning an error from the last EXEC command, which says There are open files and/or incomplete directory searches pending on the connection to U:. I am guessing that it is trying to execute the delete drive command before it has finished writing the file. If I run the statement after running the proc, it will successfully delete the drive. Here is the proc:
CREATE PROCEDURE dn_ExportFile
#ServerName varchar(50),
#ServerPath varchar(500),
#FileName varchar(100),
#Query varchar(max),
#UserName varchar(100),
#Password varchar(100),
#Drive varchar(1) = 'U'
AS
BEGIN
SET NOCOUNT ON;
DECLARE #cmd VARCHAR(8000)
--Set up virtual drive pointing to desired path
SET #cmd = 'NET USE ' + #Drive + ': ' + #ServerPath + ' /user:' + #ServerName + '\' + #UserName + ' ' + #Password
PRINT #cmd
EXEC xp_cmdshell #cmd
--Export data using BCP to virtual drive
SET #cmd = 'BCP "' + #Query + '" QUERYOUT "' + #Drive + ':\' + #FileName + '" -c -t -T'
PRINT #cmd
EXEC xp_cmdshell #cmd
--Delete virtual drive
SET #cmd = 'NET USE ' + #Drive + ': /delete'
PRINT #cmd
EXEC xp_cmdshell #cmd
END
Is there a way to successfully delete the temporary drive within the stored procedure?
I suspect it can't happen while the calling proc is still in scope. So you might try a wrapper stored procedure that does:
EXEC dbo.dn_ExportFile ...;
SET #cmd = 'NET USE ' + #Drive + ': /delete';
PRINT #cmd;
EXEC xp_cmdshell #cmd;
Otherwise I still think you're doing this in the wrong place. Have the program that calls this procedure call the command and dictate the path.

Is it possible to execute a text file from SQL query?

I have a number of generated .sql files that I want to run in succession. I'd like to run them from a SQL statement in a query (i.e. Query Analyzer/Server Management Studio).
Is it possible to do something like this and if so what is the syntax for doing this?
I'm hoping for something like:
exec 'c:\temp\file01.sql'
exec 'c:\temp\file02.sql'
I am using SQL Server 2005 and running queries in management studio.
use xp_cmdshell and sqlcmd
EXEC xp_cmdshell 'sqlcmd -S ' + #DBServerName + ' -d ' + #DBName + ' -i ' + #FilePathName
Very helpful thanks, see also this link:
Execute SQL Server scripts
for a similar example.
To turn xp_cmdshell on and off see below:
On
SET NOCOUNT ON
EXEC master.dbo.sp_configure 'show advanced options', 1
RECONFIGURE
EXEC master.dbo.sp_configure 'xp_cmdshell', 1
RECONFIGURE
Off
EXEC master.dbo.sp_configure 'xp_cmdshell', 0
RECONFIGURE
EXEC master.dbo.sp_configure 'show advanced options', 0
RECONFIGURE
SET NOCOUNT OFF
Or just use openrowset to read your script into a variable and execute it (sorry for reviving an 8 years old topic):
DECLARE #SQL varchar(MAX)
SELECT #SQL = BulkColumn
FROM OPENROWSET
( BULK 'MeinPfad\MeinSkript.sql'
, SINGLE_BLOB ) AS MYTABLE
--PRINT #sql
EXEC (#sql)
This is what I use. Works well and is simple to reuse. It can be changed to read all files in the directory, but this way I get to control which ones to execute.
/*
execute a list of .sql files against the server and DB specified
*/
SET NOCOUNT ON
SET XACT_ABORT ON
BEGIN TRAN
DECLARE #DBServerName VARCHAR(100) = 'servername'
DECLARE #DBName VARCHAR(100) = 'db name'
DECLARE #FilePath VARCHAR(200) = 'path to scrips\'
/*
create a holder for all filenames to be executed
*/
DECLARE #FileList TABLE (Files NVARCHAR(MAX))
INSERT INTO #FileList VALUES ('script 1.sql')
INSERT INTO #FileList VALUES ('script 2.sql')
INSERT INTO #FileList VALUES ('script X.sql')
WHILE (SELECT COUNT(Files) FROM #FileList) > 0
BEGIN
/*
execute each file one at a time
*/
DECLARE #FileName NVARCHAR(MAX) = (SELECT TOP(1) Files FROM #FileList)
DECLARE #command VARCHAR(500) = 'sqlcmd -S ' + #DBServerName + ' -d ' + #DBName + ' -i "' + #FilePath + #Filename +'"'
EXEC xp_cmdshell #command
PRINT 'EXECUTED: ' + #FileName
DELETE FROM #FileList WHERE Files = #FileName
END
COMMIT TRAN
I wouldn't recommended doing this, but if you really have to then the extended stored procedure xp_cmdshell is what you want. You will have to first read the contents of the file into a variable and then use something like this:
DECLARE #cmd sysname, #var sysname
SET #var = 'Hello world'
SET #cmd = 'echo ' + #var + ' > var_out.txt'
EXEC master..xp_cmdshell #cmd
Note: xp_cmdshell runs commands in the background, because of this, it must not be used to run programs that require user input.
Take a look at OSQL. This utility lets you run SQL from the command prompt. It's easy to get installed on a system, I think it comes with the free SQL Server Express.
Using the osql Utility
A qick search of "OSQL" on stack overflow shows a lot of stuff is available.
The main thing to handle properly is the user and password account parameters that get passed in on the command line. I have seen batch files that use NT file access permissions to control the file with the password and then using this file's contents to get the script started. You could also write a quick C# or VB program to run it using the Process class.
For Windows Authentication, if you are running as another user:
Open Command Prompt as your Windows user (Right click on it, Open File Location, Shift + Right Click, Run as a different user)
sqlcmd -S localhost\SQLEXPRESS -d DatabaseName-i "c:\temp\script.sql"
Or if you are using Sql Server user:
sqlcmd -S localhost\SQLEXPRESS -d DatabaseName-i "c:\temp\script.sql" -U UserName -P Password
Replace localhost\SQLEXPRESS with you server name if not local server.
Open windows command line (CMD)
sqlcmd -S localhost -d NorthWind -i "C:\MyScript.sql"
For anybody stumbling onto this question like I did and might find this useful, I liked Bruce Thompson's answer (which ran SQL from files in a loop), but I preferred Pesche Helfer's approach to file execution (as it avoided using xp_cmdshell).
So I combined the two (and tweaked it slightly so it runs everything from a folder instead of a manually created list):
DECLARE #Dir NVARCHAR(512) = 'd:\SQLScriptsDirectory'
DECLARE #FileList TABLE (
subdirectory NVARCHAR(512),
depth int,
[file] bit
)
INSERT #FileList
EXEC Master.dbo.xp_DirTree #Dir,1,1
WHILE (SELECT COUNT(*) FROM #FileList) > 0
BEGIN
DECLARE #FileName NVARCHAR(MAX) = (SELECT TOP(1) subdirectory FROM #FileList)
DECLARE #FullPath NVARCHAR(MAX) = #Dir + '\' + #FileName
DECLARE #SQL NVARCHAR(MAX)
DECLARE #SQL_TO_EXEC NVARCHAR(MAX)
SELECT #SQL_TO_EXEC = 'select #SQL = BulkColumn
FROM OPENROWSET
( BULK ''' + #FullPath + '''
, SINGLE_BLOB ) AS MYTABLE'
DECLARE #parmsdeclare NVARCHAR(4000) = '#SQL varchar(max) OUTPUT'
EXEC sp_executesql #stmt = #SQL_TO_EXEC
, #params = #parmsdeclare
, #SQL = #SQL OUTPUT
EXEC (#sql)
DELETE FROM #FileList WHERE subdirectory = #FileName
PRINT 'EXECUTED: ' + #FileName
END