If the field was essentially changed, then change the value of one of its column - sql

I have the essence of the "Requirements". If the user has changed the field "Description" in this instance, it should automatically change the value of the field "Stability" (dropdownlist). That is, if you had to change the description of the requirements, it becomes unstable. I wrote a trigger
CREATE TRIGGER [ChangeStabilityRequirement]
ON [dbo].[Requirement] AFTER UPDATE
AS
BEGIN
if update([Definition])
begin
update [Requirement] set Stability = 2
where RequirementId in (select RequirementId from inserted)
end
end
But the problem is that the trigger is activated when any change entries in the table. A need to respond only to changes in the column "Definition".
MY TABLE
CREATE TABLE [dbo].[Requirement] (
[RequirementId] INT IDENTITY (1, 1) NOT NULL,
[Rationale] NVARCHAR (MAX) NULL,
[CreatedOn] DATE CONSTRAINT [DF__Requireme__Creat__473C8FC7] DEFAULT (getdate()) NULL,
[CurentVersion] NVARCHAR (MAX) NULL,
[State] INT NOT NULL,
[Priority] INT NOT NULL,
[Type] INT NOT NULL,
[Source_BusinessRuleId] INT NULL,
[Stability] INT NOT NULL,
[UserPart] NVARCHAR (MAX) NULL,
[CreatedBy_UserId] INT NULL,
[Responsible_UserId] INT NULL,
[ImplementationVersion] NVARCHAR (MAX) NULL,
[ResponsibleId] INT DEFAULT ((0)) NULL,
[SourceId] INT DEFAULT ((0)) NULL,
[InterfacePoint_InterfacePointId] INT NULL,
[InterfacePointId] INT DEFAULT ((0)) NULL,
[CreatedById] INT DEFAULT ((0)) NULL,
[Definition] NVARCHAR (MAX) DEFAULT ('') NOT NULL,
CONSTRAINT [PK_dbo.Requirement] PRIMARY KEY CLUSTERED ([RequirementId] ASC),
CONSTRAINT [FK_dbo.Requirement_dbo.User_CreatedById] FOREIGN KEY ([CreatedById]) REFERENCES [dbo].[User] ([UserId]),
CONSTRAINT [FK_dbo.Requirement_dbo.User_ResponsibleId] FOREIGN KEY ([ResponsibleId]) REFERENCES [dbo].[User] ([UserId]),
CONSTRAINT [FK_dbo.Requirement_dbo.BusinessRule_SourceId] FOREIGN KEY ([SourceId]) REFERENCES [dbo].[BusinessRule] ([BusinessRuleId])
);
Update table
Updating occurs in a web application interface
This is query from SQL SERVER Profile
exec [dbo].[Requirement_Update]
#RequirementId=32,
#Definition=N'Реализовать возможность выбора значения "Без пени" в поле "Тип начисления пени". Диалоговое окно АР-12',
#Rationale=N'В соответствии с изменением бизнес-правила',
#CreatedOn='2014-12-18 00:00:00',
#CurentVersion=N'2.1',
#ImplementationVersion=N'2.2',
#State=0,
#Priority=1,
#Stability=1,
#Type=0

Ok, if you need update Requirement only when Definition is updated then change your trigger as:
CREATE TRIGGER [ChangeStabilityRequirement]
ON [dbo].[Requirement] AFTER UPDATE
AS
BEGIN
if update([Definition]) AND NOT update([Rationale]) AND NOT update([CurentVersion])
--AND NOT UPDATE(.....list here all possible columns that may be updated
begin
update [Requirement] set Stability = 2
where RequirementId in (select RequirementId from inserted)
end
end

Related

Error during foreign key creation: Invalid references

I have 2 tables and I want to create a foreign key constraint in the second table. This is what I tried:
Table 1:
CREATE TABLE REMINDER_RULE_M
(
REMINDER_RULE_M_D int IDENTITY(1,1) NOT NULL,
COMMUNICATION_MODE nvarchar(255) NOT NULL,
REMINDER_TO nvarchar(255) NOT NULL,
REMINDER_VALUE varchar(255) NOT NULL,
REMINDER_CONDITION varchar(255) NOT NULL,
REMINDER_TO_CUSTOM varchar(255)
)
Table 2:
CREATE TABLE REMINDER_AUDIT
(
REMINDER_AUDIT_D int IDENTITY(1,1) NOT NULL,
ACTION varchar(255) NOT NULL,
CONSTRAINT FK_b892318b20e5bbe162722ea5946
FOREIGN KEY (REMINDER_RULE_M_D)
REFERENCES REMINDER_RULE_M(REMINDER_RULE_M_D),
OLD_VALUE nvarchar(1024) NOT NULL,
NEW_VALUE nvarchar(1024) NOT NULL,
)
I get an error running the second SQL query:
Reason:
SQL Error [1769] [S0001]: Foreign key 'FK_b892318b20e5bbe162722ea5946' references invalid column 'REMINDER_RULE_M_D' in referencing table 'REMINDER_AUDIT'.
As the error clearly tells you - you don't have a column in your second table.
You must have a column in order to create a FK constraint - the FK constraint does NOT create a column in your table - it just establishes a constraint between existing tables and columns.
So try this for your second table:
CREATE TABLE REMINDER_AUDIT
(
REMINDER_AUDIT_D int IDENTITY(1,1) NOT NULL,
ACTION varchar(255) NOT NULL,
-- define the column!
REMINDER_RULE_M_D int NOT NULL,
-- I'd strongly recommend trying to come up with a more
-- intuitive and useful naming convention for your FK constraints!
CONSTRAINT FK_b892318b20e5bbe162722ea5946
FOREIGN KEY (REMINDER_RULE_M_D)
REFERENCES REMINDER_RULE_M(REMINDER_RULE_M_D),
OLD_VALUE nvarchar(1024) NOT NULL,
NEW_VALUE nvarchar(1024) NOT NULL,
)
I just guessed that REMINDER_RULE_M_D is NOT NULL - you might need to adapt this (if it's an optional key).
You do not need to write Foreign Key
CREATE TABLE REMINDER_AUDIT (
REMINDER_AUDIT_D int IDENTITY(1,1) NOT NULL,
ACTION varchar(255) NOT NULL,
CONSTRAINT FK_b892318b20e5bbe162722ea5946 REFERENCES REMINDER_RULE_M(REMINDER_RULE_M_D),
OLD_VALUE nvarchar(1024) NOT NULL,
NEW_VALUE nvarchar(1024) NOT NULL,
)

How to convert numeric to nvarchar in SQL Server?

Consider the following table. I use a trigger to add to the table. In the column of converting the number to the string, it fails.
CREATE TABLE [dbo].[tblAIAgent]
(
[AgentCode] [NVARCHAR](10) NOT NULL,
[NationalCode] [BIGINT] NOT NULL
CONSTRAINT [DF_tblAIAgent_NationalCode] DEFAULT ((0)),
[FirstName] [NVARCHAR](50) NOT NULL
CONSTRAINT [DF_tblAIAgent_Name] DEFAULT (''),
[LastName] [NVARCHAR](50) NOT NULL
CONSTRAINT [DF_tblAIAgent_Family] DEFAULT (''),
[IsActive] [BIT] NOT NULL
CONSTRAINT [DF_tblAIAgent_Active] DEFAULT ((1)),
[Counter] [INT] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_tblAIAgent]
PRIMARY KEY CLUSTERED
)
ALTER TRIGGER [dbo].[AgentInsert]
ON [dbo].[tblAIAgent]
INSTEAD OF INSERT
AS
BEGIN
DECLARE #AgentCode NVARCHAR(10)
DECLARE #NationalCode BIGINT
DECLARE #FirstName NVARCHAR(50)
DECLARE #LastName NVARCHAR(50)
DECLARE #IsActive BIT
DECLARE #CounterIs INT
SET #CounterIs = ##IDENTITY
SELECT
#AgentCode = AgentCode,
#NationalCode = NationalCode,
#FirstName = FirstName,
#LastName = LastName,
#IsActive = IsActive
FROM inserted
INSERT INTO tblAIAgent (NationalCode, FirstName, LastName, IsActive, AgentCode)
VALUES (#NationalCode, #FirstName, #LastName, #IsActive, 'Agent_' + CAST(#CounterIs AS NVARCHAR(4)))
END
You have a few problems here:
The ##IDENTITY is a system function contains the last identity value that is generated when an INSERT, SELECT INTO, or BULK COPY statement is completed. If the statement did not affect any tables with identity columns, ##IDENTITY returns NULL. If multiple rows are inserted, generating multiple identity values, ##IDENTITY returns the last identity value generated.
In your case, you have an INSTEAD OF INSERT trigger, so there is no INSERT.
This below query is completely wrong and will gives wrong results, it works as expected only if one row inserted, if there is more than 1 row, then those variables will hold just the values of one row, and you will lose the other values of the other rows, cause the pseudo INSERTED may contains 1 or more rows
select #AgentCode=AgentCode,
#NationalCode=NationalCode,
#FirstName=FirstName,
#LastName=LastName,
#IsActive=IsActive
from inserted
Now, looking to your table, you already have an IDENTITY column, so you don't need to a TRIGGER at all, you can just make a computed column as
CREATE TABLE [dbo].[tblAIAgent](
[AgentCode] AS 'Agent_' + CAST([Counter] AS VARCHAR(10)),
[NationalCode] [bigint] NOT NULL
CONSTRAINT [DF_tblAIAgent_NationalCode] DEFAULT ((0)),
[FirstName] [nvarchar](50) NOT NULL
CONSTRAINT [DF_tblAIAgent_Name] DEFAULT (''),
[LastName] [nvarchar](50) NOT NULL
CONSTRAINT [DF_tblAIAgent_Family] DEFAULT (''),
[IsActive] [bit] NOT NULL
CONSTRAINT [DF_tblAIAgent_Active] DEFAULT ((1)),
[Counter] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_tblAIAgent] PRIMARY KEY ([Counter])
);
UPDATE:
According to your comment "a computed column can no longer be selected as the PK. I want this column to be placed in other relevant tables as a FK.I wrote the trigger to get the column value instead of the computed column so that I can select the column as the primary key". You are trying to make it a PRIMARY KEY so you can do as
CREATE TABLE T(
Counter INT IDENTITY(1,1) NOT NULL,
OtherCol INT,
Computed AS CONCAT('Agent_', CAST(Counter AS VARCHAR(10))) PERSISTED,
CONSTRAINT PKT PRIMARY KEY(Computed)
);
CREATE TABLE TT(
ReferenceComputedColumn VARCHAR(16) NOT NULL,
OtherColumn INT,
CONSTRAINT FK_ReferencedComputedColumn
FOREIGN KEY(ReferenceComputedColumn)
REFERENCES T(Computed)
)
INSERT INTO T(OtherCol) VALUES
(1), (2), (3);
INSERT INTO TT(ReferenceComputedColumn, OtherColumn) VALUES
('Agent_1', 10),
('Agent_3', 20);
SELECT *
FROM T LEFT JOIN TT
ON T.Computed = TT.ReferenceComputedColumn;
See how it's working.
See also this article Properly Persisted Computed Columns by Paul White.
Try this
SELECT CONVERT(NVARCHAR(255), #AgentCode)
SELECT CAST([PictureId] AS NVARCHAR(4)) From Category

Cannot insert the value NULL into column 'Id' although Id is set

I have a strange problem.
I want to insert an item to a table from database. I use Entity Framework.
Although the Id is set, I keep getting the following error:
Cannot insert the value NULL into column 'Id', table 'project_atp.dbo.ShoppingCarts'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}
The table definition:
CREATE TABLE [dbo].[ShoppingCarts] (
[Id] INT NOT NULL,
[Guid] UNIQUEIDENTIFIER NULL,
[Name] NVARCHAR (255) NULL,
[Code] NVARCHAR (255) NULL,
[SupplierNo] NVARCHAR (255) NULL,
[SupplierName] NVARCHAR (255) NULL,
[Price] NVARCHAR (50) NULL,
[Quantity] INT NULL,
CONSTRAINT [PK_ShoppingCarts] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Can you please advise what could be wrong here! Thanks!
By default Entity Framework assumes that an integer primary key is database generated. As the result Entity Framework would not include Primary Key field in the actual INSERT statement.
I would try to either play along and ALTER the table to auto-generate the ID (which judging by your comment you did)
or set StoreGeneratedPattern property of OnlineCarStore.Models.ShoppingCarts Id column to 'None'
or use annotation: [DatabaseGenerated(DatabaseGeneratedOption.None)].

Why is my SQL table not in 3 normal form

I have made this database. It looks like it is working fine, except that I was told that my table "event" is not in third normal form. I do not see why it is not in the third normal form. I thought it is maybe because of the city and the zip code, which should be always the same, but large cities can have multiple zip codes and I do not see the point in creating another table just for the cities and their zip codes, related to the event table.
Also sorry if some of the names or attributes are named incorrectly by using some of the names reserved by the system. I had to translate the code to english, because I wrote it in my home language :). Thanks for your help.
Create table [article]
(
[id_article] Integer Identity(1,1) NOT NULL,
[id_author] Integer NOT NULL,
[id_category] Integer NOT NULL,
[title] Nvarchar(50) NOT NULL,
[content] Text NOT NULL,
[date] Datetime NOT NULL,
Primary Key ([id_article])
)
go
Create table [author]
(
[id_author] Integer Identity(1,1) NOT NULL,
[name] Nvarchar(25) NOT NULL,
[lastname] Nvarchar(25) NOT NULL,
[email] Nvarchar(50) NOT NULL, UNIQUE ([email]),
[phone] Integer NOT NULL, UNIQUE ([phone]),
[nick] Nvarchar(20) NOT NULL, UNIQUE ([nick]),
[passwd] Nvarchar(50) NOT NULL,
[acc_number] Integer NOT NULL, UNIQUE ([acc_number]),
Primary Key ([id_author])
)
go
Create table [event]
(
[id_event] Integer Identity(1,1) NOT NULL,
[id_author] Integer NOT NULL,
[name] Nvarchar(50) NOT NULL,
[date] Datetime NOT NULL, UNIQUE ([date]),
[city] Nvarchar(50) NOT NULL,
[street] Nvarchar(50) NOT NULL,
[zip] Integer NOT NULL,
[house_number] Integer NOT NULL,
[number_registered] Integer Default 0 NOT NULL Constraint [number_registered] Check (number_registered <= 20),
Primary Key ([id_event])
)
go
Create table [user]
(
[id_user] Integer Identity(1,1) NOT NULL,
[name] Nvarchar(15) NOT NULL,
[lastname] Nvarchar(25) NOT NULL,
[email] Nvarchar(50) NOT NULL, UNIQUE ([email]),
[phone] Integer NOT NULL, UNIQUE ([phone]),
[passwd] Nvarchar(50) NOT NULL,
[nick] Nvarchar(20) NOT NULL, UNIQUE ([nick]),
Primary Key ([id_user])
)
go
Create table [commentary]
(
[id_commentary] Integer Identity(1,1) NOT NULL,
[content] Text NOT NULL,
[id_article] Integer NOT NULL,
[id_author] Integer NULL,
[id_user] Integer NULL,
Primary Key ([id_commentary])
)
go
Create table [category]
(
[id_category] Integer Identity(1,1) NOT NULL,
[name] Nvarchar(30) NOT NULL,
Primary Key ([id_category])
)
go
Create table [registration]
(
[id_user] Integer NOT NULL,
[id_event] Integer NOT NULL,
Primary Key ([id_user],[id_event])
)
go
Alter table [commentary] add foreign key([id_article]) references [article] ([id_article]) on update no action on delete no action
go
Alter table [article] add foreign key([id_author]) references [author] ([id_author]) on update no action on delete no action
go
Alter table [event] add foreign key([id_author]) references [author] ([id_author]) on update no action on delete no action
go
Alter table [commentary] add foreign key([id_author]) references [author] ([id_author]) on update no action on delete no action
go
Alter table [registration] add foreign key([id_event]) references [event] ([id_event]) on update no action on delete no action
go
Alter table [commentary] add foreign key([id_user]) references [user] ([id_user]) on update no action on delete no action
go
Alter table [registration] add foreign key([id_user]) references [user] ([id_user]) on update no action on delete no action
go
Alter table [article] add foreign key([id_category]) references [category] ([id_category]) on update no action on delete no action
go
EDIT:
Do you think it could work like this? I made another table called location with all the address infos which were previously in event table and made the id_event PFK.
Create table [event]
(
[id_event] Integer Identity(1,1) NOT NULL,
[id_author] Integer NOT NULL,
[name] Nvarchar(50) NOT NULL,
[datr] Datetime NOT NULL,
[number_registered] Integer Default 0 NOT NULL Constraint [number_registered] Check (number_registered <= 20),
Primary Key ([id_event])
)
go
Create table [location]
(
[city] Char(1) NOT NULL,
[id_event] Integer NOT NULL,
[street] Char(1) NOT NULL,
[house_number] Char(1) NOT NULL,
[zip] Char(1) NOT NULL,
Primary Key ([id_event])
)
go
Alter table [event] add foreign key([id_auhtor]) references [author] ([id_author]) on update no action on delete no action
go
Alter table [location] add foreign key([id_event]) references [event] ([id_event]) on update no action on delete no action
go
To answer the question.
You are correct, the database is not in 3rd normal form. As you've identified there is an opportunity to normalise out the various postcodes, cities and streets. This would result in a row for each postcode (etc.) and you would have FKs for each.
Personally, I don't do this. It obviously depends on the application but in my systems I'm more interested in getting the address of the user rather than all the users who have a particular postcode.
Depending on how you intend to use your data 3rd normal may not be the most efficient way to store your data.
Based on your edit - close, but I'd turn it around. I'd give location a location_id column (PK), remove its event_id column, and then make event be:
Create table [event]
(
[id_event] Integer Identity(1,1) NOT NULL,
[id_author] Integer NOT NULL,
id_location Integer NOT NULL, /* Or null? does every event have to have a location */
[name] Nvarchar(50) NOT NULL,
[datr] Datetime NOT NULL,
[number_registered] Integer Default 0 NOT NULL Constraint [number_registered] Check (number_registered <= 20),
Primary Key ([id_event])
)
And then reverse the foreign key as well.
That way if an address requires correction it only needs to be corrected in one row - which is after all the point of normalization - making corrections only have to be applied once.

How to reference two tables in Visual Studio 2012 by adding foreign key?

I have a problem adding a foreign key to a table column.
My tables look this way. I need to reference ContactOwnerId from Contact table to UserId in UserProfile table
CREATE TABLE [dbo].[Contacts] (
[ContactId] INT IDENTITY (1, 1) NOT NULL,
[ContactOwnerId] INT NOT NULL,
[FirstName] NVARCHAR (MAX) NOT NULL,
[LastName] NVARCHAR (MAX) NOT NULL,
[Address] NVARCHAR (MAX) NOT NULL,
[City] NVARCHAR (MAX) NOT NULL,
[Phone] NVARCHAR (MAX) NOT NULL,
[Email] NVARCHAR (MAX) NOT NULL,
CONSTRAINT [PK_dbo.Contacts] PRIMARY KEY CLUSTERED ([ContactId] ASC),
CONSTRAINT [FK_Contacts_UserProfile] FOREIGN KEY ([UserId]) REFERENCES [Contacts]([ContactOwnerId])
);
CREATE TABLE [dbo].[UserProfile] (
[UserId] INT IDENTITY (1, 1) NOT NULL,
[UserName] NVARCHAR (56) NOT NULL,
PRIMARY KEY CLUSTERED ([UserId] ASC),
UNIQUE NONCLUSTERED ([UserName] ASC)
);
I added a foreign key, but it seems, not right, because UserId is highlighted, giving error:
SQL71501 :: Foreign Key: [dbo].[FK_Contacts_UserProfile] has an unresolved reference to Column [dbo].[Contacts].[UserId].
SQL71516 :: The referenced table '[dbo].[Contacts]' contains no primary or candidate keys that match the referencing column list in the foreign key. If the referenced column is a computed column, it should be persisted.
How do I correctly reference these two tables? Thanks in advance.
EDIT
I did like sgeddes said. But I get an error, when I try to create a contact.
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Contacts_UserProfile". The conflict occurred in database "ContactAppContext", table "dbo.UserProfile", column 'UserId'.
The statement has been terminated.
If I remove a foreign key I get no error.
What I want to achieve is, when a user creates contacts, his Id(UserId) could associate with ContactOwnerId, so that contacts could relate to one specific user.
Since ContactOwnerId in the Contact table should be the FOREIGN KEY, you need to specify that in your CONSTRAINT instead of UserId.
I think this is what you're trying to do:
CREATE TABLE [dbo].[UserProfile] (
[UserId] INT IDENTITY (1, 1) NOT NULL,
[UserName] NVARCHAR (56) NOT NULL,
PRIMARY KEY CLUSTERED ([UserId] ASC),
UNIQUE NONCLUSTERED ([UserName] ASC)
);
CREATE TABLE [dbo].[Contacts] (
[ContactId] INT IDENTITY (1, 1) NOT NULL,
[ContactOwnerId] INT NOT NULL,
[FirstName] NVARCHAR (MAX) NOT NULL,
[LastName] NVARCHAR (MAX) NOT NULL,
[Address] NVARCHAR (MAX) NOT NULL,
[City] NVARCHAR (MAX) NOT NULL,
[Phone] NVARCHAR (MAX) NOT NULL,
[Email] NVARCHAR (MAX) NOT NULL,
CONSTRAINT [PK_dbo.Contacts] PRIMARY KEY CLUSTERED ([ContactId] ASC),
CONSTRAINT [FK_Contacts_UserProfile] FOREIGN KEY ([ContactOwnerId]) REFERENCES [UserProfile]([UserId])
);
The problem was with the last line. You need to reference the column from the Contacts table first, and then point to your UserProfile table. You had that backwards.
Here's a SQL Fiddle
Here's some documentation/examples for creating FOREIGN KEY CONSTRAINTS:
http://msdn.microsoft.com/en-us/library/aa258255(v=sql.80).aspx