I am curious whether I can drop multiple procedures by simple using "%"?
Like:
DROP constantName%
When I use DROP in the Management studio, it looks like that:
/****** Object: StoredProcedure [dbo].[x] Script Date: 02/02/2010 09:36:25 ******/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[x]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[x]
Why it is checking the object ID when I am dropping this particular object?
The OBJECT_ID returns the database object identification number of a schema-scoped object. In your code it is checking it inside an IF EXISTS, so that it will only DROP the stored proc if is present in the database.
You could just have DROP PROCEDURE proc_name, but you could end up getting an error if the procedure does not exist. Its just good practise to check before you remove.
Tables, View, Stored Procs etc all have an OBJECT_ID as a key identifier.
I do not believe you can drop mutiple stored procedures using a LIKE. (Though i;m not 100% certain on that)
I think SQL was designed with this limitation, the drop procedure command needs a string constant. You can't pass a variable as an argument either, it just gives a 'incorrect syntax' error when you do.
Also the OBJECT_ID function only returns a valid id of objects the user owns, or has permission to. So OBJECT_ID is used because it performs the security validation.
Deleting with just "WHERE name = 'object_name'" could also work, but only if the user has permission for that object.
I am afraid you cant use the like syntax in DROP, below the simple one liner to drop multiple procedures.
DROP PROCEDURE testest,testest1
And for your 2nd question. There are scenarious we can create Storedprocedure that can be accessible only to the particular role.
create proc dbo.testest
as
begin
select 1
end
query sys.objects with the role value
select * from sys.objects where name ='dbo.testest'
it returns null
select * from sys.objects where name ='testest'
now it works
sys.objects catalog view stores the information without the role names (only just names). But using OBJECT_ID, we can retrieve the role specific info
select OBJECT_ID('dbo.testest') //works
select OBJECT_ID('testest') //works
hope you can understand now.
Related
Some time ago the procedure ALF_GetPopulationForPolygon_2_old was created. Then in SSMS, it was renamed (right mouse button -> rename) to the procedure ALF_GetPopulationForPolygon_2_old_FOR_DELETE_20170504. Renaming passed normally, but as a result, the query:
SELECT
sm.definition
FROM
sys.objects AS o
INNER JOIN sys.sql_modules AS sm
ON ( 1 = 1 )
AND ( sm.object_id = o.object_id )
WHERE
( 1 = 1 )
AND ( o.name like 'ALF_GetPopulationForPolygon_2_old_FOR_DELETE_20170504' )
And calling the stored procedure:
EXEC sp_helpText 'ALF_GetPopulationForPolygon_2_old_FOR_DELETE_20170504'
Return the following text:
...
CREATE PROCEDURE [dbo]. [ALF_GetPopulationForPolygon_2]
...
Those show the OLD(!) name of the procedure. Do you have any idea what this is caused, and how can this be fixed?
You shouldn't rename your objects for at least two reasons.
If you'd use a T_SQL command instead of GUI (all that you "clicks" in Management Studio produces T-SQL coede behind the scenes), you'd get a warning, the same you can see in BOL article:
sp_rename (Transact-SQL)
CAUTION Changing any part of an object name can break scripts and stored
procedures. We recommend you do not use this statement to rename
stored procedures, triggers, user-defined functions, or views;
instead, drop the object and re-create it with the new name.
And it was the first reason against renaming.
Scrolling the article find the Remarks section:
Renaming a stored procedure, function, view, or trigger will
not change the name of the corresponding object name in the definition
column of the sys.sql_modules catalog view. Therefore, we recommend
that sp_rename not be used to rename these object types. Instead, drop
and re-create the object with its new name.
And this was the second.
So when you want to rename your procedure you should script your procedure as CREATE and change the procedure name, doing so you recreate your proc with the new name and then you can drop the old one
I am stuck with the following stored procedure where I can't seem to get the IF EXISTS and DROP parts to work, leading to a failure in the SELECT INTO part.
Both database A and database B are on the same server, I have full permissions in both databases. The stored procedure is in database A.
I have copied the IF EXISTS syntax from somewhere (can't remember where) so I don't really understand the structure of it. I gathered the problem lies in the IF EXISTS statement because when I try and execute IF EXISTS component of the stored procedure, I get something if I have selected DatabaseB in the top left-hand corner drop-down box in Management Studio but if I have DatabaseA selected in there, I get nothing.
I have also tried to run similarly structured stored procedures in DatabaseA (where there is an IF EXISTS and DROP statements pointing to DatabaseB followed by a SELECT INTO from DatabaseA into DatabaseB) and I have got some to work before, while some others failed. I cant seem to pinpoint what is causing it to work sometimes and sometimes not.
USE [DatabaseA]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--DROP TABLE A if exists--
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'DatabaseB.dbo.TableA') AND type IN (N'U'))
DROP TABLE DatabaseB.dbo.TableA
--Select INTO TableA on DatabaseB--
SELECT *
INTO DatabaseB.dbo.TableA
FROM DatabaseA.dbo.TableA
I usually use if object_id('databaseB.dbo.TableA') is not null instead of the exists check to avoid having to fully qualify sys.objrcts.
Some time ago the procedure ALF_GetPopulationForPolygon_2_old was created. Then in SSMS, it was renamed (right mouse button -> rename) to the procedure ALF_GetPopulationForPolygon_2_old_FOR_DELETE_20170504. Renaming passed normally, but as a result, the query:
SELECT
sm.definition
FROM
sys.objects AS o
INNER JOIN sys.sql_modules AS sm
ON ( 1 = 1 )
AND ( sm.object_id = o.object_id )
WHERE
( 1 = 1 )
AND ( o.name like 'ALF_GetPopulationForPolygon_2_old_FOR_DELETE_20170504' )
And calling the stored procedure:
EXEC sp_helpText 'ALF_GetPopulationForPolygon_2_old_FOR_DELETE_20170504'
Return the following text:
...
CREATE PROCEDURE [dbo]. [ALF_GetPopulationForPolygon_2]
...
Those show the OLD(!) name of the procedure. Do you have any idea what this is caused, and how can this be fixed?
You shouldn't rename your objects for at least two reasons.
If you'd use a T_SQL command instead of GUI (all that you "clicks" in Management Studio produces T-SQL coede behind the scenes), you'd get a warning, the same you can see in BOL article:
sp_rename (Transact-SQL)
CAUTION Changing any part of an object name can break scripts and stored
procedures. We recommend you do not use this statement to rename
stored procedures, triggers, user-defined functions, or views;
instead, drop the object and re-create it with the new name.
And it was the first reason against renaming.
Scrolling the article find the Remarks section:
Renaming a stored procedure, function, view, or trigger will
not change the name of the corresponding object name in the definition
column of the sys.sql_modules catalog view. Therefore, we recommend
that sp_rename not be used to rename these object types. Instead, drop
and re-create the object with its new name.
And this was the second.
So when you want to rename your procedure you should script your procedure as CREATE and change the procedure name, doing so you recreate your proc with the new name and then you can drop the old one
I understand that you cannot simply drop an SQL server schema, you must first of all drop all the objects contained therein. I found this stored proc that performs the task of dropping all objects and then the schema itself.
Is there really no simpler way to drop a schema? Ideally, I'd like to find a way to do this without using a stored proc.
Also, it seems like the stored proc will cause errors if the schema name provided does not exist. I would like it to simply do nothing instead. I guess this is simply a matter of putting this pseudocode at the top of the script
IF #SchemaName NOT EXISTS
QUIT
Can someone convert this into language that SQL Server will understand?
The following at the top of the script should help:
IF SCHEMA_ID(#SchemaName) IS NULL
RETURN
SCHEMA_ID returns the schema ID associated with a schema name, and RETURN exits unconditionally from a query or procedure.
You have to remove all objects in the schame before dropping it or migrate all objects to a new schema. There is no "wildcard" option for either
To exit a stored procedure before any further processing...
IF SCHEMA_ID(#SchemaName) IS NULL
RETURN
if exists(select * from sys.schemas where name = #SchemaName)
begin
-- Your work
end
You must drop all objects before dropping the schema.
To check if a schema exists:
IF NOT EXISTS (select SCHEMA_NAME from INFORMATION_SCHEMA.SCHEMATA WHERE CATALOG_NAME='YOUR DB NAME HERE' and SCHEMA_NAME=#SchemaName)
BEGIN
-- Do some processing...
return
END
Is there a way when executing a stored procedure in Management Studio to get the data types of the result sets coming back? I'm looking for something like functionality of when you pass a table name to sp_help
You do get to look at the types though, if you call the stored procedure via ADO, ADO.NET, ODBC or the likes: The resulting recordsets have the type information you are looking for. Are you really restricted to Management Studio?
Your best bet would be to change the stored procedure to a function. But that only works if your environment allows it.
No easy way comes to mind without parsing syscomments to see what it's querying from where. If you can edit the SP to select XML, you can append XML_INFO to the query to get the schema back.
Actually, you can do it from within an SP:
EXEC ('if exists (select * from sys.tables where name = ''tmp_TableName'') drop table tmp_TableName')
EXEC ('select * into tmp_TableName from MyTable')
-- Grab the column types from INFORMATION_SCHEMA here
EXEC ('if exists (select * from sys.tables where name = ''tmp_TableName'') drop table tmp_TableName')
Although, I think there must be a better way.
It's not the most elegant solution, but you could use OPENROWSET to put the stored proc results into a table, then use sp_help to get a description of it.
eg
select * into tmp_Results
from openrowset( 'SQLOLEDB.1'
, 'Server=your_server_name;Trusted_Connection=yes;'
, 'exec your_stored_proc')
exec sp_help 'tmp_Results'
drop table tmp_Results
You could always use an actual table that is garrenteed to be unique. It's a kludge, but it's an option. This will not work inside a stored proc though.
if exists (select * from sys.tables where name = 'tmp_TableName')
drop table tmp_TableName
go
select * into tmp_TableName from MyTable
--do some stuff
go
if exists (select * from sys.tables where name = 'tmp_TableName')
drop table tmp_TableName
go