This seems like it would be trivial, but I have not been able to come up with a solution to this small problem.
I am attempting to create a stored procedure in my application's database. This stored procedure just executes a job that has been set up in the SSMS on the same server (seemed to be the only way to programmatically execute these jobs).
The simple code is shown below:
USE ApplicationsDatabase
GO
CREATE PROCEDURE [dbo].[procedure]
AS
BEGIN
EXEC dbo.sp_start_job N'Nightly Download'
END
When ran as is, the procedure technically gets created but cannot be executed due to it not being able to find the 'sp_start_job' since it is using the ApplicationsDatabase. If I try to create the procedure again (after deleting previously created) but updating the USE to MSDB, it tries to add it to that system database for which I do not have permissions to do. Finally, I attempted to keep the original create statement but added the USE MSDB within the procedure (just to use the 'sp_start_job' procedure), but it would error saying USE statements cannot be placed within procedures.
After pondering on the issue for a little (I'm obviously no SQL database expert), I could not come up with a solution and decided to solicit the advice of my peers. Any help would be greatly appreciated, thanks!
You will have to fully qualify the path to the procedure. Of course, you can only execute this is the application has permissions.
Try this:
USE ApplicationsDatabase
GO
CREATE PROCEDURE [dbo].[procedure]
AS
BEGIN
EXEC msdb.dbo.sp_start_job N'Nightly Download'
END
Related
I'm working on modifying some code around and I noticed that when I go to execute a stored procedure, lets call it 'yyyyyyyyy_sproc' I get an error saying that 'xxxxxxxxxxx_sproc' doesn't exist (saying that there are two different names).
I went into the code of sproc 'yyyyyyyyyy_sproc' and didn't see anywhere where 'xxxxxxxxx_sproc' was being used. My question is, is there a process in SSMS that automatically links two sprocs together? As using EXEC 'yyyyyyyyy_sproc' would therefor trigger an error if there was an issue with 'xxxxxxxxxxxxx_sproc'?
Is there a way to update another database with the newly created stored procedure whenever a stored procedure is created in the main database?
For example, i have two databases, DB1 and DB2.
When I create a stored procedure in DB1, i want that same procedure to created in DB2 automatically? Is there a trigger that can do this?
USE [DB1]
CREATE PROCEDURE [dbo].[TestSproc]
..something
AS
BEGIN
...something
END
I know a use [DB2] statement will do the job, but i want this to be done automatically. Any thought?
Thanks for the help!
This might be a bit evil, but in SQL Server you are able to create DDL triggers which fire when you create/alter/drop tables/procedures etc. The syntax to fire when a procedure is created is:
CREATE TRIGGER <proc-name>
ON DATABASE
FOR CREATE_PROCEDURE
AS
--Your code goes here
In a DDL trigger you get access to an object called EVENTDATA. So to get the text of the procedure you created:
SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
Now all you need to do is keep that value and execute it in your secondary database. So your query becomes something like this, though I leave the code to update the secondary database down to you as I don't know if it's on the same server, linked server etc.:
CREATE TRIGGER sproc_copy
ON DATABASE
FOR CREATE_PROCEDURE
AS
DECLARE #procedureDDL AS NVARCHAR(MAX) = EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
--Do something with #procedureDDL
As this is not tested, there's probably a few gotchas. For example, what happens if you create procedure with full name (CREATE PROC server.database.schema.proc)
No simple solution for this unless you want to execute the same statement twice, once on each target database,
One thing that comes to my mind is that you can Set up Replication and only publish Stored Procedures to your second database which will be the subscriber in this case.
Following is the window where you select which Objects you want to send over to your secondary databases.
I have created a stored procedure and can see it under the stored procedure node, but when trying to execute it doesn't find the procedure.
Under stored procedure node it is called dbo.CopyTable
exec CopyTable
CopyTable is undefined in red saying it does not exist. Why?
Even if I right-click on the procedure and say script stored procedure as execute to - the code it generates is underlined in red and cant find stored procedure either.
Ensure that the database selected contains the stored procedure CopyTable
USE YourDatabase
EXEC CopyTable
Try adding dbo and selecting the right database,
USE databaseName
GO
EXEC dbo.CopyTable
GO
Execute a Stored Procedure
Most likely you are just in the wrong database in the query window, you can specify the database like this:
EXEC [yourDBName].dbo.CopyTable
Reading on how to Execute a Stored Procedure
Considering your updated question:
Even if i rightclick on the procedure and say script stored procedure
as execute to - the code it generates is underlined in red and cant
find stored procedure either.
This could happen if your stored procedure is invalid. Please double-check the validity of the SPROC and ensure the tables it references exist, etc.
Try running your CREATE PROCEDURE. Highlight it, f5 it, and then make sure it runs before you call it elsewhere.
Maybe in your procedure you've accidentally cut-pasted your script name (dbo.CopyTable), say something like...
SELECT * FROM dbo.CopyTable
WHERE ClientId = #ClientId
RETURN
Then when you call your proc you get 'invalid object name dbo.CopyTable' and assume sql is having trouble finding the stored-proc ... which isn't the problem, its finding and running the proc but its actually a problem within the proc.
I'm running a stored procedure on server1 from my application. The stored procedure does a bunch of stuff and populate a table on server2 with the result from the procedure.
I'm using linked server to accomplish this.
When the stored procedure is done running the application continues and tries to do some manipulation of the result from the stored procedure.
My problem is that the results from the stored procedure has not been completely inserted into the tables yet, so the manipulation of the tables fails.
So my question is. Is it possible to ensure the insert into on the linked server is done synchronous? I would like to have the stored procedure not return until the tables on the linked server actually is done.
You can use an output parameter of the first procedure. When the table is create on the second server the output parameter value will be return to your application and indicates the operation is ready.
If the things are difficult then this you can try setting a different isolation level of your store procedure:
http://msdn.microsoft.com/en-us/library/ms173763.aspx
I found the reason for this strange behavior. There was a line of code in my stored procedure added during debug that did a select on a temporary mem table before the data in the same table was written to the linked server.
When the select statement was run, the control was given back to my application and at the same time the stored procedure continued running. I guess the stored procedure was running synchronously from the start.
When I created my stored procedure somehow I managed to place it within the stored procedures folder, however not inside the system stored procedures folder (the system SP folder exists within the stored procedures folder). How do I move it one level down into the system stored procedures folder?
EDIT: After reading the answers below I'm thinking that the problem is how I'm telling my C# program to access the stored procedure. I have this line of code that is throwing an exception, telling me that it cannot find it:
SqlCommand cmd = new SqlCommand("<database_name>.dbo.<stored_procedure_name>.sql", conn);
If anyone can offer any help on how to call the stored procedure properly it would be appreciated. Thx!
You don't, or at the least shouldn't.
This is for system stored procedures, which are built into the RDBMS and used for system functions, like renaming objects or checking users on the server.
Don't think of these as folders like in a file system - they are just organizing your objects based on existing meta-data (Stored procedure or View? System object or User object?)
You can conceivably mark it as a system object, but that's just a terrible idea.
Why do you want to obfuscate your procedure? If you are creating it it's obviously a user procedure and not a system one.
I'm really not sure why you would need to do this, but you can:
exec sp_ms_marksystemobject myprocname
It's undocumented - so I you won't have any support if you try and use it, and it might be removed from a future version of SQL Server.
+1 for #JNK's comment above.
Also, ensure that you've created the stored procedure under the schema you think you did. If you execute a statement like this:
create procedure foobar as ...
the stored procedure foobar gets created under your default schema, which is likely not dbo. You should always create and reference database objects with at least a 2-level, schema-qualified name:
create procedure dbo.foobar ...
create procedure some_schema.foobar ...
lest you shoot yourself in the foot. You should schema-qualify references as well. References like
select * from some_table
exec some_stored_procedure
rather than
select * from dbo.some_table
exec dbo.some_stored_procedure
are resolved by first probing for an object of the desired name and type under your default schema. If found, that is the object used to resolve the reference. If no such object is found, then a probe is made under the schema dbo.
Further, you should not generally give a stored procedure a name that begins with sp_: that further complicates (and slows down) resolution, throwing probes of the master database into the mix.