LoadFromSQLServer method has encountered OLE DB - sql-server

I have this error:
LoadFromSQLServer method has encountered OLE DB error code 0x80004005 (Login timeout expired). The SQL statement that was issued has failed
And here is my code, what is wrong?
DECLARE #FileName VARCHAR(50);
DECLARE #VendorID VARCHAR(50);
DECLARE #sql VARCHAR(2000);
DECLARE #Local_File_FullPath VARCHAR(100);
SET #FileName = 'Extgt_skinny_file.txt.pgp'
Set #VendorID = 'ET'
Select #Local_File_FullPath = dw03_path FROM GMAC_META.dbo.VENDOR_XFER_METADATA where vendor_id = #VendorID
SET #sql = 'dtexec /SQL "\EMAP_FTP_XFER_CHECK" /SET \Package.Variables[User::FileName].Properties[Value];"'
+ #FileName+'" /SET \Package.Variables[Local_File_FullPath].Properties[Value];'
+ #Local_File_FullPath+' /SERVER "hqgmdw02/dw_dev" /CHECKPOINTING OFF /REPORTING E'
exec xp_cmdshell #sql

Try the following:
GRANT exec ON xp_cmdshell TO '<somelogin>'. Please refer to xp_cmdshell (Transact-SQL).
Check to see if you are using a 32-bit DTExec on a 64-bit machine.
Ensure that the users that will run the SSIS package have sufficient permissions. I take that you run is under SSIS in a SQL Server Agent or you might run it manually. The service account running SQL Agent and your account must have permissions to execute the job. Please see Error in executing SSIS package through Agent

As the OP mentioned, the server routes (for parameter /SERVER) should use backslashes and not common slashes. The error being displayed is a little misleading for this occasion, as the login times out because the server path is incorrect.
So change
/SERVER "hqgmdw02/dw_dev"
for
/SERVER "hqgmdw02\dw_dev"

Related

How do I look at SQL Agent Job without starting SQL Agent?

I have just set up a new SQL Server instance on a new server and moved our application to use the new server. So I've had to turn SQL Agent off on the old server - turning it on would start the scheduler and start sending out emails and running things that shouldn't be run any more.
However, I need to take a close look at a SQL Agent Job on the old server, and ideally reverse-engineer the code to recreate it so I can modify it and apply it to the new server.
How do I generate the code for that Job on the old server without turning SQL Agent on?
Thanks
Even if SQL server agent is not running, you can see how jobs and schedules were set up by viewing the following system DMVs.
msdb.dbo.sysjobs_view
msdb.dbo.sysjobs
msdb.dbo.sysjobschedules
msdb.dbo.sysschedules
I use preset scripts to create all my jobs and schedules independent of the server. Here is a sample script to create the recycle log job. You can modify this or use any piece of this as you see fit.
DECLARE #sql nvarchar(max)
BEGIN TRY
IF EXISTS (SELECT job_id
FROM msdb.dbo.sysjobs_view
WHERE name = N'Cycle SQL log')
EXEC msdb.dbo.sp_delete_job #job_name=N'Cycle SQL log'
, #delete_unused_schedule=1
EXEC msdb.dbo.sp_add_job
#job_name = N'Cycle SQL log',
#description = N'This job forces SQL to start a new error log (In the Managment node of SSMS)',
#owner_login_name = N'your_sql_login' ;
EXEC msdb.dbo.sp_add_jobstep
#job_name = N'Cycle SQL log',
#step_name = N'sp_cycle_errorlog',
#subsystem = N'TSQL',
#command = N'exec sp_cycle_errorlog' --put your executable code here
--These next two lines set the target server to local, so that the job can be modified if necessary
SET #sql = 'EXEC msdb.dbo.sp_add_jobserver #job_name=N''Cycle SQL Log'', #server_name = N''' + ##SERVERNAME + ''''
EXEC sys.sp_executesql #stmt = #sql
END TRY
BEGIN CATCH
PRINT 'Uh-oh. Something bad happened when creating the Cycle SQL Log job. See the following error.'
PRINT CAST(ERROR_MESSAGE() AS NVARCHAR(1000))
END CATCH
You can use use code to automate the addition of schedules based on values you pull from the DMVs listed above.

Run a query in SQL Server on an Access database as linked server

I have been trying to figure this out for about a half of a day now. I have been trying to run a very simple query on an Access database in SQL Server 2014.
Query:
select * from plantsT
what I have tried.
I tried to run
SELECT *
FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'\\path\MasterDatabase.accdb';
'';
'', PlantsT);
Error message:
Cannot create an instance of OLE DB provider "Microsoft.Jet.OLEDB.4.0" for linked server "(null)".
I have tried all of the options on MSDN
Same error.
I have tried to install access 2007 drivers.
I have tried to link as linked server. I was able to link to access file using this code"
DECLARE #AccessFileName nvarchar(32);
DECLARE #FilePath nvarchar(max);
DECLARE #CombinedPath nvarchar(max);
SET #AccessFileName = N'MasterDatabase.accdb';
SET #FilePath = N'Y:\';
SET #CombinedPath = #FilePath + #AccessFileName;
IF EXISTS (
SELECT srv.name
FROM sys.servers srv
WHERE srv.server_id != 0
AND srv.name = N'MasterDatabase' )
BEGIN
EXEC master.dbo.sp_dropserver
#server=N'MasterDatabase'
END
EXEC master.dbo.sp_addlinkedserver
#server = N'MasterDatabase',
#provider = N'Microsoft.ACE.OLEDB.12.0',
#srvproduct = N'Access2007',
#datasrc= #CombinedPath
I tried to connect to a test database with same path and no luck there either.
I have checked permissions and shared that folder with everyone.
I have checked and made sure Access is installed on executing server.
How can I run a query on this db?
I have just found out that i think it is the wrong bit level driver please inform me how to fix or work around.

SQL Server 2012 -- xp_fileexist returns 0 when checking for file on local machine

The SQL server exists on the same machine I am physically logged into, and xp_fileexist is failing to recognize any files on the D drive, which is not a network drive. I already configured xp_cmdshell and restarted the SQL server instance. Any other ideas?
Yup, we had the same problem. On SQL Server 2008, our legacy xp_fileexist code worked fine, but on SQL Server 2012... nope.
It would work if we ran the xp_fileexist command as ourselves (with Admin rights) but not when we ran it as a SQL Server user, who didn't exist as an Active Directory user. Even if we changed the security on that folder to give Everyone full permissions, the xp_fileexist would fail, always returning a 0, as if a file within that folder didn't exist.
However, what did work was to use dir from within a Stored Procedure, and test if the file existed that way. (Yeah, I know... I'm rolling my eyes myself... this is dodgy..)
Here's the Stored Procedure I wrote, based on suggestions on this site :
CREATE PROCEDURE [dbo].[DoesFileExist]
(
#directoryName NVARCHAR(500),
#filename NVARCHAR(500)
)
AS
BEGIN
-- Does a file exist in a particular folder ?
--
-- EXEC [dbo].[DoesFileExist] 'D:\MyFiles', 'SomeExcelFile.xls'
--
DECLARE #bFileExists INT
DECLARE #cmd nvarchar(300);
SELECT #cmd = 'dir ' + #directoryName + '\' + #filename;
DECLARE #dir TABLE ([output] varchar( 2000 ))
INSERT INTO #dir
EXEC master.dbo.xp_cmdshell #cmd;
-- Uncomment the following line, if you want to see what
-- a "dir" looks like from SQL Server !!
-- SELECT * FROM #dir
if EXISTS(SELECT * FROM #dir WHERE [output] LIKE '%' + #filename + '%' )
BEGIN
-- File *was* found in this folder
SET #bFileExists = 1
END
ELSE
BEGIN
-- File was NOT found in this folder
SET #bFileExists = 0
END
SELECT #bFileExists
END
You can call this SP simply by passing it a folder name and a filename:
EXEC [dbo].[DoesFileExist] 'D:\MyFiles', 'SomeExcelFile.xls'
And yes, strangely, it does seem to work, for the SQL Server users who can't use xp_fileexist.
Remember that, to use this code, your SQL Server user must have permissions to use xp_cmdshell :
GRANT EXECUTE ON xp_cmdshell TO YourSQLServerUser

Can a SSIS package called using xp_cmdshell enlist in a SQL Server transaction?

I have a very basic SSIS package with one data flow task (from an OLE DB Source to a Flat File).
The TransactionOption property is set to Required and I have tried the IsolationLevel option set to ReadCommitted, ReadUncommitted and Serializable.
The package exports all rows from a table [TestTable] to the flat file.
I have the following SQL script (that I'm running in Management Studio for the moment):
BEGIN TRANSACTION
DELETE FROM [dbo].[TestTable]
DECLARE #SsisString VARCHAR(8000)
DECLARE #PackageName VARCHAR(200)
DECLARE #ServerName VARCHAR(100)
DECLARE #ReturnCode INT
SET #PackageName = 'TransactionalTestPackage'
SET #ServerName = 'SERVERNAME'
SET #SsisString = 'dtexec /sq ' + #PackageName + ' /ser ' + #ServerName + ' '
EXEC #ReturnCode = xp_cmdshell #SsisString
SELECT #ReturnCode
--COMMIT TRANSACTION
ROLLBACK TRANSACTION
Note that I'm deleting all the rows from the table before running the package, so in theory the package should export zero rows to the file, but what is actually happening is the package is hanging (I think because of the uncommitted delete on the TestTable). Question is: Does the SSIS package called in this way actually enlist in the transaction started at the top of the SQL block, and if not, can it?
The actions in the xp_cmdshell are going to be outside of the transaction, doesn't matter if it's SSIS or another query. You could just as easily replaced the #ssisstring with 'sqlcmd -S myserver -d mydatabase -Q "SELECT TOP 1 FROM dbo.TestTable"
If you need transactions, do it in SSIS. Put your DELETE statement as an Execute SQL Task. Wire that up to your data flow task. At the package level (right click on the background of the control flow and select properties) change the package's transaction level from Supported to Required. This will start a transaction. Everything contained within it will enlist in the parent transaction unless you explicitly opt out of the transaction by changing the default transaction level from Supported to NotSupported.

How to have database name as variable in an SP?

We use stored procedures exclusively here, and that raises a little problem. We cross reference two different databases like dbdev..table1 in dev, dbqa..table1 in qa, and dbprod..table1 in production.
So every time we deploy to a different environment, we have to search and replace from dbdev to dbqa or dbprod.
Is there a way to use synonym or whatever sql server mechanics to solve problem?
Use sqlcmd variables, which are supported by sqlcmd deployment of .sql provisioning scripts,a s well as by VSDB projects. So your provisioning script looks like:
create procedure usp_myProc
as
select .. from [$(crossdb)]..table1;
go
When deploying it in production you run sqlcmd /E /I provisoning.sql /v crossdb=dbprod, while the QA deployment will be done via sqlcmd /E /I provisioning.sql /v crossdb=dbqa. See Using sqlcmd with Scripting Variables.
As a side note, I am working on a project that allows sqlcmd variables to be used from .Net SqlClient (SqlConnection, SqlCommand): the dbutilsqlcmd project.
SQL Server 2005 supports synonyms, so you can create synonym1 to refer to dbdev..table1 in dev environment, and to dbprod..table1 in prod environment. Your SP's (and probably views) just operate on the synonyms.
Update:
The easiest way to create synonyms:
exec sys.sp_MSforeachtable
'print ''CREATE SYNONYM '' + REPLACE(''?'', ''].['', ''].[syn_'') +
'' FOR [my_database].?
GO'''
(there is a line break before GO)
Run and paste result into new query window.
No.
It is not possible to create a Synonym for a database. That is a popular request though.
Is it really necessary to rename your databases for dbdev, dbqa, dbprod etc. though?
Dynamic sql
(forgive potential typos, but the concept is there)
Declare #dbname nvarchar(255), #sql nvarchar(max)
set #dbname = 'db1'
Set #sql = 'Select * From ' + #dbname + '.dbo.table1'
exec sp_executesql #sql
You can have the database name as a parameter of your stored procedure, then use Dynamic SQL to construct your queries.
Ex:
CREATE PROC MyStoredProcedure #DBName VARCHAR(50)
AS
DECLARE #SQL VARCHAR(MAX)
SET #SQL = 'SELECT * FROM ' + #DBName + '.dbo.table1'
EXEC sp_executesql #SQL
Then you would simply call your stored procedure with the appropriate DB Name:
EXEC MyStoredProcedure 'dbdev'

Resources