How to use a SQL Server Parameter Input from Command Line? - sql-server

I'm a SQL Newbie and I'm trying to figure out how to use a Parameter with SQL Thru Command-Line
For my boss/staff I have written Batch Files to run SQL Code for them to export data and the like. In Access all I have to do is [Paramerter] and it prompts for data to be entered.
The #State Variable I'd like to be able to be set dynamically. I'd like the batch file to ask for State and Query use that information. I have no idea how to do it.
Batch File
sqlcmd -E -S ServerName -i C:\Lead$\SQL\MakeSTPhoeLists.sql
pause
The SQL File
Use LeadsDb
Go
Declare #State VarChar(2)
Set #State = 'DE'
DELETE FROM tblzExportPhone
INSERT INTO tblzExportPhone ( Phone )
SELECT tblLeads.Phone
FROM tblLeads
WHERE tblLeads.ST = #State
Declare #FileName VarChar(100)
Set #FileName = 'H:\Leads\Storage\STLists\' + #State +'StatePhoneList.csv'
DECLARE #bcp_cmd4 VARCHAR(400) = ' BCP.EXE LeadsDb..tblzExportPhone out '
SET #bcp_cmd4 = #bcp_cmd4 + 'H:\Leads\SQL\Formats\PhoneTmp.csv' + ' -T -f H:\Leads\SQL\Formats\tblzExportPhone.fmt'
SET #bcp_cmd4 = #bcp_cmd4 + ' & Copy /b H:\Leads\SQL\Formats\ExPhone.csv+H:\Leads\SQL\Formats\PhoneTmp.csv ' + #FileName + ' /y'
Set #bcp_cmd4 = #bcp_cmd4 + ' & Del H:\Leads\SQL\Formats\PhoneTmp.csv'
Thank You.

In your sql file use this notation $(statename)
Add this to your command file -v statename = %1
And execute it passing the parameter mycommanfile.cmd DE
Also read this for a full example.

Essentially what I found out is you have to make a Stored Procedure and Call a query to run it. I'm going to leave an example. BTW SQL Query Creates CSV File from table Using bcp and then Zips it up using RAR Dos Command.
BTW Stored procedure is used due to every which other way I try to do it withoutI failed, but once I added it I was golden. Can use Dos prompt insead of bat file but I'm setting up bat files for 'Semi-Computer Smart people'
Hope this helps a newbie like me out^^
BAT File (cmd prompt)
Echo phone numbers in the State to send to Paramount.
Echo Then after the file is made converts it to Zip.
Echo '
Set /p State=Enter Initials of the State? :
sqlcmd -E -S Titania -i H:\Lead$\SQL\STPhones.sql -v StateName=%State%
SQL Command #1
Use dbNameHere
go
Declare #State NVarChar(2)
EXECUTE [dbo].[STPhoneListB] #State=$(StateName)
SQLCommand #2
Use dbNameHere
Go
CREATE PROCEDURE [dbo].[STPhoneListB]
#State NVarChar(2) = 'DE',
#Folder VarChar(100) = 'H:\Lead$'
AS
BEGIN
Declare #FileName VarChar(150)
Set #FileName = #Folder + '\STPhones_'+ #State +'.csv'
Declare #DosCMD VarChar(150) = 'Del ' + #Folder +'\STPhones'+ #State
+'.Zip /q'
EXEC master..xp_cmdshell #DosCMD
DECLARE #bcp_cmd4 VARCHAR(400)
DELETE FROM tblzExportPhone
INSERT INTO tblzExportPhone ( Phone )
SELECT tblLeads.Phone
FROM tblLeads
WHERE tblLeads.ST = #State
Set #bcp_cmd4 = 'BCP.EXE LeadsDb..tblzExportPhone out '
SET #bcp_cmd4 = #bcp_cmd4 + 'H:\SQL\PhoneTmp.csv' +
' -T -f H:\SQL\tblzExportPhone.fmt'
SET #bcp_cmd4 = #bcp_cmd4
+ ' & Copy /b H:\SQL\ExPhone.csv+H:\SQL\PhoneTmp.csv '
+ #FileName + ' /y'
Set #bcp_cmd4 = #bcp_cmd4 + ' & Del H:\SQL\PhoneTmp.csv'
EXEC master..xp_cmdshell #bcp_cmd4
Set #bcp_cmd4 = 'cd '+ #Folder +
' & "C:\Program Files\WinRAR\rar.exe" m STPhones_'+ #State +'.Zip ' +
'STPhones_'+ #State +'.csv'
EXEC master..xp_cmdshell #bcp_cmd4
DELETE FROM tblzExportPhone
END

Related

Move file in SQL server based on the beginning of the name

I need to copy certain file from a folder A to a folder B, but I need to copy only file based on a condition. The name of the file must start with the same value as a variable I have in my stored procedure.
Here is what I've got at the moment:
DECLARE #SQLFile VARCHAR(1024)
DECLARE #MessageId INT = 3 --copy all the files from the source folder that start with this variable
DECLARE #SourceFolderPath VARCHAR(1024)
DECLARE #DestinationFolderPath VARCHAR(1024)
SET #DestinationFolderPath = '\\mydestination'
SET #SourceFolderPath = '\\mysource'
SET #SQLFile = ' COPY /Y ' + #SourceFolderPath + ' /B ' + #DestinationFolderPath
EXEC master..xp_cmdshell #SQLFile
With this code I copy all the files but I don't know if there is a way to integrate the condition of beginning of name.
Thanks
I'm guessing a simple file glob will do what you want. But as people said in the comments using xp_cmdshell can create all kinds of security issues if used where untrusted data is kicking about. For this reason it is also often blocked by SQL Server security policy.
DECLARE #SQLFile VARCHAR(1024)
DECLARE #MessageId INT = 3 --copy all the files from the source folder that start with this variable
DECLARE #SourceFolderPath VARCHAR(1024)
DECLARE #DestinationFolderPath VARCHAR(1024)
SET #DestinationFolderPath = '\\mydestination'
SET #SourceFolderPath = '\\mysource'
SET #SQLFile = ' COPY /Y ' + #SourceFolderPath + '\' + CAST(#MessageID AS varchar(max)) + '* /B ' + #DestinationFolderPath
EXEC master..xp_cmdshell #SQLFile

How to read from a file which has SQL script which needs to be executed on multiple DBs on same server

Below script suppose to be executed on multiple DBs, however on parsing gives below error-
Msg 102, Level 15, State 1, Line 40
Incorrect syntax near '+'.
declare #list table (name varchar(128) not null);
fill the list with your custom subset
insert into #list
select name from sys.databases where name like '%connect%';
--select * from #list
--select min(name) from #list
--read the script
declare
#DBServerName varchar(128),
#FilePathName varchar(128),
#DBName varchar(128)
;
set #DBServerName = 'peeyushp-w8';
set #FilePathName = 'D:\script.sql';
set #DBName = '';
--EXEC xp_cmdshell 'sqlcmd -S ' + #DBServerName + ' -d ' + #DBName + ' -i ' + #FilePathName
declare
#db varchar(128),
#t varchar(max),
#s varchar(max)
;
--set #t = 'use {db}; exec sp_spaceused';
set #db = (select min(name) from #list);
while #db is not null
begin
--set #s = replace(#t, '{db}', ' -d' + #db);
--exec (#s);
EXEC xp_cmdshell 'sqlcmd -S ' + #DBServerName + #s + ' -i ' + replace(#FilePathName, '{db}', ' -d' + #db);
set #db = (select min(name) from #list where name > #db);
end
GO
Error is coming on 'xp_cmdshell' exec statement. Am i missing something which to be included in my SQL script. Will appreciate any help on the same.
According to PROCEDURE's Limitations and Restrictions in T-SQL :
You cannot specify a function name as a parameter default value or as the value passed to a parameter when executing a procedure. However, you can pass a function as a variable as shown in the following example.
So, it is impossible to use directly the string concatenation as procedure parameter. It must be declared before :
DECLARE #cmd VARCHAR(400)
SET #cmd = 'sqlcmd -S ' + #DBServerName + ' -d ' + #DBName + ' -i ' + #FilePathName
-- Now you can use it
EXEC xp_cmdshell #cmd

delete from database using batch file and sql scipt

BATCH FILE:
ECHO OFF
SET /P colu= Enter column name:
SET /P sn= Enter ID (split by commas):
rem Grab filenames in an array
set n=0
for %%a in (%SN%) do (
set /A n+=1
set "id[!n!]=%%~a"
)
rem For example, to process the filenames:
for /L %%i in (1,1,%n%) do (
echo %%i- !id[%%i]!
)
sqlcmd -U USER-P PASSW -S SERVER -d DB -i sqlFILE.sql -o LOGS.txt -v delete=colu d_id=snode
I want to delete several ids from the database. This batch file asks the user what they want to be deleted and it is suppose to put the entered values in an array.
These entered values are entered into this SQL script:
declare #columnName nvarchar(255)
declare #intValue int
set #columnName = '$(colu)' --COLUMN NAME WHERE VALUE IS LOCATED
set #intValue = '$(sn)' --VALUE TO BE DELETED
declare #DeleteValue varchar(10)
set #DeleteValue = convert(varchar(10), #intValue)
declare #sql nvarchar(max) = ''
select #sql = #sql + 'delete ' + object_name(c.object_id) + ' where ' + #columnName + ' IN ' + #DeleteValue + ';'
from sys.columns c
where c.name = #columnName
select #sql
exec sp_executesql #sql
The problem is that the program is still looking at the values entered as one whole value and not separate values.

SQL BCP invalid object name ##Labels

I'm having trouble with BCP. It keeps saying invalid object name ##Labels despite me creating a global table. What am I doing wrong please?
The code is: -
DECLARE #SQL varchar(max)
SET #BatchNo = 'abc123'
DECLARE #test TABLE(A varchar(max),B varchar(max),C varchar(max),D varchar(max),E varchar(max),F varchar(max),G varchar(max),H varchar(max),I varchar(max),J varchar(max))
insert into #test values ('1','2','3','4','5','6','7','8','9','10')
SELECT * INTO ##Labels FROM #test
SET #SQL = 'SELECT * FROM ##Labels'
DECLARE #TMPfile varchar(25)
DECLARE #folder varchar(128)
DECLARE #LabelDir varchar(128)
DECLARE #template varchar(25)
DECLARE #FinalFile varchar(40)
DECLARE #cmdstr varchar(300)
SET #TMPfile = #BatchNo + '.tmp'
--Trigger folder
SET #folder = '\\WIN-0H\LABELLING\XFER\'
--Print Directive Folder
SET #LabelDir = '\\WIN-0H\DIR\'
--Label Data Template
SET #template = 'cl.csv'
--Fine output file
SET #FinalFile = #BatchNo + '.CHLABEL'
--Bulk Copy Query to csv temp file
SET #cmdstr = 'bcp "' + #SQL + '" QUERYout ' + #folder + #TMPfile + ' -c -t "," -T'
SELECT * FROM ##Labels
EXEC master..xp_cmdshell #cmdstr
PRINT #cmdstr
--join the label csv template to the actual data
SET #cmdstr = 'copy /Y /B ' + #LabelDir + #template + ' + ' + #folder + #TMPfile + ' ' + #folder + #FinalFile
EXEC master..xp_cmdshell #cmdstr
PRINT #cmdstr
--Remove all temporary files
SET #cmdstr = 'del ' + #folder + #TMPfile
EXEC master..xp_cmdshell #cmdstr
PRINT #cmdstr
PRINT 'Im Printing'
DROP TABLE ##Labels
The error message is:
Error = [Microsoft][SQL Server Native Client 11.0][SQL Server]Invalid
object name '##Labels'.
The BCP command-line utility runs independently of the T-SQL script, even when inviked via xp_cmdshell. It connects to the default instance on the same server it runs on unless the BCP /S parameter specifies otherwise.
In this case, the global temp table was created on the named instance where the script ran. However, the BCP command connected to the default instance and the global temp table did not exist there (fortunately).

SQL Server output to a file using variable name

I want to send SQL Server output to a file which is working as expected. But if I pass the file path in a variable, It is not creating the file.
Working
:out 'C:\Temp.txt'
Not Working
DECLARE #BCVFileName VARCHAR(500)
SET #BCVFileName= 'C:\Temp.txt'
:out #BCVFileName
Could anyone please help me on this??
Thanks,
Mahesh
For this you need to store your query in Query file and then you can execute from command to store result to a text file as shown below.
>sqlcmd -E -S(Local)\SQLExpress -YourDBName -iC:\myQuery -oC:\Output.txt
Another way to use T-SQL and create a batch statement to execute via XP_CMDSHELL. Following script will help you to do the same just replace your query, ServerName with used variables.
SET NOCOUNT ON;
GO
DECLARE #sqlcmd varchar(1000);
PRINT 'using SqlCMD.exe';
SET #sqlcmd = 'sqlcmd -S' + ##SERVERNAME + ' -E -oc:\outfile.txt '
DECLARE #cmd varchar(1000);
SET #cmd = '-Q"SELECT RIGHT(REPLICATE('' '' , 6) + CONVERT(varchar, AddressID), 6 ) AS AddressID, CONVERT(varchar(10), ModifiedDate, 121) AS ModifiedDate FROM AdventureWorks.Person.Address ORDER BY ModifiedDate;"';
SET #sqlcmd = #sqlcmd + #cmd;
--SELECT #sqlcmd;
EXEC xp_cmdshell #sqlcmd, no_output;
PRINT 'using BCP.exe';
SET #cmd = '"SELECT RIGHT(REPLICATE('' '' , 6) + CONVERT(varchar, AddressID), 6 ) AS AddressID, CONVERT(varchar(10), ModifiedDate, 121) AS ModifiedDate FROM AdventureWorks.Person.Address ORDER BY ModifiedDate;"';
SET #sqlcmd = 'bcp ' + #cmd + ' queryout "c:\outfile2.txt" -c -T -S' + ##SERVERNAME
--SELECT #sqlcmd;
EXEC xp_cmdshell #sqlcmd, no_output;
regards

Resources