Hello Microsoft SQL Server Masters,
Well, I have an Microsoft SQL Server 2000 as described below:
Microsoft SQL Server 2000 - 8.00.2039 (Intel X86)
May 3 2005 23:18:38
Copyright (c) 1988-2003 Microsoft Corporation
Desktop Engine on Windows NT 5.2 (Build 3790: Service Pack 2)
I need to execute an Operating System command from this Microsoft SQL Server, I checked that I have sysadmin privileges with the query below and it returned "1", which confirm my privilege.
SELECT IS_SRVROLEMEMBER('sysadmin', 'sa');
I tried the traditional xp_cmdshell and nothing happened, just to make sure it was working I tried the famous:
EXEC xp_cmdshell 'dir c:\'; EXEC master.dbo.xp_cmdshell 'dir c:\';
EXEC master..xp_cmdshell "dir c:\";
And all returned NOTHING, which make me believe that xp_cmdshell is not available. I know that xp_cmdshell comes disable by default in Microsoft SQL Server 2005, but not in 2000, anyway, I tried to reenable it on the same way but it failed.
I looked at internet and I found this way to reenable xp_cmdshell for Microsoft SQL Server 2000:
exec sp_addextendedproc 'xp_cmdshell', 'xplog70.dll'
exec sp_addextendedproc xp_cmdshell, 'C:\Program Files\Microsoft SQL Server\MSSQL\Binn\xplog70.dll'
However, it still doesn't work. I found another article telling that sometimes admins delete this files and I think it may be my case, the article says that if it was deleted I can execute "xp_msver" and in my case it also return nothing.
Reference: http://support.microsoft.com/kb/891984
I also tried this query that I found on the internet to see if xp_cmdshell exist and it returned nothing (but it may be a limitation of my weird SQL client, see below please).
if exists (select * from dbo.sysobjects where id = object_id(N’[dbo].[ xp_cmdshell]‘) and OBJECTPROPERTY(id, N’IsExtendedProc’) = 1);
So, I'm really in trouble, I researched at Google and found potential solutions such as Job agent, SSIS package, CLR stored procedure, sp_OACreate (and friends) and SQLCMD but nothing worked. Maybe I did it incorrect, but another limitation in my case is that I just have access to this Microsoft SQL Server 2000 from a jump-box (Linux) that has a very odd sql-server client that do not accept queries with multiple lines, consequently I can't try with success the following potential solutions:
1# Job Agent
DECLARE #jobID uniqueidentifier, #cmd varchar(1000)
SET #cmd = 'netstat -na > c:\connections.txt'
EXEC msdb.dbo.sp_add_job #job_name = '_tmp_MakeDirectory', #enabled = 1, #start_step_id = 1, #owner_login_name='sa', #job_id = #jobID OUTPUT
EXEC msdb.dbo.sp_add_jobstep #job_id = #jobID, #step_name = 'Create Backup Folder', #step_id = 1, #subsystem = 'CMDEXEC', #command = #cmd
EXEC msdb.dbo.sp_add_jobserver #job_id = #jobID
EXEC msdb.dbo.sp_start_job #job_id = #jobID, #output_flag = 0
WAITFOR DELAY '000:00:05' -- Give the job a chance to complete
IF EXISTS (SELECT name FROM msdb.dbo.sysjobs WHERE name = '_tmp_MakeDirectory')
BEGIN
EXEC msdb.dbo.sp_delete_job #job_name = '_tmp_MakeDirectory'
END
2# SQLCMD
CREATE PROCEDURE SQLCMD_TEST
AS
!!MKDIR "netstat -na > c:\connections.txt"
:OUT "C:\TEST\test.TXT"
SELECT ##VERSION AS 'SERVER VERSION'
!!DIR
GO
SELECT ##SERVERNAME AS 'SERVER NAME'
GO
EXEC SQLCMD_TEST
Unfortunately I don't have any other way to access this Microsoft SQL Server, I know it's not the best way, but it's how it's and I can't do anything. So, I need a solution to execute Operating System commands on this Microsoft SQL Server 2000 with all this limitations. Can someone port any of the two above methods for one single line query, please?
Any other suggestion with example is very welcome.
Thanks a lot.
Regards.
I used to use xp_cmdshell before CLR support came along. Unfortunately, you are a version away from CLR support (SQL Server 2005) and the system.io namespace. You can, however, create your own extended stored procedures which can access the file system and create directories. See here for more info: http://www.devarticles.com/c/a/SQL-Server/Extended-Stored-Procedures-Intro-And-10-Cool-Examples/
By the way, xp_cmdshell is an extended stored procedure.
Related
I am trying to import .dbf files into SQL Server 2016 64bit. For this I installed Microsoft Visual FoxPro. Below setup works for 32bit version of SQL Server but not to 64bit. I also tried changing the driver's name eg: Microsoft.Jet.OLEDB.4.0, Microsoft.ACE.OLEDB.16.0, etc. but no luck.
USE [master]
GO
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO
EXEC sp_configure 'ad hoc distributed queries', 1
RECONFIGURE
GO
USE [master]
GO
EXEC master.dbo.sp_MSset_oledb_prop N'VFPOLEDB', N'AllowInProcess', 1
GO
And then,
DECLARE #sql AS NVARCHAR(200),
#path AS NVARCHAR(200),
#table AS NVARCHAR(200)
SET #path = 'C:\Users\sid\Downloads\VPF\'
SET #table = 'dmfiles'
SET #sql = 'Select * from openrowset(''VFPOLEDB'','''+#path+''';'''';'''',''select * from '+#table+'.dbf'')'
EXEC sp_executesql #sql
Also tried creating a Linked server type of cmd:
SELECT *
FROM OPENROWSET ('MICROSOFT.ACE.OLEDB.12.0','dBase
5.0;HDR=YES;IMEX=2;DATABASE=\Dbf Directory\','SELECT * FROM dbf_filename.dbf')
When I either try to open Linked server, run any command, SQL Server just says executing and never shows any result nor throws error.
I tried using DBF Viewer 2000 to convert .dbf to .sql and ran them against a DB but, running above SQL (if worked fine) would be great for my automation script.
Help is much appreciated!
I'm trying to replicate a production environment locally and the production database uses a linked server. I've been able to create multiple instances of localdb; is it possible to create a linkedserver between localdb instances? If not, what other options do I have available (ideally without having to use a full sql instance).
Not sure if it's bad form to answer your own question but in case anyone else has the same issue in the future, it turns out it is possible and pretty straight forward. Once you've created your new instance of localdb, use this:
USE master
IF EXISTS(SELECT * from sys.servers WHERE name = N'{serverName}')
BEGIN
DECLARE #serverId INT
SELECT #serverId = server_id FROM sys.servers WHERE name = N'{serverName}'
IF EXISTS(SELECT * FROM sys.linked_logins WHERE server_id = #serverId)
BEGIN
EXEC sp_droplinkedsrvlogin '{serverName}', null
END
EXEC sp_dropserver '{serverName}'
END
EXEC sp_addlinkedserver
#server=N'{serverName}',
#provider=N'SQLNCLI',
#srvproduct=N'',
#datasrc=N'{dataSource}';
EXEC sp_addlinkedsrvlogin
#rmtsrvname=N'{serverName}',
#useself='true'
To expand on Dave's auto-answer a little...
If the remote database has not been attached to its instance yet, it will be necessary to include additional connection details in the Provider String argument of sp_addlinked server.
EXEC sp_addlinkedserver
#server=N'{serverName}',
#provider=N'SQLNCLI',
#srvproduct=N'',
#datasrc=N'{dataSource}'
#provstr=N'{providerString}';
In my case I used:
{dataSource} = (LocalDB)\MSSQLLocalDB
{providerString} = AttachDbFileName=C:\Temp\Test.mdf;Integrated Security=True
As a proof of concept we're trying to insert an xp_cmdshell command into an existing solution. Currently an application invokes a stored procedure on our database server which when profiled looks like:
declare #P1 int
set #P1=1
exec Name_Of_The_SP #param1 = 3, #param2 = 'blah', #parametc = 'blahetc', #ID = P1 output
select #P1
The SP essentially opens a transaction, inserts a row, and then commits. Inside this we added:
exec master..xp_cmdshell 'dir > c:\test.txt'
When we then run the first block of code in a SSMS query window the file is generated on the server as expected. But when we use the application to invoke it then the rows are inserted as normal but the file isn't generated?
The SQL Server and SQLAgent users are local admins and sysadmins so can't see any issues there. Tried making the application user a local admin also, to no avail, it was already a sysadmin.
This is SQL Server 2000
We managed to figure this out - we (I) were overlooking in profiler that the exec was coming in under a different login. Granting execute permission to master.dbo.xp_cmdshell specifically got it working. Apologies to anyone who spent any time/effort on this!
I am running SQL Server 2005 on Windows Server 2003 machine.
I have a requirement to accumulate small text files into a bigger one.
So I use
exec xp_cmdshell #sql
where #sql=
'copy /b'+#sourcePath+#sourceFile+' '+#destinationPath+#NewFileName
Both the source and destination paths are on a separate server.
Seldom this process fails and I don't find anything else in the event or SQL Server logs.
The Surface Area Config for xp_cmdshell is also enabled.
Please help.....
I just tested this on my sql server 2005 and EXEC dbo.xp_cmdshell always returns output (even in the case of a bogus command) in the form of a table. For C#, if you call this code with ExecuteNonQuery, then call it with ExecuteReader and read the output. Alternatively, you could dump the output in a table so that you can look at it later at your leisure. Create a table like this :
CREATE TABLE [dbo].[xp_cmdShellOutput](
[errorMsg] [nvarchar](max) NULL
)
and then use this code :
DECLARE #sql AS VARCHAR(600)
SELECT #sql = '<your command>'
INSERT dbo.xp_cmdShellOutput(errorMsg)
EXEC dbo.xp_cmdshell #sql
How can I read the value of a system environment variable in a T-SQL script?
This is to run on SQL Server 2005.
To "read the value of a system environment variable in a T-SQL script" you can set SQL Management Studio to use "sqlcmd Mode".
Then you can use like this:
Print '$(TEMP)'
:r $(Temp)\Member.sql
go
I'm not sure how this is done outside of "SQL Management Studio" but it should be hard to find out.
This should give you a list (provided you allow people to execute xp_cmdshell)
exec master..xp_cmdshell 'set'
Note: xp_cmdshell is a security hazard ...
You could also do this with a managed stored proc an extended stored proc or via a com component.
Hey, if you want to get the server name, just call SELECT ##SERVERNAME
xp_cmdshell is generally best avoided for security reasons.
You're better off using a CLR assembly. Here's a good introduction to creating a CLR assembly.
You can use System.Environment.GetEnvironmentVariable() in C# - you'll find more info on how to do that here.
Thanks for the answers.
They helped me get to a working solution, although this is probably not the most advanced method:
declare #val varchar(50)
create table #tbl (h varchar(50))
insert into #tbl exec master..xp_cmdshell 'echo %computername%'
set #val = (select top 1 h from #tbl)
drop table #tbl
Specifically I was trying to get the hostname, the echo %computername% could be replaced with the hostname system command. But this now works for any environment variable.
To determine a specific environment variable in T-SQL (MS SQL Server) you can do something like:
Grant Security Permissions
use [master]
execute sp_configure 'show advanced options', 1
reconfigure
go
execute sp_configure 'xp_cmdshell', 1
reconfigure
go
grant execute on xp_cmdshell to [DOMAIN\UserName]
grant control server to [DOMAIN\UserName]
go
Source: https://stackoverflow.com/a/13605864/601990
Use Environment Variables
-- name of the variable
declare #variableName nvarchar(50) = N'ASPNETCORE_ENVIRONMENT'
-- declare variables to store the result
declare #environment nvarchar(50)
declare #table table (value nvarchar(50))
-- get the environment variables by executing a command on the command shell
declare #command nvarchar(60) = N'echo %' + #variableName + N'%';
insert into #table exec master..xp_cmdshell #command;
set #environment = (select top 1 value from #table);
-- do something with the result
if #environment = N'Development' OR #environment = N'Staging'
begin
select N'test code'
end
else
begin
select N'prod code'
end
Also remember to restart the SQL Server Service when changing the Environment Variables.