Enabling SQL Ad Hoc Distributed Queries for a single command - sql-server

I need to read data from Excel files to make hundreds of updates to SQL Server. The server is by default configured to not allow these queries, but I can change this setting. I read about the risks of allowing these queries, but I was wondering if there are security concerns or performance issues or other risks I don't know about, if I enable them for the duration of a single command.
In short, is it reasonable to do the following?
exec sp_configure 'Ad Hoc Distributed Queries', 1
reconfigure
begin try
select * from OPENROWSET(
'Microsoft.ACE.OLEDB.12.0'
,'Excel 12.0;Database=C:\Temp\Test.xlsx;'
,'SELECT * FROM [Sheet1$]') as xl
end try
begin catch
print 'Error occurred'
end catch
exec sp_configure 'Ad Hoc Distributed Queries',0
reconfigure
I would of course wrap this in a stored procedure and use it many times over for different source and target tables.

Answering my own question based on my own findings, the answer is no, the above is not quite reasonable.
Apparently the GO keyword is necessary at least after the reconfigure statements. I couldn't get a successful test as the server machine did not have the ACE OleDb provider installed.
Also, try-catch does not catch errors relating to the missing provider. So if someone can tell how this could be done safely, please do.

Related

Silent truncation using OpenRowSet to Bulk Load data

I‌‌ have to load CSV data into SQL server table using OpenRowSet.
‌ I have installed the AccessDatabaseEngine_X64.exe, Access and SQL server 2014 both are 64-bit.
Also enabled below settings,
sp_configure 'show advanced options', 1
reconfigure with override
sp_configure 'Ad Hoc Distributed Queries', 1
reconfigure with override
INSERT INTO dbo.Test
SELECT * FROM OPENROWSET('MSDASQL'
,'Driver={Microsoft Access Text Driver (*.txt,*.csv)}','select * fromD:\MYDATA\go\test.CSV')
‌‌
D‌ata was also getting loaded into the table, but some of my rows in CSV have data more than what is defined in the schema of the table (Test) and I don't want to change column size in the table(Test) So SQL started giving errors related to truncation. Without using OpenRowSet earlier I used to use "Set ANSI WARNINGS OFF" to do silent truncation. But with OpenRowSet if I use this command then it gives below error
Heterogeneous queries require the ANSI_NULLS and ANSI_WARNINGS options to be set for the connection. This ensures consistent query semantics. Enable these options and then reissue your query.‌‌
I want to use OpenRowSet because it is very fast. So can anyone please help me on how I can do silent truncation using OpenRowSet.

Can I do "Local" System calls using query?

I'm currently on a host(A), connecting to a MSSQL database on server(B).
When I do a System call, such as
EXEC xp_cmdshell 'Systeminfo' GO
from within MS SQL 2008 it always returns me system information from the client(A) I'm currently running my SQL management tool on.
Is there a possibility to run System calls that will return me information from the server(B)?
I have since asking this question rebooted, and tried all the steps again:
1. Turn off local server
2. Connect to external server
3. Turn on XP_CMDSHELL command for the external server using
-- 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
And then just run
EXEC xp_cmdshell 'Systeminfo';
GO
Weird that it works now,because I couldn't get it to work past weeks.

Resource limit error in linked server

I have a problem with running a query in a linked server, I use sql sp’s for ETL process in my BI project
(For some reason I cannot use ssis).one of my queries witch has to read recently changed records and insert them in my warehouse take too long to execute and always fail with this error:
OLE DB provider 'SQLOLEDB' reported an error for linked server ‘XXX’. Execution terminated by the provider because a resource limit was reached..
But other queries run successfully. I also run following scrip in my linked server (warehouse) to increase timeout threshold.
sp_configure 'remote login timeout', 30
go
reconfigure with override
go
sp_configure 'remote query timeout', 0
go
reconfigure with override
go
Hint: I’ve used change tracking option in source tables to track updates and inserts..
I would be really thankful if someone could help me out of this.

Replicating Production to Test Environment w/ 2 servers in each

I've got 4 servers total. The production side has live replication from EARTH to TR. The Dev side has live replication from KOHOUTEC to CROMELIN. I'd like to make a snapshot from EARTH to KOHOUTEC.
When I set this up, I get an error:
Cannot drop the table 'dbo.SomeTable' because it is being used for replication.
Googling around, I found this: http://support.microsoft.com/kb/326352.
That article uses this script:
sp_configure 'allow updates', 1
go
reconfigure with override
go
begin transaction
update sysobjects set replinfo = 0 where name = 'object_name'
commit transaction
go
sp_configure 'allow updates', 0
go
reconfigure with override
go
But is also has some pretty serious warnings:
IMPORTANT: The 3724 message may occur legitimately when an object is marked for replication. Do not use the following workaround if the object is being used for replication.
And:
IMPORTANT: Running sp_removedbreplication on a database removes all replication objects from the database. Therefore, all publications and subscriptions in the database are removed.
So I'm understandably a little nervous about doing this, especially since I'm not 100% sure what's going on in the first place.
At the end of the day, all I want is to have the development environment have a nightly copy of the production environment. If replication isn't the way to do it, I'm open to any suggestions.
Thanks!

Accessing another SQL Server from SQL Job Agent

I have a SQL Server Agent Job on "server X." This job is simple, and uses the following query to refresh a table (on server X) by clearing it, then re-populating it with data from a view (also on server X):
DELETE FROM [ClientList].[dbo].[LatestDownloadLogs]
INSERT INTO [ClientList].[dbo].[LatestDownloadLogs]
SELECT * FROM [ClientList].[dbo].[latestoverview-union]
The "LatestDownloadLogs" table is moving to "server Y," but the "latestoverview-union" view will remain on "server X".
Therefore what I need is something that looks like this:
DELETE FROM [server Y].[ClientList].[dbo].[LatestDownloadLogs]
INSERT INTO [server Y].[ClientList].[dbo].[LatestDownloadLogs]
SELECT * FROM [server X].[ClientList].[dbo].[latestoverview-union]
Of course, it's not that easy, but hopefully that illustrates what I'm trying to accomplish.
Create a linked server on server x to server y.
You could use OPENROWSET, which'll require the connection info, username & password...
But first you may need to turn on Ad Hoc Distributed Queries
EXEC sp_configure 'show advanced options', 1
reconfigure
EXEC sp_configure 'Ad Hoc Distributed Queries', 1
reconfigure
You can then select, insert or delete
SELECT FROM
OPENROWSET (... params...)
UPDATE
OPENROWSET (... params...)
Hope this helps... good luck.

Resources