Remote table-Valued Function Calls are not allowed - sql

How can I make this work?Im running a table valued function from a remote linked server. i tried adding no lock to this 4 part naming but still i get the same error. Im using mssql-2008
select * from [110.10.10.100].testdbname.dbo.ufn_getdata('4/25/2013') as tb;(NOLOCK)

You need to add WITH (NOLOCK). Not entirely sure why but I just ran into this issue today and this solved my issue.
SELECT *
FROM [110.10.10.100].testdbname.dbo.ufn_getdata('4/25/2013') AS tb WITH (NOLOCK);

Nolock doesn't work for me.
However, using OPENQUERY does...
Replace DMS_DB.dbo.tfu_V_DMS_Desktop(''de'')' with [110.10.10.100].testdbname.dbo.ufn_getdata(''4/25/2013'')
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tfu_V_DMS_Desktop]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[tfu_V_DMS_Desktop]
GO
CREATE FUNCTION [dbo].[tfu_V_DMS_Desktop]
(
#param1 int
)
RETURNS table
AS
RETURN
(
-- Add the SELECT statement with parameter references here
-- SELECT 0 as abc
SELECT * FROM OPENQUERY(CORDB2008R2, 'SELECT * FROM DMS_DB.dbo.tfu_V_DMS_Desktop(''de'')')
)
GO
On a footnote, the problem is OPENQUERY doesn't allow a variable, so you cannot have variable parameters.
You can however reference all tables and views as views from a remote server, and just create the table-valued function 1:1 locally. This will probably be slow, however.

Following SQL OpenQuery command should be working
Parameter values which are surrounded with ' are replaced with double ''
So in this case there is no need to create a stored procedure on the target instance database
SELECT *
FROM OPENQUERY(
[110.10.10.100],
'SELECT * FROM testdbname.dbo.ufn_getdata(''4/25/2013'')'
) as oq

Also make sure that RPC OUT is set to TRUE in linked server options. This option also needed when you try to execute stored procedure on linked server. Otherwise you will get following error.
Server 'servername' is not configured for RPC

See this answer:
Use OPENQUERY
Replace SP call with SELECT ... FROM fn() query and it should work.

This is the example of calling a remote SQL user defined function returning a table as output in SQL Server 2014. It is working for me.
Declare #Param1 Varchar(10)
Declare #SqlText nvarchar(4000)
Set #Param1 = 'xxx'
Set #SqlText = 'SELECT * FROM Database.dbo.ufn_Function (''' + #Param1 + ''')'
EXEC LinkedServer.Database.dbo.sp_executesql #SqlText

Related

SQL OpenQuery variable tablename

I need to transfer data from a linked server to our main SQL server. The issue is, that the table name changes everyday.
I have looked around this site to find out if it is even possible to have a variable database name, which it is, but also to see if it is possible to have variables in a OPENQUERY, which it also is.
But i am struggling to combine those needs, so i have a variable table name in a OPENQUERY.
I need something like this:
Declare #LinkedServer as varchar(max) = 'LinkedServer'
Declare #TName as varchar(max) = 'TName'+substring(cast(cast(getdate() as date) as
varchar(50)),1,4)+substring(cast(cast(getdate() as date) as
varchar(50)),6,2)+substring(cast(cast(getdate() as date) as
varchar(50)),9,2)
SELECT * FROM OPENQUERY(#LinkedServer, 'SELECT * FROM dbo.#TName')
Is there any way i can make a variable table name in a OPENQUERY ?
Thank you for your help.
/Mikkel
I'd write a synonym which gets updated every day before you kick off your data extraction job. Then you don't need to be updating (potentially a tonne of) references.
CREATE SYNONYM LinkedTableA
FOR
ServerName.DBName.dbo.TName20170331
SELECT * FROM LinkedTableA
The answer i have, is this:
USE [DataBase]
GO
DROP SYNONYM [dbo].[eCallByCallStat]
GO
declare #tablename varchar(50)
set #tablename = 'Server1..dbo.eCallByCallStat'+substring(cast(cast(getdate()-1 as date) as varchar(50)),1,4)+substring(cast(cast(getdate()-1 as date) as varchar(50)),6,2)+substring(cast(cast(getdate()-1 as date) as varchar(50)),9,2)
declare #sql varchar(500)
set #sql = 'CREATE SYNONYM [dbo].[eCallByCallStat] FOR ' + #tablename
exec (#sql)
This will run everymorning updating the table name in the synonym, and then we will insert that data into a prober table so we have all the data.

SQL Server Linked Server Join

I have added a linked server in my sql server 2008. I want to fetch data from a table and a table valued function residing on my linked server and join this data on a local table by following below given naming convention.
<server>.<database>.<schema>.<table>
However my first problem is I need to fetch <server> part from a table. So when I try to do something like following it fails
Select * FROM #ServerNameVariable.database.dbo.myTable
Any idea how can I form fully qualified linked server table name with a user defined variable ?
My SP is as follows
CREATE PROCEDURE TEST_SP
AS
BEGIN
DECLARE #NetworkDBName VARCHAR(255)
SET #NetworkDBName = '[MyLinkedServerName]'
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
select * from #NetworkDBName + '.' + testDatabase.dbo.Invoice_tb
END
GO
You cannot use variables in place of database, schema or table names.
Instead you can build and execute dynamic SQL statements, using sp_ExecuteSQL.
This example won't work, as the server name is seen as a string and not a server object.
Failed Example
/* Anti-pattern.
* Does not work.
*/
DECLARE #Server SYSNAME = 'Server001';
SELECT
*
FROM
#Server.Database1.dbo.Table1
;
This example shows a method that does work. Here the SQL statement is built as a string, which is then executed.
/* Dynamic SQL statement.
* Will work.
*/
DECLARE #Server SYSNAME = 'Server001';
DECLARE #Statement NVARCHAR(255);
SET #Statement = 'SELECT * FROM ' + QUOTENAME(#Server) + '.Database1.dbo.Table1;';
EXECUTE sp_ExecuteSQL #Statement;
As ever; please be careful when generating and executing dynamic SQL statements. You do not want to open yourself up to SQL injection attacks. Look into OPENROWSET or check the passed server name against the code kindly supplied by #Devart above (SELECT name FROM sys.servers WHERE server_id > 0) before executing.
EDIT 1: Added more detail to the paragraph on SQL injection.
EDIT 2: Removed square brackets from 2nd example query, replaced with QUOTENAME, as per #TTs comment.
Use the name of link server it will a 4 part qualifier e.g
Select * From [Link Server Name ].[Database].[Schema].[Table]

Issue in passing parameter on stored procedure

I have created a procedure without any problem. I have tested before creating the procedure but when I try to execute my procedure I have a problem only in the first parameter I have
SQL SERVER 2008 SHOW ME Error syntax in 'Mundus'
ProcAvancementTotalbyEtab 'Erasmus Mundus','C:\Users\AA\Desktop\Table1.xlsx'
and After I try to make like this:
ProcAvancementTotalbyEtab N'Erasmus Mundus','C:\Users\AA\Desktop\Table1.xlsx'
This is my stored procedure:
alter proc ProcAvancementbyEtab
(
#nameEtabb nvarchar(50),
#FilePath nvarchar(60)
)
as
begin
EXEC
(
'
SET NOCOUNT OFF;
insert into Avancement(nameEtab)
SELECT distinct T.[EFP]
From OPENROWSET(''MICROSOFT.ACE.OLEDB.12.0'',
''Excel 12.0;Database='+#FilePath+''',
''SELECT *
FROM [Sheet1$]'') T
where T.[EFP] is not null and T.[Avancement] is not null
and
not exists (select * from Avancement where
Avancement.nameEtab=T.[EFP])
and T.[EFP]='+#nameEtabb+'
')
end
When I comment this line
and T.[EFP]='+#nameEtabb+'
it works fine so my probleme is here
and T.[EFP]='+#nameEtabb+'
and when I test without stored procedure it work also OMG.
My guess is that name is stored as a string. You need an extra pair of quotes:
and T.[EFP] = '''+#nameEtabb+'''

SQL Server stored procedures to copy tables

I have to move a table into other table using a stored procedure by passing the table names as parameters.
Syntax is:
alter procedure [dbo].[moving]
(
#to_table varchar(50),
#from_table varchar(50)
)
as
begin
EXEC('Select * into '+#to_table+'from '+#from_table)
end
while executing by.
exec moving newtable,hello
It is giving an error:
Incorrect syntax near 'hello'
pls anyone give solution for this
Try:
exec moving 'newtable','hello'
It also looks like you are going to need to fix your SP. You will need a space before from:
EXEC('Select * into '+#to_table+' from '+#from_table)
Read EXECUTE syntax and try,
EXEC moving 'newtable','hello'
SELECT ... INTO needs to create table, if table exists use INSERT INTO ... SELECT ..FROM
AND
in your case you need to run SP in such a way:
EXEC dbo.moving 'table1', 'table2'
BUT
EXEC('Select * into '+#to_table+' from '+#from_table)
will not work, you need to rewrite it with variable:
declare #sql nvarchar(max)
SET #sql = N'Select * into ['+#to_table+N'] from ['+#from_table+N']'
EXEC(#sql)
BUT
you also need to worry of sql injections and complex table names AT LEAST, so - for complex table names I already framed your tables with square braces, and you need to do something to prevent sql injections.
And once more - SELECT...INTO works only if you creating new table with name from #to_table parameter
add an extra space after single quote and FROM
EXEC('Select * into ' + #to_table + ' from ' + #from_table)

Execute stored proc with OPENQUERY

I have SQL Server 2008 with a linked Sybase server and I am trying to execute a stored procedure on the Sybase server using OPENQUERY. If I have a stored proc that doesn't take parameters it succeeds fine. If I have a stored proc with parameters it fails. I even tried a very basic stored proc that only took an int an that still failed. Below is the syntax I am using:
select * from
OPENQUERY([LINKSERVER],'exec database.user.my_stored_proc ''AT'',''XXXX%'',''1111'',1')
Msg 7357, Level 16, State 2, Line 3
Cannot process the object "exec database.user.my_stored_proc 'AT','XXXX%','1111',1". The OLE DB provider "ASEOLEDB" for linked server "LINKSERVER" indicates that either the object has no columns or the current user does not have permissions on that object.
As the proc will execute just fine without parameters, I don't think it is a permission issue.
This worked for me,
SELECT * FROM OPENQUERY(LOCALSERVER, 'SET FMTONLY OFF EXEC snr.dbo.GetAllSignals #controlRunId = 25, #experimentRunId = 26')
I was creating temporary tables, and that's why i got access denied
Here is more info http://www.sommarskog.se/share_data.html#OPENQUERY
I create a sp that doesn't return any value and it doesn't work.
Your SP in mysql have to return a value!
for example I do this in "mysql":
CREATE DEFINER=`root`#`localhost` PROCEDURE `MyPro`(IN `Name` VARCHAR(50), IN `Id` INT, OUT `Result` INT)
MODIFIES SQL DATA
BEGIN
DECLARE Result INT;
SET Result = 0;
INSERT into MyTable (Id,Name) VALUES(Id,Name);
SELECT Result;
END
That "Id" and "Name" is input parameter and "Result" is output parameter
and create linked server in SQL SERVER and call it like this:
select * from openquery
(
Test,'call mydb.MyPro(''Name'',''16'', #P0);'
)
It works for me :D
Linked Servers and OPENQUERY, Gems to MS SQL Server...that are wolves in sheep clothing. I've found the following solutions to work when dealing with parameters
If the SP is basically just SELECT statements, the move the same to a VIEW and just pass SQL statements via OPENQUERY.
Build the OPENQUERY as a string and then use execute_sql.
You could also see if it works to precede exec with SET FMTONLY ON:
OPENQUERY([LINKSERVER],'SET FMTONLY ON; exec database.user.my_stored_proc ''AT'',''XXXX%'',''1111'',1')
If you try this and it works, you should probably Google FMTONLY+OPENQUERY to get an idea of what it means.
Try this,
SELECT * FROM OPENQUERY(linked_server_name, 'SELECT postgres_procedure_name (parameters)');
I experienced a very similar issue, but my SP wasn't taking any parameters.
I tried experimenting with altering the query sent through the openquery to include 'SET NOCOUNT ON' and 'SET FMTONLY OFF' but this had no difference.
The only solution that worked for my stored procedure was dropping the existing version, and altering the code to specifically 'SET NOCOUNT ON'
After doing this I was able to successfully run my stored proc through my linked server connection.
First of all you have to add hard code text fields then you have to
replace it by your parameters value like FromDate,TillDate,EmpID,CompCode,0,DeptID,DesgId,LocationID,AtnType
DECLARE #startdate varchar(255) = '2019-12-17'
DECLARE #enddate varchar(255) = '2019-12-17'
Set #SQL = 'SELECT * FROM OPENQUERY(' + quotename(#LinkedServer) + ',' + '''' +
'SET FMTONLY OFF; exec [TAP].[dbo].[GetAttendanceList] ' + 'FromDate,TillDate,EmpID,CompCode,0,DeptID,DesgId,LocationID,AtnType,1'')'
You have to replace your parameters values shown below
set #SQL=REPLACE(#SQL,'FromDate',+''''+''''+#startdate+''''+'''')
set #SQL=REPLACE(#SQL,'TillDate',+''''+''''+#enddate+''''+'''')
set #SQL=REPLACE(#SQL,'CompCode',+''''+''''+#CompCode+''''+'''')
set #SQL=REPLACE(#SQL,'AtnType',+''''+''''+''''+'''')
if #EmpID is Null
begin
set #SQL=REPLACE(#SQL,'EmpID','null')
end
if #DeptID is Null
begin
set #SQL=REPLACE(#SQL,'DeptID','null')
end
if #DesgId is Null
begin
set #SQL=REPLACE(#SQL,'DesgId','null')
end
if #LocationID is Null
begin
set #SQL=REPLACE(#SQL,'LocationID','null')
end
print #SQL
exec ( #SQL)