I have 3 SQL Servers, and I'm getting strange behavior with OpenRowset.
Given:
Server 1 = 192.168.1.1,
Server 2 = 192.168.1.2,
Server 3 = 192.168.1.3,
Server 4 = 192.168.1.4
SQL:
SELECT a.*
FROM OPENROWSET('SQLOLEDB',
'Data Source=192.168.1.1;Persist Security
Info=True;uid=sa;pwd=password',
'SELECT * FROM dfs_database.dbo.dfs_vehicledata ') AS a;
Here is the strange part: if I run the above SQL statement on servers .3 and .4, everything works fine.
However, if I run the SQL statement on server .2, I get:
OLE DB provider "SQLNCLI11" for linked server "(null)" returned message "Deferred prepare could not be completed.".
Msg 8180, Level 16, State 1, Line 7
Statement(s) could not be prepared.
Msg 208, Level 16, State 1, Line 7
Invalid object name 'dfs_database.dbo.dfs_vehicledata'.
So what could make one relationship not work when the others work fine? Any ideas? They are all SQL Server express, and all report having SQLNCLI11 providers.
Using OpenRowSet it look like this:
sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO
OPENROWSET('SQLNCLI',
'Server=ipHere\ExtentionNameifHas;Database=DBName;Uid=userName;PWD=Password;'
,'SET FMTONLY OFF;SET NOCOUNT ON;SELECT * FROM
dfs_database.dbo.dfs_vehicledata'
From the error log try changing the OLE DB provider name from 'SQLOLEDB' to 'SQLNCLI11' and also
check the location of the object. Make sure to give the full location with database, table etc.
Related
I have a set of SQL queries that need to be run against 3 databases, they are stored on 2 different servers that have been linked.
All 3 databases have the the exact same tables and tables name, however the database names are different.
The queries have been written and all use just table names not the full database.dbo.table syntax so I can't use an automated find and replace on "linked.database1" to "linked.database2"
All the queries will always be executed through one server "Server1"
I'm trying to come up with a method of passing the queries to one of the linked servers but have a "use" command go through as it means I only have to change the database in the "use" line.
So far I have tried the following from Server1:
Select * from [Linked].Database.DBO.Table - Successful
Exec ('Select * from [Linked].Database.DBO.Table') - Successful
Direct on Server2 (using the account the linked server operates on):
EXEC ('Use Database; SELECT * from Table') - Successful
So with these above three I can ascertain
The login on Server1 can reach the databases needed and can access the data with a basic select and when passed with and Exec command.
The account on Server2 can run the Exec command and passing the "Use Database" line with Exec works on Server2.
However when I try using the below:
Select * from openquery ([Linked], 'Exec (Use Database; Select * from Table)')
I get the following error:
OLE DB provider "SQLNCLI10" for linked server "172.20.11.123" returned message "Deferred prepare could not be completed.".
Msg 8180, Level 16, State 1, Line 7
Statement(s) could not be prepared.
Msg 102, Level 15, State 1, Line 7
Incorrect syntax near ')'.
Msg 156, Level 15, State 1, Line 7
Incorrect syntax near the keyword 'Use'.
Have I messed up the syntax anywhere in the OpenQuery or can the USE command never be passed through OpenQuery.
If what I'm trying to do with OpenQuery and USE isn't possible then is there a way of passing the database you want the OpenQuery run against in the statement?
Or as a second thought, is there a way of putting together the Linked Server account so that it uses a particular database as its default database?
No, the way to do this, as far as I can tell, if you know which database you need to execute against:
DECLARE #database sysname = N'Database1';
DECLARE #sql nvarchar(max) = N'SELECT * FROM dbo.Table;';
DECLARE #exec nvarchar(4000) = N'[Linked].'
+ QUOTENAME(#database) + N'.sys.sp_executesql';
EXEC #exec #sql;
I'm not quite sure what this was trying to accomplish:
Select * from openquery ([Linked],
'Exec (Use Database; Select * from Table)')
But if you take out from that what you're trying to tell [Linked] to EXEC, it's this:
Exec (Use Database; Select * from Table)
Try that anywhere. Broken. You might get it to work like this, as #AlwaysLearning suggested:
Select * from openquery ([Linked],
'Exec (''Use Database; Select * from Table'')')
...but that's kind of, like, really gross, compared to the solution at the top. Unless you absolutely need to select from openquery for some reason.
Looking for pointers on how to resolve this issue.
I have a linked server setup.
This query works in SSMS, I get rows back.
SELECT tbl.[Col1]
,tbl.[CoL2]
FROM [LINKEDSERVER].[CATALOG].[SCHEMA].[TABLENAME] tbl
But trying to do the same in SSMS with OPENQUERY fails
SELECT [Col1]
FROM OPENQUERY([LINKEDSERVER],
'SELECT tbl.[Col1]
,tbl.[CoL2]
FROM [LINKEDSERVER].[CATALOG].[SCHEMA].[TABLENAME] tbl'
) As Whatever
The messages are as follows:
OLE DB provider "SQLNCLI11" for linked server "SERVER" returned
message "Deferred prepare could not be completed.". Msg 8180, Level
16, State 1, Line 1 Statement(s) could not be prepared. Msg 7202,
Level 11, State 2, Line 1 Could not find server 'SERVER' in
sys.servers. Verify that the correct server name was specified. If
necessary, execute the stored procedure sp_addlinkedserver to add the
server to sys.servers.
The server name SERVER does appear when I check select * from sys.servers
OPENQUERY from here against other linked servers is successful.
Because when you use OPENQUERY you send the query you want to run on the remote server. The error is being thrown by the remote server. Take out the linked server name in the query. Something along these lines.
SELECT [Col1]
FROM OPENQUERY([LINKEDSERVER],
'SELECT tbl.[Col1]
,tbl.[CoL2]
FROM [CATALOG].[SCHEMA].[TABLENAME] tbl'
) As Whatever
This sentence its use with another server but , its ok try this:
EXEC SP_SERVEROPTION 'SERVER\INSTANCIA' ,'DATA ACCESS',TRUE
SELECT * FROM OPENQUERY(YOURSERVER,'SELECT * FROM TABLE').
And its done. :)
Is there any way to find the SQL query errors without executing the query in SQL server?
For example,
Use TestDB
Select * from Employee1
Consider TestDB doesn’t contain any table named “Employee1”. In this case, while we running this query, we will get the “Invalid object name Employee1” SQL error.
My question is that, after writing the query, is there any better approach to find these errors without executing?
I got a comment from my colleague is that use the sp_describe_first_result_set System stored procedure.
If you have 2012 and above you can use the sp that your colleague has mentioned.
If you use 2008 R2 and less then use
SET FMTONLY ON;
Select * from MyTabl;
SET FMTONLY OFF;
Msg 208, Level 16, State 1, Line 3
Invalid object name 'MyTabl'.
This will execute the query but not process any data. NOEXEC only parses the query so any objects that don't exist will not be flagged. NOEXEC checks syntax only. So what you want is either sp_describe_first_result_set or FMTONLY.
Alternatively if you have a select then you can also append to your where 1=2. For example
SELECT *
FROM MyTabl
WHERE 1=2
which gives them same result
Msg 208, Level 16, State 1, Line 3
Invalid object name 'MyTabl'
I'm running sql server 2008 and I'm trying to run the query
OPEN CUR_InvHeader
FETCH NEXT FROM CUR_InvHeader INTO
#CH_iBilling_Log_RecID
WHILE (##FETCH_STATUS = 0) BEGIN --Loop for Cur_InvHeader
select * into tarInvoiceDetail_201101 FROM OPENROWSET('SQLNCLI', 'Server=(local);Trusted_Connection=yes;',
'EXEC _sp_cwm5_GetInvoiceDetail #CH_iBilling_Log_RecID')
I get the error
OLE DB provider "SQLNCLI10" for linked
server "(null)" returned message
"Deferred prepare could not be
completed.".
I've run sp_configure 'ad hoc..', 1
reconfigure with override
to ensure i can run the select against the openrecordset
any ideas what i might be doing wrong?
thanks in advance
The first thing that's wrong is that your "EXEC _sp_cwm5_GetInvoiceDetail #CH_iBilling_Log_RecID" statement will be evaluated as a constant, rather than pass the value of #CH_iBilling_Log_RecID through to OPENROWSET. You'd have to replace the whole "SELECT * INTO..." into a string variable and run sp_executesql on it.
The second thing wrong is that your "select into" statement will create tarInvoiceDetail_201101 every time, as INTO creates a new table when run. So if your cursor covers more than one row you'll get an error on the second pass.
Also, what does "Server=(local)" represent here? Are you trying to use OPENROWSET against your local copy of SQL Server while connected to a remote server? Or are you trying to use OPENROWSET to get around the limitation that you can't directly use a stored procedure as the source for an INSERT?
i use sql server 2008 for publisher and sql server 2005 express for subscriber ,
when i insert to a table from my subscriber this error occur :
Msg 21079, Level 16, State 1, Procedure sp_getpublisherlink, Line 52
The RPC security information for the Publisher is missing or invalid. Use sp_link_publication to specify it.
Msg 20512, Level 16, State 1, Procedure sp_MSreplraiserror, Line 8
Updateable Subscriptions: Rolling back transaction.
Msg 3609, Level 16, State 1, Line 1
The transaction ended in the trigger. The batch has been aborted.
when insert to table from publisher all thing is ok .
Try creating the link on the subscriber. Run this on your subscriber database.
sp_link_publication #publisher = '{publisher instance name}'
, #publisher_db = '{published database name}'
, #publication = '{publication name}'
, #security_mode = '1'
, #login = '{sql server login account to connect publisher}'
, #password = '{password}'
, #distributor = '{distributor instance name}'