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.
Related
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.
We have environments for Dev, Uat, and Live. We have a different version of the same stored procedure for each environment. For each environment, a stored procedure is run from a database catalog of the same name "CMS". In each case, the sql that is called differs only on the server name. For example, the code on UAT looks like this (simplified):
INSERT INTO UAT.ABC.[dbo].NOTE (ID, [TEXT])
VALUES (2, 'Just a note')
The code on Live looks like this (simplified):
INSERT INTO Live.ABC.[dbo].NOTE (ID, [TEXT])
VALUES (2, 'Just a note')
We would like to just write the stored procedure once and be able to deploy that same stored procedure so that it points to the right server when, say, performing the insert statement in our example. We wish to avoid using dynamic sql. Is there a way to pass down a parameter into the stored procedure to tell it which server to use? Can this be achieved using sqlcmd with scripting variables, if so then how? Is there an easy way of doing this without dynamic sql or scripting variables?
EDIT
Six separate instances of SQL Server 2014 - 3 for each environment for the calling code and 3 for each environment for the code being called.
I'm assuming there are 3 copies of the DB with "identical" code, or rather to code should be identical. Remove the hardcoded DB reference, and the stored procedure will run in the context of the DB in which it lives.
You are making life hard for yourself by hardcoding the db reference.
And you answer your own question. If you ahve to do this, then you must use dynamic SQL.
Keep the Linked Server name the same in all instances, and just change the definition of where the linked server points to go to the correct instance.
So use something like:
INSERT INTO MyAppLinkedServer.ABC.[dbo].NOTE (ID, [TEXT])
VALUES (2, 'Just a note')
In UAT, MyAppLinkedServer will point to UAT SQL server.
In Dev, MyAppLinkedServer will point to DEV SQL server.
Here is an example of how to setup the linked server:
EXEC master.dbo.sp_addlinkedserver #server = N'MyAppLinkedServer', #srvproduct=N'MyAppLinkedServer', #provider=N'SQLNCLI', #datasrc=N'ActualServerNameGoesHere', #catalog=N'ABC'
The short answer was not to use any linked servers but to create any entry the host file for each environment, where the entry would have a different IP mapping for each environment.
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.
I have a stored procedure that I'm positive of has no errors but I recently deleted the table it references but imported a backup with the same name exactly and same column settings (including identity) that the previous one had but now it doesn't work.
Is there any reason that having deleted the table but importing a new would break the stored procedure?
BTW: Running Microsoft SQL Server Express Edition w/ IIS.
you can try to recompile the stored procedure with:
exec sp_recompile YourProblemTableNameHere
this will recompile all procedures that use the YourProblemTableNameHere table. But that is just a guess based on the very limited info given.
I have 2 SQL Servers:
temp1 XX.13.23.2
temp2 XX.23.45.6
The temp1 server has a database called db1 and contains a procedure called p1.
I want that procedure to insert the value on Temp2 server Database name db2 on table T1.
Is it possible to use procedure to insert value on another server's database?
If this is this possible then can someone provide me with an idea or some examples on how to achieve this?
Yes, please look into linked servers:
http://msdn.microsoft.com/en-us/library/ms188279%28SQL.90%29.aspx
You can call a remote stored procedure from the instance you want to insert to:
exec [RemoteServer].DatabaseName.DatabaseOwner.StoredProcedureName
You need to have the RemoteServer set up as a linked server.
Another option, especially if you're going to have a development version of the procedure where you're going to want to do tests and you don't want touching a production environment, would be to use SQL Server synonyms: http://technet.microsoft.com/en-us/library/ms177544.aspx.
I personally like using them because once the proc is initially setup to use them, you won't have to change the SQL in the procedure.