Syntax error on stored procedure call to linked server? - sql

I've got an Informix machine I've configured as a linked server in SQL Server.
I can remotely send, and receive the results of, a query for, say
SELECT * FROM linkedServer.instanceName.database.myTable
but can't run the
linkedServer.instanceName.database.selectAllFromMYTABLE
stored procedure.
The error message I'm getting returned is "[Informix][Informix ODBC Driver][Informix]A syntax error has occurred." which is not massively helpful, except that it tells me that my request was received in some form...
Could someone tell me what the correct calling syntax would be to execute an Informix stored procedure via SQL Server? Presumably I'm screwing up the stored procedure call, because the stored procedure can be verified to be working fine on the Informix server.
EDIT: Adding the full text of a stored procedure I am testing, in order to verify I'm not doing something stupid in Informix which is causing a knock-on problem with the SQL Server execution:
CREATE FUNCTION sp_testSP()
RETURNING char(20) as item_no
DEFINE item_no char(20);
FOREACH
SELECT table_name.item_code
INTO item_no
FROM table_name
WHERE table_name.item_code LIKE 'test%'
RETURN item_no WITH RESUME;
END FOREACH;
END FUNCTION
As I've mentioned, this appears to work fine in RazorSQL, which I have connected to Informix, but maybe seeing this will jog someone's memory with some reason why SQL Server can't work with this return method...

Have you tried using OpenQuery?
http://msdn.microsoft.com/en-us/library/ms188427.aspx

In native Informix, you would write (approximately):
EXECUTE PROCEDURE database#linkedServer:selectAllFromMYTABLE();
I'm not sure quite where you'd fit an instance name into that - the 'linkedServer' corresponds to an instance name (to my way of thinking). The nearest approaches would be:
database#linkedServer:instancename.selectAllFromMyTABLE()
instancename#linkedServer:database.selectAllFromMyTABLE()
However, that is via the native Informix interfaces. If you go via SQL Server, then the syntax probably needs to be the native SQL Server syntax for invoking a procedure. In theory, I believe, the API used (ODBC or whatever) should be able to translate to the native Informix syntax.

Related

How to tell if ALTER PROCEDURE worked?

I'm pretty new to SQL and SQL Server. I'm trying to run an ALTER PROCEDURE query from a .sql file called through C# code. Before I move on to making sure my query does what it's supposed to do, I want to verify that my ALTER PROCEDURE query actually altered the procedure, but I don't know how to verify that.
For example, in SQL Server, I can see where the stored procedure I'm trying to edit lives, in:
- database-name
- Programmability/
- Stored Procedures/
- dbo.MyStoredProcedure
If my ALTER TABLE query worked correctly, would I be able to see my procedure code here, or would I check somewhere else? Or am I thinking about this the wrong way?
Generally, we rely on error and exception messages to tell us when something like this has not worked. However, I suppose that it might be possible that the procedure Alter-ed was not the one that was intended (implying bugs in the name/path/call construction, of course).
In that case, you can get the current text of any SQL Module (Procedure, View, Trigger, etc., anything script-baseD) from the sys.sql_modules table:
SELECT definition FROM sys.sql_modules
WHERE object_id=OBJECT_ID('dbo.UserSamples_Insert')
You should note that usually when something like this happens without an error message it is because either:
You are executing in the wrong database (like PROD when you meant to be in DEV or vice-versa), or
You are not using the correct Schema (because you can make and use schemas other than 'dbo').
Wait, you say ALTER PROCEDURE twice, but then the third time you say ALTER TABLE. Which is it? I ask because unlike almost every other SQL object, tables are not script-based and their definition cannot be found in any of the Sql script repositories like sys.sql_modules. I actually use either SMO (from a client) or a tool that #SeanLange wrote years ago for that (from the server itself).

Check database / server before executing query

I am frequently testing certain areas on a development server and so running a pre-defined SQL statement to truncate the tables in question before testing again. It would only be a slip of a key to switch to the live server.
I'm looking for an IF statement or similar to prevent that.
Either to check the server name, database name, or even that a certain record in a different table exists before running the query.
Any help appreciated
For such cases I use stored procedures. I'd call them TestTruncateTables, etc.
Then instead of calling TRUNCATE TABLE you should CALL TestTruncateTables.
Just make sure that the procedures are not created on the live server. If by any chance you happen to run CALL TestTruncateTables on the live server you only get an error about non-existing proc.

Getting results from Oracle stored procedure insertion through pyodbc

I am using pyodbc (version 3.0.7) to access an Oracle (version 11g) database. We are writing stored procedures to handle the insertions. The primary keys for inserted objects are assigned with triggers, so we want to get the newly-inserted object's primary key into python after the stored procedure is called by the python script. (Due to client requirements, we don't have the flexibility of changing database, libraries, etc.)
According to the pyodbc documentation, return (OUT) parameters in stored procedures are not supported. Neither are stored functions. The documentation suggests to add a SELECT statement to the end of a stored procedure to get results out. However, we are new to SQL scripting, and Google searching for the last two days has turned up a lot of information for SQLServer and other databases, but next to nothing for Oracle. Trying the SQLServer examples on the Oracle db has not been tremendously helpful, as the Oracle SQL Developer shows various errors with the syntax (DECLARE where one shouldn't be, INTO required for SELECT statements, etc.).
Ultimately, we want the stored procedure to insert a new object, and then we want to somehow get the newly-created primary key for that object.
Here is an example of a stored procedure that correctly inserts an object (note that if obj_id is given as "None" in python, then the object is assigned a new primary key by a trigger):
CREATE OR REPLACE PROCEDURE insert_an_obj (an_obj_id NUMBER) AS
new_primary_key NUMBER;
BEGIN
INSERT INTO OBJS (OBJ_ID) VALUES (an_obj_id) RETURNING OBJ_ID INTO new_primary_key;
-- A SELECT statement should go here in order to get the new value for new_primary_key.
END insert_an_obj;
Supposedly, a SELECT statement at the end of the stored procedure will make it so the next time my script calls cursor.fetchall(), the script would get a list of whatever was selected. However, I have been unable to get this to work. Some failed SELECT examples (one of which might go in the stored procedure above in place of the SELECT comment) include the following:
-- These fail to compile because SQL Developer doesn't like them (though various sources online said that they work on SQLServer):
SELECT * FROM OBJS WHERE OBJ_ID=new_primary_key;
SELECT OBJ_ID FROM OBJS WHERE OBJ_ID=new_primary_key;
Like I said, I'm new to SQL, and likely I just need to know the proper syntax to get the SELECT statement working nicely in Oracle. Any suggestions? Or is there something that I'm misunderstanding?
As mentioned by Justin Cave in the comment above, "you can't just put a SELECT in a stored procedure to return data to the client." At least not with Oracle 11g. He continues: "In 11g, the only way to regurn data from a stored procedure is to have an OUT parameter", which AFIK, not possible using version 3.0.7 of pyodbc.

SQL Server 2005 How to ignore errors during Create Procedure

I need to create a Stored Procedure in SQL Server 2005. Somewhere in the procedure, I have to join to a table which does not exist in the test environment but in the live environment (in a database in a linked server). I will not run the procedure in the test environment, but I need it to exist in order to create the ORM code in the application.
Naturally, SQL Server raises the error "Could not find server 'xxx' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedur sp_addlinkedserver to add the server to sys.servers.". However, I know that I can't add this server to the test environment, as it is not accessible from outside.
So, my question is, how can I create my stored procedure by ignoring the errors? Is there a way for it?
This is an old thread, but if other people are having the same problem, here's another solution:
You can have your server via text and the procedure will pass.
create proc test
as
declare #myserver varchar(50) = '[myserver\myinst]'
exec('select * from '+#myserver+'.dbo.table')
This way, the proc will compile on any environment, but will only run successfully on production
If you are certain that everything is correct and the procedure will work fine in live environment then create a fake linked server using sp_addlinkedserver.
What I mean is, if procedure body contains a linked server named test_linked and if it's not found then it will throw error.
Use sp_addlinkedserver and create a fake linked server named test_linked pointing to your test environment or even live environment. that will solve the issue cause it will try to check whether a linked server named test_linked does exist in sys.servers or not but unless you are running the procedure the actual linked server will not be accessed (AFAIK).
As Aaron Bertrand have mentioned in comment, Going by synonym would be a much cleaner approach though.

microsoft SQL server 2005

While running a procedure it gives error like Insert Error: Column name or number of supplied values does not match table definition. But when I run same set of queries without any procedure it run fine. Can someone tell me what 's the problem
I'm going to guess that your stored procedure is asking for a certain set of parameters, but you are supplying a different set of arguments. When you call the stored procedure, make sure any arguments given are correct for what is expected.
Either that or the stored procedure itself has an error trying to talk to a database table and getting the schema wrong.