SQL linked server Python pyodbc insert error - sql-server

I'm having an interesting error when I'm trying to trigger an SP on a local SQL Server with two linked servers.
The purpose of the exorcise above is to move data from one linked server to another.
When I'm triggering the stored procedure from SSMS it works like a charm, but when I trigger it from Python I'm getting these sexy error messages:
(
'42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The OLE DB provider "SQLNCLI11" for linked server "XXXX" reported an error. One or more arguments were reported invalid by the provider. (7399) (SQLExecDirectW)
; [42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The operation could not be performed because OLE DB provider "SQLNCLI11" for linked server "XXXX" was unable to begin a distributed transaction. (7391)
; [42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]OLE DB provider "SQLNCLI11" for linked server "XXXX" returned message "The parameter is incorrect.". (7412)'
)
In short my python scripts (that fails with the errors above) looks as follows:
MyConn = pyodbc.connect(DRIVER="ODBC Driver 17 for SQL Server",SERVER=os.environ["sqlServer"],UID=os.environ["sqlUID"],DATABASE=os.environ["sqlDB"],PWD=os.environ["sqlPWD"])
Cursor = MyConn.cursor()
sqlQuery = "exec dbo.usp_XXXXETL #LookBackDays = 0"
Cursor.execute(sqlConta)
I've also tested the connection above; I'm able to run select statements against the linked servers from python.
What's even more annoying is that when I write it in R it works:
conn = odbcDriverConnect("Driver={ODBC Driver 17 for SQL Server};Server=*SameServer*;Database=*SameDB*;Uid=*Uid*;Pwd=*Pwd*;Connection Timeout=360;")
sqlExecute(
conn,
query="dbo.usp_XXXXETL #LookBackDays = 0",
fetch=FALSE,
errors=TRUE,
query_timeout=300)
Obviously it works so it's no big problem, it's just that I hate R-scrips and am sort of puzzled by the error.
In advance many thanks for your time and brain power!

You've started a transaction, and the linked server is configured to enlist the remote server in the transaction, which required MSDTC. So
1) Don't start a transaction. You've probably got autocommit off, which causes the session to use implicit transactions.
2) Disable the remote proc transaction promotion option for the linked server with sp_serveroption
3) Troubleshoot MSDTC to enable the distributed transaction.

Related

Can't connect to Azure SQL Server from 1/3 of our servers

I was trying to create a linked server from an on-premises SQL Server (BadMachine1), to an Azure SQL Server.
Code for creating the linked server
EXEC sp_addlinkedserver D365BI_Testing, '', 'SQLNCLI11', #datasrc='blabla.database.windows.net', #catalog = 'DbName'
EXEC sp_addlinkedsrvlogin D365BI_Testing, 'false', null, 'blabla_Admin', 'thepassword'
Created fine, but when testing connection on BadMachine1, this error message:
TITLE: Microsoft SQL Server Management Studio
------------------------------
The test connection to the linked server failed.
------------------------------
ADDITIONAL INFORMATION:
An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)
------------------------------
TCP Provider: The specified network name is no longer available.
Client unable to establish connection because an error was encountered during handshakes before login. Common causes include client attempting to connect to an unsupported version of SQL Server, server too busy to accept new connections or a resource limitation (memory or maximum allowed connections) on the server.
OLE DB provider "SQLNCLI11" for linked server "D365BI_Test2" returned message "Client unable to establish connection due to prelogin failure".
OLE DB provider "SQLNCLI11" for linked server "D365BI_Test2" returned message "Client unable to establish connection". (Microsoft SQL Server, Error: 64)
For help, click: https://learn.microsoft.com/sql/relational-databases/errors-events/mssqlserver-64-database-engine-error
------------------------------
BUTTONS:
OK
------------------------------
OK, tested on two other machines we have (GoodMachine1, GoodMachine2) - all of these are in the same data center. The test connection succeeded on both GoodMachine1 and GoodMachine2, and I could successfully write a query from Goodmachine1 and GoodMachine2's SQL Server, to the Azure SQL Server.
Next test:
Tried logging into each of the 3 machines, and opening up SSMS to try to connect to the Azure SQL Db. Connection worked on GoodMachine1 & GoodMachine2. Failed on BadMachine1, with the following error message.
TITLE: Connect to Server
Cannot connect to blabla.database.windows.net.
------------------------------
ADDITIONAL INFORMATION:
A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 0 - The specified network name is no longer available.) (Microsoft SQL Server, Error: 64)
For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft%20SQL%20Server&EvtSrc=MSSQLServer&EvtID=64&LinkId=20476
------------------------------
The specified network name is no longer available
------------------------------
BUTTONS:
OK
------------------------------
I don't have access to check, but I'm told the firewall rules are OK on the Azure side.
There are some characteristics that differ among the 3 machines:
BadMachine1: ODBC Driver 11, old "Microsoft AS OLE DB Provider for SQL Server 2014". SQL Server 2014
GoodMachine1: ODBC Drivers 11, 13, 17, no OLE driver. SQL Server 2016
GoodMachine2: ODBC Driver 13, recent install of OLE driver. SQL Server 2016
Could the old ODBC driver on BadMachine1 be it? Other ideas? Apologies in advance, I've never tired to setup a linked server before, and don't really know what I'm doing very well.
Turns out our IT was blocking those outbound connections from BadMachine1. Now that they're unblocked, the linked server works fine.

SQL Server -- CREATE EXTERNAL FILE FORMAT to query Parquet files via Polybase -- failing due to TCP error

Context: I'm trying to use SQL Server's Polybase to query data in parquet files. One of the steps required to do so is to create an external file format that maps to parquet. MSDN provides SQL sample below.
CREATE EXTERNAL FILE FORMAT parquet_file_format
WITH (
FORMAT_TYPE = PARQUET,
--DATA_COMPRESSION = 'org.apache.hadoop.io.compress.SnappyCodec'
DATA_COMPRESSION = 'org.apache.hadoop.io.compress.GzipCodec'
);
When I execute it I get the following error.
OLE DB provider "MSOLEDBSQL" for linked server "(null)" returned message "Login timeout expired".
OLE DB provider "MSOLEDBSQL" for linked server "(null)" returned message "A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.".
Msg 10061, Level 16, State 1, Line 40
TCP Provider: No connection could be made because the target machine actively refused it.
I've tried enabling TCP network protocol
and also tried configuring the remote access server configuration option neither of which resolve the error.
EXEC sp_configure 'remote access', 0 ;
GO
RECONFIGURE ;
GO
Question: Can someone please point me in the right direction, or tell me what I'm doing wrong?
Turns out issue was Polybase services weren't running. I was able to run them in the sql server configuraion manager under sql server network configuration. This was helpful: https://www.sqlservercentral.com/forums/topic/polybase-syntax-error

Error while calling stored procedure on linked server

I had configured a linked server to enable the SQL Server Database Engine to execute commands against OLE DB data sources outside of the instance of SQL server by executing sp_addlinkedserver procedure. After doing that I was trying to execute a procedure on a linked server using the following statement
EXEC [LinkedServer].[DatabaseName].[DatabaseOwner].[StoredProcedure] param1, param2
When I tried to execute the statement mentioned above it threw me the following error
OLE DB provider "SQLNCLI10" for linked server "server name" returned message "Unable to complete login process due to delay in opening server connection".
Msg 7303, Level 16, State 1, Line 1
Cannot initialize the data source object of OLE DB provider "SQLNCLI10" for linked server "server name".
I tried the following
Check if a linked server has remote access enabled
Increase remote query timeout
Check firewall to see if port was enabled.
What am I missing here? I appreciate your help.

SSIS Package Errors using OLE DB Command transformation

I recently begun upgrading a MS SQL Server 2005 instance to MS SQL 2012. I have created a VM and installed MS SQL Server and used backups to create the DBs on the new server.
In Visual Studio I was switching my old connections to the new connections and when I switched the connection of an OLE DB Command Transformation that contains the command "UPDATE JOB SET Active = 0 WHERE Job.JobId = ?" I received the following errors.
Error 1 Validation error.
Sync Jobs: Sync Jobs: SSIS Error Code
DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code:
0x80004005. An OLE DB record is available. Source: "Microsoft SQL
Server Native Client 11.0" Hresult: 0x80004005 Description: "The
metadata could not be determined because statement 'REVERT
--Check if SSB is enabled in this database' in procedure 'sp_send_dbmail'
does not support metadata discovery.". JobPack.dtsx 0 0
Error 2 Validation error.
Sync Jobs: Sync Jobs: Unable to retrieve
destination column descriptions from the parameters of the SQL
command. JobPack.dtsx 0 0
I checked to make sure this "SSB" was on in the new DB (it wasn't) but even after enabling it I still cannot resolve this error. I switch back to the old server and it works fine...
UPDATE:
I was wondering where the email procedure came into play and I found that the DB has a trigger that emails when updated. Disabling this trigger resolves the SSIS package issue. I still have no idea why BIDS shows an error in the editor when this trigger is enabled.
I was able to resolve this issue simply by switching from the Native SQL Driver to the MS SQL Driver on the transformation. I still have no idea why that works and why this caused a compatibility problem.
I came across a similar error.
An OLE DB record is available. Source: "Microsoft SQL Server Native Client 11.0" Hresult: 0x80004005 Description: "The metadata could not be determined because statement '....' uses a temp table.".
Work around.
If SP uses a #table or ##table and it is used in the SP, then we need to specify the #table structure along with the EXEC.
The SP should be given along with the structure.
EXEC SP_TestTemp 1,2
it should be given like
EXEC SP_TestTemp 1,2 WITH RESULT SETS
(
(
id int,
Marks int
)
)
Note: the 'retain same connection = true' and 'validate external metadata' = false did not help/work here.

VB.NET DataSet not working with view with linked SQL Server

I am in DataGrid hell right now but that's another post.
Anyway, I wrote a view with a union query in SQL Server that grabs data from a linked SQL server.
Anytime I try to add this object as a dataset in VB.NET it completely bombs out on me with this ugly error message...
ERROR [42000] [Microsoft] [ODBC SQL Server Driver] [SQL Server] The operation could not be performed because the OLE DB Provider 'SQLOLEDB' was unable to begin a distributed transaction. ERROR [01000] [Microsoft] [ODBC SQL Server Driver] [SQL Server] [OLE/DB provider returned message : new transaction cannot enlist in the specified transaction coordinator] ERROR [01000] [Microsoft] [ODBC SQL Server Driver] [SQL Server] OLE DB Error Trace [OLE/DB Provider 'SQLOLEDB' lTransactionJoin::JoinTransaction returned 0x8004d00a]
I'm completely stumped as to why I can't create a dataset from a view that references a linked SQL server. It's not this specific view either, all views that reference this linked server bomb out.
Any ideas?
Thanks.
This simple answer is to enable MSDTC on the servers. As to why this is happening on your views, I'm not entirely sure. There are also some good trouble shooting tips here.

Resources