I am presently updating a procedure with multiple EXEC lines such as:
EXEC databasename.tablename.pr_sys_drop_Object 'zt_Staging_of_class'
yet nowhere have I found the definition of EXEC in this context.
If it's a full three part name where the middle part is not the name of a table but of a schema a kind of SQL namespace. So in that context pr_sys_drop_Object is a stored procedure in a separate schema.
If you look in the named database, in the named schema you'll probably find a stored procedure called pr_sys_drop_Object.
Execute is a sql server keyword see the docs here for more details. It is used to execute stored procedures or raw sql.
In your case it seems to be executing the procedure databasename.tablename.pr_sys_drop_Object and passing in 'zt_Staging_of_class' as a parameter to that procedure.
Related
I'm trying to execute Snowflake Stored Procedure in Matilion Using Sql Script component.
But i'm getting error as Unknown user defined function.
Can someone help me to call the procedure using Matilion Job.
Thank You !
That looks like a name resolution error. Snowflake does not recognize the name of the stored procedure. You will see the same generic error message when trying to call a procedure that really does not exist...
You most likely need to
qualify the procedure name with a database and a schema
put the names inside double-quotes if they are case sensitive.
In the Matillion stored procedure article there is an example CALL "${environment_database}"."${examples_schema}"."audit"('START', ${run_history_id}, NULL)
Background Information:
In Python, I might write something like this if I want to apply the same logic to different values in a list.
database_list = ["db_1", "db_2", "db_3"]
for x in range(0,len(database_list),1):
print("the database name is " + database_list[x])
What I am trying to do:
What I am trying to do in SSMS, is pull a list of DB objects for each database. I created a stored procedure to pull exactly what I want, but I have to run it against each database, so 10 databases mean running it 10 times.
My goal is to do this with a T-SQL query instead of Python.
I tried doing something like this:
exec sp_MSforeachdb 'USE ?; EXEC [dbo].[my_stored_procedure]';
The problem with this is, [dbo].[my_stored_procedure] has to exist in every database I want to do this in.
How can I create the stored procedure in 1 database, but execute it for all databases or a list of databases that I choose?
I know what you are trying to do and if it's what I think (you seem reluctant to actually say!) you can do the following:
In the master database, create your procedure. Normally you wouldn't do this, but in this case you must prefix it sp_
use master
go
create procedure sp_testproc as
select top 10 * from sys.tables
go
Now if you run this, it will return tables from the master database.
If you switch context to another database and exec master.dbo.sp_testproc, it will still return tables from the master database.
In master, run
sys.sp_MS_marksystemobject sp_testproc
Now switch context to a different database and exec master.dbo.sp_testproc
It will return tables from the database you are using.
Try creating your sproc in master and naming it with an sp_ prefix:
USE master
GO
CREATE PROCEDURE sp_sproc_name
AS
BEGIN
...
END
GO
-- You *may* need to mark it as a system object
EXEC sys.sp_MS_marksystemobject sp_sprocname
See: https://nickstips.wordpress.com/2010/10/18/sql-making-a-stored-procedure-available-to-all-databases/
It should then be available in all dbs
Create the stored procedure in the Master database with the sp_ prefix, and use dynamic SQL in the stored procedure so it resolves object names relative to the current database, rather than the database which contains the stored procedure.
EG
use master
go
CREATE OR ALTER PROCEDURE [dbo].[sp_getobjects]
AS
exec ('
select *
from [sys].[objects]
where is_ms_shipped = 0
order by type, name
')
go
use AdventureWorks2017
exec sp_getobjects
#LunchBox - it's your single stored procedure (that you create in one database) that is actually going to need to contain the "exec sp_MSforeach ...." command, and instead of the command to be executed being "EXEC ", it will need to be the actual SQL that you were going to put into the stored proc.
Eg. (inside your single stored procedure)
EXEC sp_MSforeachdb 'USE ?; SELECT * FROM <table>; UPDATE <another table> SET ...';
Think of the stored procedure (that you put into one database) as being no different than your Python code file - if you had actually wanted to achieve the same thing in Python, you would have either needed to create the stored proc in each database, or build the SQL statement string in Python and execute it against each database.
I understand what you thought you might be able to achieve with SQL, but stored procedures really don't work the way you were expecting. Even when you're in the context of a different database, but you run EXEC <different_db>.stored_proc, that stored proc ends up running in the context of the database in which it exists (not your context database).
Now, the only one issue you may come up against is that the standard sp_MSforeachdb stored proc has a limit of 2000 characters for the command that can be executed (although, it does have multiple "command" parameters, this may not be practical if you were planning on running a very large code block, perhaps with variables that carry all the way through). If this is something that might impact what you're intending to do, you could do a search online for "sp_MSforeachdb alternatives" - there seem to be a handful that people have created where the command parameter can contain a larger string.
I need to essentially wrap a common table expression around the output from a stored procedure, obviously the stored procedure cannot be called directly from within the CTE so I am trying to find a workaround.
I have tried using SELECT FROM OPENROWSET, which initially looked like it solved the problem - however some of the stored procedures I need to call contain sp_executesql commands so it generates an error -
The metadata could not be determined because statement 'EXEC sp_executesql #SQL' in procedure 'sp_CustomerAndWorkers' contains dynamic SQL. Consider using the WITH RESULT SETS clause to explicitly describe the result set."
I have also looked at OPENQUERY, but that doesn't allow parameters to be included.
Is there any other method I could consider? Would be be possible
Thanks in advance.
Have you considered Temporary tables?
Example:
INSERT INTO #tempTable
EXEC sp_executesql
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 hava a stored procedure named PROC_fetchTableInfo (simple select from sys.tables) in a database named
Cust
I would like use this procedure in a another database named
Dept
I tried to execute this sp in this database using command
EXECUTE Cust.dbo.PROC_fetchTableInfo
but as a result I get tables from the database Cust. How to get this procedure to work in database Dept?
A stored procedure is tighly bound to the objects in its code. If Cust.dbo.PROC_fetchTable references a table T, that is stricly the table T in schema dbo in database Cust. You can invoke the procedure from any other place, it will always refer to this table.
If you need to run the same procedure in another table on another database then the best solution, by far, is to have a new procedure: Dept.dbo.PROC_fetxTableInfo. This is better than the alternative of using Dynamic-SQL. While this seems counteruintuitive from a DRY and code reuse perspective, T-SQL is a data access language is not a programming language, leave your C/C# mind set at the door when you enter the database. Just have another procedure in the Dept database.
Your procedure, Cust.dbo.PROC_fetchTableInfo looks at data in the Cust database. Sounds like you need a copy of it in the Dept database.
Alternately (and quite unsatisfactory to me) you can add a parameter that controls which database to query by building the query in the sproc dynamically.
Perhaps you could create it in some "Common" database and call it like EXEC Common..PROC_fetchTableInfo #databaseName='Dept'
This is possible (if you are trying to write some utility function that you can use across all databases). You can create it in the master database, give it a sp_ prefix and mark it as a system object.
use master
go
CREATE PROCEDURE dbo.sp_sys_tables_select
AS
SELECT * FROM sys.tables
GO
EXEC sys.sp_MS_marksystemobject 'dbo.sp_sys_tables_select'
GO
EXEC tempdb.dbo.sp_sys_tables_select
EXEC msdb.dbo.sp_sys_tables_select