Syntax error in stored procedure - sql

I am trying to write one small stored procedure to clean up database programmatically.
For this,
First, I am dropping all Foreign key constraints
Second, I am dropping all primary key constraints,
Third, I am dropping all the tables.
I have written the following code to do above three steps (third step not yet started)
CREATE PROCEDURE usp_CleanupDB AS
BEGIN
--Begin: Code to drop FOREIGN KEY CONSTRAINTS in the database
DECLARE #ForeignKeyConstraint AS VARCHAR(100)
DECLARE #ForeignKeyContainedTableName AS VARCHAR(100)
DECLARE #ForeignKeyConstraintsTableCursor AS CURSOR
SET #ForeignKeyConstraintsTableCursor = CURSOR FOR
SELECT ForeignKeyName, TableName FROM dbo.GetDBForeignKeyConstraints()
OPEN #ForeignKeyConstraintsTableCursor
FETCH NEXT FROM #ForeignKeyConstraintsTableCursor INTO #ForeignKeyConstraint, #ForeignKeyContainedTableName
WHILE ##FETCH_STATUS = 0
BEGIN
--Drop FOREIGN KEY Constraint
ALTER TABLE #ForeignKeyContainedTableName DROP CONSTRAINT #ForeignKeyConstraint
FETCH NEXT FROM #ForeignKeyConstraintsTableCursor into #ForeignKeyConstraint, #ForeignKeyContainedTableName
END
CLOSE #ForeignKeyConstraintsTableCursor
DEALLOCATE #ForeignKeyConstraintsTableCursor
--End: Code to drop FOREIGN KEY CONSTRAINTS in the database
--Begin: Code to drop PRIMARY KEY CONSTRAINTS in the database
DECLARE #PrimaryKeyConstraint AS VARCHAR(100)
DECLARE #PrimaryKeyContainedTableName AS VARCHAR(100)
DECLARE #PrimaryKeyConstraintsTableCursor AS CURSOR
SET #PrimaryKeyConstraintsTableCursor = CURSOR FOR
SELECT PrimaryKeyName, TableName FROM dbo.GetDBPrimaryKeyConstraints()
OPEN #PrimaryKeyConstraintsTableCursor
FETCH NEXT FROM #PrimaryKeyConstraintsTableCursor INTO #PrimaryKeyConstraint, #PrimaryKeyContainedTableName
WHILE ##FETCH_STATUS = 0
BEGIN
--Drop PRIMARY KEY Constraint
ALTER TABLE #PrimaryKeyContainedTableName DROP CONSTRAINT #PrimaryKeyConstraint
FETCH NEXT FROM #PrimaryKeyConstraintsTableCursor INTO #PrimaryKeyConstraint, #PrimaryKeyContainedTableName
END
--End: Code to drop PRIMARY KEY CONSTRAINTS in the database
END
I am getting the following error:
Msg 102, Level 15, State 1, Procedure usp_CleanupDB, Line 15
Incorrect syntax near '#ForeignKeyContainedTableName'.
Msg 102, Level 15, State 1, Procedure usp_CleanupDB, Line 33
Incorrect syntax near '#PrimaryKeyContainedTableName'.
Can anybody please tell how to solve the problem?

You can't use variables for object names in DDL commands like ALTER TABLE.

Would you please use below way, also declare your variable at the top so that each variable is available to everywhere.
EXECUTE('ALTER TABLE ' + #PrimaryKeyContainedTableName + ' DROP CONSTRAINT '+ #PrimaryKeyConstraint)

Related

My INSERT statement conflicted with the FOREIGN KEY constraint

enter image description here
Those are my diagrams - I create procedure
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[hasta]
#Ad nchar(50),
#Soyadı nvarchar(100),
#TcKimlik nchar(11),
#DogumTarihi varchar(8),
#TelefonNo nvarchar(11)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].Hastalar ([Ad], [Soyadı], [TcKimlik], [DogumTarihi], [TelefonNo])
VALUES (#Ad, #Soyadı, #TcKimlik, #DogumTarihi, #TelefonNo)
END
After I want add data in Hastalar table, I write
exec hasta 'Emir','Yılmaz','35635993564','1995.11.19','05347331085'
but I get this error
Msg 547, Level 16, State 0, Procedure hasta, Line 13
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Hastalar_Testler". The conflict occurred in database "hastane", table "dbo.Testler", column 'TestID'. The statement has been terminated.
In your table [dbo].Hastalar, it has a foreign key reference to another table. The way a FK works is it cannot have a value in that column that is not also in the primary key column of the referenced table.
If you have SQL Server Management Studio, open it up and sp_help '[dbo].Hastalar'. See which column that FK is on, and which column of which table it references. You're inserting some bad data.
What part of the error do you not understand?
The message is saying that one of the columns -- "TestId" -- is referring to another table. And the value being inserted is not already in that table.
You are not explicitly inserting a value for TestId, so that value is being set using a default constraint or trigger. I would suggest that you explicit provide the value in the insert -- even if that value is NULL.

how to delete a primary key which is having auto increment [duplicate]

This question already has answers here:
Finding a Primary Key Constraint on the fly in SQL Server 2005
(4 answers)
Closed 5 years ago.
I need to drop the primary key of a table Student in a SQL Server database.
I have edited in the table and the script I got is
ALTER TABLE dbo.Student
DROP CONSTRAINT PK__Student__9CC368536561EF8B
But when I run this script in SQL Server query browser to drop the primary key
It shows the message
Msg 3728, Level 16, State 1, Line 1
'PK__Student__9CC368536561EF8B' is not a constraint.
Msg 3727, Level 16, State 0, Line 1
To my concern I think PK__Student__9CC368536561EF8B this will be generated randomly
please help me to drop the primary key constraint using script.
Thanks in advance
You can look up the constraint name in the sys.key_constraints table:
SELECT name
FROM sys.key_constraints
WHERE [type] = 'PK'
AND [parent_object_id] = Object_id('dbo.Student');
If you don't care about the name, but simply want to drop it, you can use a combination of this and dynamic sql:
DECLARE #table NVARCHAR(512), #sql NVARCHAR(MAX);
SELECT #table = N'dbo.Student';
SELECT #sql = 'ALTER TABLE ' + #table
+ ' DROP CONSTRAINT ' + name + ';'
FROM sys.key_constraints
WHERE [type] = 'PK'
AND [parent_object_id] = OBJECT_ID(#table);
EXEC sp_executeSQL #sql;
This code is from Aaron Bertrand (source).
simply click
'Database'>tables>your table name>keys>copy the constraints like 'PK__TableName__30242045'
and run the below query is :
Query:alter Table 'TableName' drop constraint PK__TableName__30242045
The answer I got is that variables and subqueries
will not work and we have to user dynamic SQL script. The following works:
DECLARE #SQL VARCHAR(4000)
SET #SQL = 'ALTER TABLE dbo.Student DROP CONSTRAINT |ConstraintName| '
SET #SQL = REPLACE(#SQL, '|ConstraintName|', ( SELECT name
FROM sysobjects
WHERE xtype = 'PK'
AND parent_obj = OBJECT_ID('Student')))
EXEC (#SQL)

What does this not like about my AddPartner procedure?

So I'm getting a slew of errors
(1 row(s) affected) Msg 2812, Level 16, State 62, Line 48 Could not
find stored procedure 'AddPartner'. Msg 2812, Level 16, State 62, Line
49 Could not find stored procedure 'AddPartner'. Msg 2812, Level 16,
State 62, Line 50 Could not find stored procedure 'AddPartner'.
(1 row(s) affected)
(1 row(s) affected) Msg 547, Level 16, State 0, Procedure AddAnswer,
Line 114 The INSERT statement conflicted with the FOREIGN KEY
constraint "FK__Answers__partner__145C0A3F". The conflict occurred in
database "SurveyDb", table "dbo.Partners", column 'id'. The statement
has been terminated. Msg 547, Level 16, State 0, Procedure AddAnswer,
Line 114 The INSERT statement conflicted with the FOREIGN KEY
constraint "FK__Answers__partner__145C0A3F". The conflict occurred in
database "SurveyDb", table "dbo.Partners", column 'id'. The statement
has been terminated. Msg 547, Level 16, State 0, Procedure AddAnswer,
Line 114 The INSERT statement conflicted with the FOREIGN KEY
constraint "FK__Answers__partner__145C0A3F". The conflict occurred in
database "SurveyDb", table "dbo.Partners", column 'id'. The statement
has been terminated. Msg 547, Level 16, State 0, Procedure AddAnswer,
Line 114 The INSERT statement conflicted with the FOREIGN KEY
constraint "FK__Answers__partner__145C0A3F". The conflict occurred in
database "SurveyDb", table "dbo.Partners", column 'id'. The statement
has been terminated.
and I think they all originate from the first 3 errors about AddPartner, however I cannot figure out the exact source of the problem as I've looked over my syntax plenty of times. On a related note, does there exist some sort of online tool that can help one get hints for debugging SQL errors?
-- Create database for all information
-- needed in the application, set as context
CREATE DATABASE SurveyDb;
GO
USE SurveyDb;
-- Create surveys table
GO
CREATE TABLE Surveys (
id INT IDENTITY(1,1),
title NVARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);
GO
-- Create sprocs for adding and deleting surveys
CREATE PROCEDURE AddSurvey
#title NVARCHAR(100)
AS
INSERT INTO Surveys (title) VALUES (#title)
GO
CREATE PROCEDURE DeleteSurvey
#id INT
AS
DELETE FROM Surveys WHERE id=#id
GO
-- Seed the surveys table with 1 sample survey
EXEC AddSurvey #title = "Survey Numero Uno";
GO
-- Create partners table
CREATE TABLE Partners (
id INT IDENTITY(1,1),
name NVARCHAR(50) NOT NULL,
PRIMARY KEY (id)
);
GO
-- Create sprocs for adding and deleting partners
CREATE PROCEDURE AddParter
#name NVARCHAR(50)
AS
INSERT INTO Partners (name) VALUES (#name)
GO
CREATE PROCEDURE DeletePartner
#id INT
AS
DELETE FROM Partners WHERE id=#id
GO
-- Seed the partners table with a few samples
EXEC AddPartner #name = 'Haliburton';
EXEC AddPartner #name = 'Berkshite Hathaway';
EXEC AddPartner #name = 'Infosys';
GO
-- Create questions table. Questions are associated with
-- a particular survey. If the survey is deleted then so
-- are all associated questions.
CREATE TABLE Questions (
id INT IDENTITY(1,1),
survey_id INT,
qtext NVARCHAR(300) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (survey_id) REFERENCES Surveys(id) ON DELETE CASCADE
);
GO
-- Create sprocs for adding and deleting questions.
CREATE PROCEDURE AddQuestion
#survey_id INT,
#qtext NVARCHAR(300)
AS
INSERT INTO Questions (survey_id, qtext) VALUES (#survey_id, #qtext)
GO
CREATE PROCEDURE DeleteQuestion
#id INT
AS
DELETE FROM Questions WHERE id=#id
GO
-- Seed the questions table with sample questions.
EXEC AddQuestion #survey_id = 1, #qtext = 'What is the average velocity of an African swallow?';
EXEC AddQuestion #survey_id = 1, #qtext = 'How hot is she, on a scale of 1.0-100.0?';
GO
-- Create table for answers. Answers are associated with both
-- a question and a partner. If either the question or partner
-- is deleted then so are all associated answers.
CREATE TABLE Answers (
id INT IDENTITY (1,1),
question_id INT,
partner_id INT,
val DECIMAL NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (question_id) REFERENCES Questions(id) ON DELETE CASCADE,
FOREIGN KEY (partner_id) REFERENCES Partners(id) ON DELETE CASCADE
);
GO
-- Create sprocs for adding and deleting answers.
CREATE PROCEDURE AddAnswer
#question_id INT,
#partner_id INT,
#val DECIMAL
AS
INSERT INTO Answers (question_id, partner_id, val) VALUES (#question_id, #partner_id, #val)
GO
CREATE PROCEDURE DeleteAnswer
#id INT
AS
DELETE FROM Answers WHERE id=#id
GO
-- Seed the questions table with sample answers.
EXEC AddAnswer #question_id = 1, #partner_id = 1, #val = 23.3;
EXEC AddAnswer #question_id = 2, #partner_id = 1, #val = 99.5;
EXEC AddAnswer #question_id = 1, #partner_id = 2, #val = 0.12345;
EXEC AddAnswer #question_id = 2, #partner_id = 2, #val = 0.19;
The problem is in the AddAnswer procedure. You're adding partner id's that don't exist in the partner table, so referential integrity fails. Look in your partner table ( select * from partners ) and see what the id's are.
Other than that, I'd say that 1) you need to add some checking before inserting rows. If you try to add 'Berkshire Hathaway' twice, it's going to error. Check first and you don't have that problem:
if not exists ( select * from partners where [name] = #name )
begin
INSERT INTO Partners (name) VALUES (#name)
end
Also: you should really consider not using a column named name - call it PartnerName or something, sure, but having random name columns doesn't help readability and may cause syntax-checking problems down the road.
EDIT: Or, as Jamie points out, correct the typo in the stored procedure name.

Combine "delete query"

I'm making a stored procedure but the query doesn't work.
create proc deleteUser
#username varchar(50)
as
begin
DECLARE #sql NVARCHAR(MAX) = 'delete from lars.userInformation where username='+#username;
'delete from lars.userAcces where username='+#username
EXEC sp_executeSQL #sql,N'
#username
',#username
end
How could I do this without using joins?
You don't need dynamic sql:
create proc deleteUser
#username varchar(50)
as
begin
delete from lars.userInformation where username=#username;
delete from lars.userAcces where username=#username;
end
Why do you need to use the EXEC statement. Can you not just perform the DELETE statements directly, preferably using a TRANSACTION?
The optimum solution is to add a constraint to the table so when the parent record is deleted, child records are automatically deleted.
This will ensure the data has integrity no matter how the parent row is deleted.
Example:
-- foreign key constraint
ALTER TABLE [dbo].[OrderDetail] WITH CHECK
ADD CONSTRAINT [FK_OrderDetail_Order] FOREIGN KEY([OrderID])
REFERENCES [dbo].[Order] ([OrderID])
ON DELETE CASCADE

Error during trigger execution: Error converting data type nvarchar to bigint

I have created a trigger which must update the total amount from Account table. Whenever some data is update from Sale table, the trigger executes a store procedure calculating the current amount and inserting it into Account, but when it's about to update the Account table, some quite strange error occurs:
The data in row 5 was not committed Error Source: .Net SqlClient
DataProvider Error Message: Error converting data type nvarchar to
bigint. The statement have been terminated.
Below there is the Sale's trigger script:
CREATE TRIGGER [dbo].[Trigger_Sale]
ON [dbo].[Sale]
FOR DELETE, INSERT, UPDATE
AS
BEGIN
exec ComputeAccountAmount ID_Account
END
And the procedure ComputeAccountAmount:
CREATE PROCEDURE [dbo].[ComputeAccountAmount]
#IdAccount bigint
AS
begin transaction
update Account set AccountAmount = (SELECT sum(AmountSold)
from Sale
where #IdAccount = ID_Account)
where #IdAccount = ID_Account
commit
I've already checked out all the types the procedures uses, yet its tables and everything is bigint as shown below:
CREATE TABLE [dbo].[Account] (
[ID_Account] BIGINT IDENTITY (1, 1) NOT NULL,
[ExpireDate] DATE NOT NULL,
[PurchaseLimit] MONEY NOT NULL,
[OpeningDate] DATE NOT NULL,
[ID_Customer] INT NOT NULL,
[AccountAmount] MONEY NULL,
CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED ([ID_Account] ASC),
CONSTRAINT [FK_Account_Customer] FOREIGN KEY ([ID_Customer]) REFERENCES [dbo].[Customer] ([ID_Customer]) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE [dbo].[Sale] (
[ID_Sale] INT IDENTITY (1, 1) NOT NULL,
[SaleDate] DATE NOT NULL,
[AmountSold] MONEY NOT NULL,
[ID_Account] BIGINT NULL,
PRIMARY KEY CLUSTERED ([ID_Account] ASC)
);
For testing, I'm using the Visual Studio to manually verify the trigger. What's going on?
Obviously you have syntax error in your trigger
CREATE TRIGGER [dbo].[Trigger_Sale]
ON [dbo].[Sale]
FOR DELETE, INSERT, UPDATE
AS
BEGIN
exec ComputeAccountAmount ID_Account
END
What is ID_Account? It will throw an error
You need to select distinct accountIDs from INSERTED and DELETED tables in your trigger and for each of this account call exec ComputeAccountAmount. Something like:
CREATE TRIGGER [dbo].[Trigger_Sale] ON [dbo].[Sale]
FOR DELETE, INSERT, UPDATE
AS
BEGIN
DECLARE #AccountID BIGINT
DECLARE trCur CURSOR FAST_FORWARD READ_ONLY
FOR
SELECT AccountID FROM DELETED
UNION
SELECT AccountID FROM INSERTED
OPEN trCur
FETCH NEXT FROM trCur INTO #AccountID
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC ComputeAccountAmount #AccountID
FETCH NEXT FROM trCur INTO #AccountID
END
CLOSE trCur
DEALLOCATE trCur
END