SQL Server 2008: DROP PROCEDURE error - sql

I try to execute this command:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.njams_test_sql_2.[PROC_CHECK_TRACE_SETTINGS]') AND type in (N'P', N'PC'))
DROP PROCEDURE dbo.njams_test_sql_2.[PROC_CHECK_TRACE_SETTINGS]
GO
But I'm getting this error:
Msg 166, Level 15, State 1, Line 1
'DROP PROCEDURE' does not allow specifying the database name as a prefix to the object name
What I'm trying to do is to delete all objects in a database, so that the database is empty. I'm using Microsoft SQL Server 2014 Management Studio.

As the error clearly says - you cannot use the database name as a prefix in a DROP PROCEDURE.
You need to make sure you're connected to the correct database and then you need to execute
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.njams_test_sql_2.[PROC_CHECK_TRACE_SETTINGS]') AND type in (N'P', N'PC'))
DROP PROCEDURE [PROC_CHECK_TRACE_SETTINGS]
GO

You need to change the order of database name and schema.
This is wrong:
DROP PROCEDURE dbo.njams_test_sql_2.[PROC_CHECK_TRACE_SETTINGS]
This is correct:
DROP PROCEDURE njams_test_sql_2.dbo.[PROC_CHECK_TRACE_SETTINGS]
Or, you can just leave them away. Then the current database and the default schema (most likely dbo) are used:
DROP PROCEDURE [PROC_CHECK_TRACE_SETTINGS]

Related

How - create and use database directly after creation in SQL Server?

I created a sql script to check if a database already exist, if it already exists it deletes and re-creates.
After I would like to connect it directly after its creation for creating tables ..
Here is my code but it does not work.
He announces an error message
Msg 911, Level 16, State 1, Line 10
Database 'Arms2' does not exist. Make sure that the name is entered correctly.
My script
IF EXISTS (select * from sys.databases where name = 'Arms2')
BEGIN
DROP DATABASE Arms2
PRINT 'DROP DATABASE Arms2'
END
CREATE DATABASE Arms2;
PRINT 'CREATE DATABASE Arms2'
USE Arms2
CREATE TABLE .....
Put a GO statement after the CREATE...
...
CREATE DATABASE Arms2;
PRINT 'CREATE DATABASE Arms2'
GO
USE Arms2

Using synonyms in stored procedures

I have a synonym for a table in another DB defined
using
create synonym TableA for otherDb.dbo.TableA
I have a locally defined stored procedure
CREATE PROCEDURE dbo.spGetTableA
AS
BEGIN
SELECT * FROM TableA
END
Now when I call the SP
EXEC spGetTableA
I get the following error
Invalid object name 'TableA'
While calling the SQL directly SELECT * FROM TableA
works perfectly.
Any idea what I'm missing for this to work?
You are probably calling the stored procedure from a user whose default schema is not dbo. Therefore you should always reference the schema both when you create the synonym and when you reference the table in a query.
DROP SYNONYM TableA;
GO
CREATE SYNONYM dbo.TableA FOR OtherDB.dbo.TableA;
GO
ALTER PROCEDURE dbo.spGetTableA
AS
BEGIN
SELECT * FROM dbo.TableA;
END
GO
EXEC dbo.spGetTableA;
I wish I could bold all of those dbo. references within the code. They are important and should ALWAYS be there.
Please read:
Bad habits to kick : avoiding the schema prefix

Stored procedure and where type in P, U, PC

I'm beginner in SQL. I can't find what is this line:
type in (N'P', N'PC')
What is in where clause: P, PC, U?
EDIT:
The full query is:
IF EXISTS (SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].SP_AUTHENTIFICATION]')
AND type in (N'P', N'PC'))
First off what Relational Database Management System?
However, I suspect that type is a column in a table or a variable in your stored procedure.
N, implies that you're converting the next string to a nchar, nvarchar or nvarchar2 (depending on RDBMS). These are data-types that allow multi-byte characters.
'PC' and 'P' are strings.
Putting this all together you're converting 'PC' and 'P' to a multi-byte character set and checking whether the column or variable type is the same as one of these strings.
in means that type can be the same as either 'PC' or 'P'.
From your comment you're using SQL-Server
You're checking whether the object [dbo].[SP_AUTHENTIFICATION] exists and is a stored procedure (P) or a assembly stored procedure (PC).
The column type in sys.objects is not an nchar so the conversion is fairly pointless.
Going point by point
IF EXISTS - If the result of the following query in brackets returns a row:
SELECT * FROM sys.objects - Select a row from sys.objects
WHERE object_id = - Where the object_id is equal to the following
OBJECT_ID(N'[dbo].[SP_AUTHENTIFICATION]') - Return the object_id of [dbo].[SP_AUTHENTIFICATION]
AND type in (N'P', N'PC') - and where that object is a stored procedure.
U, which isn't in your query is checking to see whether the type is a table. The documentation gives you a full list.
If you want your question to be useful for other people, the detail from the comment belongs to the body of the question, as these identifiers are only meaningful in the context of the sysobjects table.
Here are the meanings.
U - user table
P - traditional stored procedure (SQL)
PC - CLR stored procedure (usually C# or VB.NET)
Your clause therefore checks whether any procedure called sp_authetication exists.
The 'line' is looking for a stored procedure named SP_AUTHENTIFICATION and likely dropping it if it exists. This is quite common in SQL Server because SQL Server does not have CreateOrAlter.
I found a better way to perform a CreateOrAlter so that history is maintained on the stored procedure.
if not exists(SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[myproc]') AND type in (N'P', N'PC'))
exec('create proc dbo.myproc as select 0')
alter proc dbo.myproc
as
...

How do I solve these two errors when creating a trigger?

I'm creating a simple trigger that will email me when a table is updated or inserted into:
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'sportsNewsUpd' AND type = 'TR')
DROP TRIGGER sportsNewsUpd
GO
CREATE TRIGGER sportsNewsUpd
ON sportsNews
FOR Insert, UPDATE
AS
EXEC master.webdb.xp_sendmail
#recipients = 'name#email.com',
#subject = 'Sports News has been altered.'
GO
I am getting two errors:
Incorrect syntax near 'GO', 'CREATE TRIGGER' must be the first tatement in query batch., Incorrect syntax near 'GO'. (two 'GO', two errors).
My resources:
http://msdn.microsoft.com/en-us/library/aa258254(v=sql.80).aspx (B. under examples)
http://msdn.microsoft.com/en-us/library/ms189505.aspx
semicolon after DROP TRIGGER sportsNewsUpd?
so...
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'sportsNewsUpd' AND type = 'TR')
DROP TRIGGER sportsNewsUpd;
GO
try:
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'sportsNewsUpd' AND type = 'TR')
begin
DROP TRIGGER sportsNewsUpd
end
GO
CREATE TRIGGER sportsNewsUpd ON sportsNews FOR Insert, UPDATE AS
begin
EXEC master.webdb.xp_sendmail
#recipients = 'name#email.com',
#subject = 'Sports News has been altered.'
end
GO
How do you run the query(ies)?
I doubt very much that you would get these errors running the script from an SSMS query window. Also, you wouldn't get the errors if you were running it using sqlcmd or osql.
What I mean is I'm suspecting you are trying to run the script from the application and so you may have probably been unaware that GO is not a part of T-SQL.
Solution in this case would be to split the script in two and run each part in turn.

SQL Server stored procedure meaning

I'm developing a simple database architecture in VisualParadigm and lately ran over next code excerpt.
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'getType') AND type in (N'P', N'PC'))
DROP PROCEDURE getType;
Next goes my stored procedure:
CREATE PROCEDURE getType #typeId int
AS
SELECT * FROM type t WHERE t.type_id = #typeId;
Can anyone explain what does it mean/do (the former one)?
P.S.: It would be great, if you may also check for any syntax errors as I'm totally new to SQL Server and stored procedures.
The IF EXISTS part first checks if a stored procedure with the same name exists. if it does it drops it before creating it. Without this check you'd get an error that the stored procedure already exists.
Adding to Raj's post, there is no means to do an "upsert" with stored procedures. The Create Procedure statement must be the first statement of the batch. Thus, the following would not work:
If Not Exists(Select 1 From sys.procedures Where Name = 'getType')
Create Procedure...
Else
Alter Procedure...
The only means to "update" a procedure and not have it throw an error if it already exists is to drop it and re-create it.
ADDITION
To address a specific question you made in comments, sys.objects is a catalog view which contains a list of all objects (tables, constraints, columns, indexes etc. Every "thing" in the database) of which procedures are one of them. Thus, this is checking whether the procedure object (based on filters on type) exist. The primary key of the sys.objects table/view is object_id which is an integer. In your example, they are using the OBJECT_ID function to find the id of the object getType and determine if it is a procedure. (It probably would have been safe to just use If OBJECT_ID(N'getType') is not null but just in case there is another object with that name that isn't a procedure, they added the check on the object type).
a CREATE PROCEDURE getType... will fail if the object already exists. by including the IF EXISTS... code which will drop the object if it exists first, you eliminate the error and the CREATE... will run.
The OBJECT_ID(N'getType') just returns the numeric ID of an object named N'getType' and the AND type in (N'P', N'PC')) makes sure that the object is a P=stored procedure or a PC=Assembly (CLR).
You could try using something like this, so you can use ALTER to keep permissions (DROP+CREATE removes any):
BEGIN TRY EXEC ('CREATE PROCEDURE YourProcedureName AS SELECT ''ERROR'' RETURN 999') END TRY BEGIN CATCH END CATCH
GO
ALTER PROCEDURE YourProcedureName
AS
SELECT 'WORKS!2'
GO
EXEC YourProcedureName
OUTPUT:
-------
WORKS!2
(1 row(s) affected)
It looks like this is part of a script to generate your DB. The first statement looks to see if your sproc called "getType" exists. If it does then it will drop it. Why? Because the next line is going to create it.
The only other way it could create it and make sure it matches the current version of your procedure is to change create to alter. That would make for longer code because it would have to list the sproc twice. Or it could generate dynamic sql which is not nearly as clean.
It's doing a drop and recreate
if a database object called getType exists:
WHERE object_id = OBJECT_ID(N'getType')
and it's a stored procedure:
AND type in (N'P', N'PC'))
then drop it before adding your stored procedure:
DROP PROCEDURE getType;
The first query drops procedure if it exists. The second creates a new procedure that takes integer parameter and returns resultset.