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
Related
I have two tables called timeus and usdpay in my SQL Server database. These two tables get updated every week.
I did small transformation and combined these two tables and created a new table called fluslabor.
I created fluslabor using the stored procedure shown here, and it is working:
CREATE PROCEDURE [dbo].[sp_uslabor]
AS
BEGIN
SET NOCOUNT ON
IF OBJECT_ID(N'dbo.fluslabor', N'U') IS NOT NULL
TRUNCATE TABLE [dbo].[fluslabor];
SELECT ut.employee_code
,ut.employee_name
,ut.department_desc
,ut.location_desc
,ut.hour
,ut.projects_code
,ut.in_effective_time
,ut.out_effective_time
,ut.date
,ut.id
,p.rate
,(p.rate * ut.hour ) as Labour_Cost
INTO fluslabor
FROM timeus ut
LEFT JOIN usdpay p ON (TRIM(ut.id) = TRIM(p.id) AND ut.date = p.date)
WHERE ut.projects_code NOT LIKE '0%'
END
Today I got new data updated in my two tables timeus and usdpay.
When I execute my stored procedure, SQL Server is throwing this error:
Msg 2714, Level 16, State 6, Procedure SP_uslabor, Line 12 [Batch Start Line 38]
There is already an object named 'fluslabor' in the database.
I need to truncate my table every time and load the new data. I checked the similar post, they said to use drop table option. I don't want to drop the table, just want to truncate and execute the procedure
Can anyone advise what is the issue here please?
The problem here is that the table fluslabor already exists in the database. what you are trying above the insert is checking the object existence and then truncating the same
There are two possible approaches that you can try here.
Instead if the TRUNCATE do a DROP TABLE. But This will also remove the existing user permissions on the table if you have provided specific custom access to the table to any of the users
IF OBJECT_ID(N'dbo.fluslabor', N'U') IS NOT NULL DROP TABLE [dbo].[fluslabor];
The safest approach will be change the SELECT .. INTO statement and convert it into INSERT INTO like this
INSERT INTO fluslabor ( <List your Destination columns> ) SELECT <List your Source columns> FROM <Source Query>
the 2nd approach will have the records loaded along with keeping all the existing permissions
IF EXISTS (SELECT 1 FROM sys.objects WHERE type = 'P' AND name = 'your SP name')
BEGIN
DROP PROCEDURE "your SP name";
END
GO
CREATE PROCEDURE "your SP name"
AS
BEGIN
.
.
.
.
try this one I guess this will help you.
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 have 10 stored procedures they are different with their definition in sys_modules. I find them with this query:
select
b.definition, a.name
from
sysObjects a
left outer join
sys.sys_modules b on b.id = a.object_id
where
b.definition not like '%' + b.name + '%'
Could someone tell me why this happens?
It's the second time I faced this problem.
This happens if you use sp_rename and is explicitly called out in the documentation
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.
Note that the rename functionality in SSMS object explorer does in fact call this procedure.
Use INFORMATION_SCHEMA.ROUTINES and get the ROUTINE_DEFINITION column for stored procedures
While selecting the sp name by using Rename, i wrongly press 's' and press tab. Then it is renamed wrongly. I don't know the Sp Name. How do i get the old sp name. Kindly suggest me.
From MSDN I found in sp_rename (Transact-SQL)
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.
I have tested the same and I got old object name.
GO
CREATE PROCEDURE PROC_MY_SP
AS
BEGIN
SELECT 1 AS COL
END
GO
SELECT OBJECT_ID('PROC_MY_SP') --789786071
GO
SELECT * FROM sys.sql_modules WHERE OBJECT_ID('PROC_MY_SP')= OBJECT_ID
GO
sp_rename 'PROC_MY_SP', 'PROC_YOUR_SP'
GO
SELECT OBJECT_ID('PROC_YOUR_SP') --789786071
--Changing the SP Name wont change the objectID
GO
SELECT definition,* FROM sys.sql_modules WHERE OBJECT_ID=789786071
--Or Simply pass your new sp name
SELECT definition, * FROM sys.sql_modules WHERE OBJECT_ID('PROC_YOUR_SP')= OBJECT_ID
Here the definition column showing the old sp name only.
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.